การเขียนโปรแกรมไสยศาสตร์


19

ความท้าทายของคุณนั้นง่ายมาก ให้ปีเป็นอินพุทพิมพ์เดือนทั้งหมดในปีนั้นซึ่งจะมีวันศุกร์ที่ 13ตามปฏิทินเกรกอเรียน โปรดทราบว่าแม้ว่าปฏิทิน Gregorian จะไม่ถูกนำมาใช้จนถึงปี 1582 แต่เราจะแกล้งทำเป็นว่ามีการใช้งานมาตั้งแต่ปีค. ศ. 0001

กฎระเบียบ

  • อนุญาตให้ใช้โปรแกรมหรือฟังก์ชั่นแบบเต็ม

  • คุณสามารถรับอินพุตเป็นอาร์กิวเมนต์ฟังก์ชันจาก STDIN หรือเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

  • คุณไม่ได้รับอนุญาตให้ใช้วันที่และเวลาในตัว

  • คุณสามารถสรุปได้ว่าข้อมูลที่ป้อนจะเป็นปีที่ถูกต้อง หากอินพุตมีขนาดเล็กกว่า 1 ไม่ใช่จำนวนเต็มที่ถูกต้องหรือใหญ่กว่าภาษาของคุณคุณไม่จำเป็นต้องจัดการกับสิ่งนี้และคุณจะได้รับพฤติกรรมที่ไม่ได้กำหนด

  • เอาต์พุตอาจเป็นตัวเลขเป็นภาษาอังกฤษหรือในรูปแบบที่มนุษย์สามารถอ่านได้อื่น ๆ ตราบใดที่คุณระบุมาตรฐาน

  • ตรวจสอบให้แน่ใจว่าคุณคิดเป็นปีอธิกสุรทิน และจำไว้ว่าปีอธิกสุรทินจะไม่เกิดขึ้นทุก ๆ 4 ปี!

เคล็ดลับ

เนื่องจากมีวิธีการมากมายเกี่ยวกับเรื่องนี้ฉันจึงไม่ต้องการที่จะบอกคุณว่าจะทำอย่างไร อย่างไรก็ตามอาจทำให้เกิดความสับสนได้ว่าจะเริ่มต้นอย่างไรดังนั้นนี่คือวิธีที่เชื่อถือได้สองวิธีที่แตกต่างกันในการกำหนดวันในสัปดาห์จากวันที่

ตัวอย่าง IO

2016 --> May
0001 --> 4, 7
1997 --> Jun
1337 --> 09, 12
123456789 --> January, October

ตามปกตินี่คือ code-golf ดังนั้นจึงใช้ช่องโหว่มาตรฐานและคำตอบที่สั้นที่สุดชนะ


5
เมื่อทำงานในวันศุกร์ที่ 13 ควรย้อนกลับและส่งออกเดือนที่ไม่มีวันศุกร์ที่ 13 (การอ้างอิงในวันศุกร์ประหลาดสำหรับการชนะ)
Addison Crump


ตัวอย่างนี้ถูกต้อง0001 --> 5หรือไม่ ตามหน้านี้ (และรหัสของฉัน) มันควรจะเป็นเมษายนและกรกฎาคม
faubi

@faubiguy ฉันไม่ดีคุณพูดถูก นั่นคือในปฏิทินจูเลียน ขอผมแก้ไขหน่อย
DJMcMayhem

โดย "คุณไม่ได้รับอนุญาตให้ใช้วันที่หรือเวลาในตัว" ฉันไม่สามารถแปลงเป็นเวลา unix ได้หรือไม่?
busukxuan

คำตอบ:


1

Pyth, 73 ไบต์

L?>b2QtQfq%+++13+/-*2.6?qT2 12%-T2 12 .2 1*5%yT4*4%yT100*6%yT400 7 5r1 13

ลองออนไลน์!

การใช้อัลกอริธึมแบบเกาส์เช่นเดียวกับในคำตอบ Python ของฉัน รหัส ~ 55 ไบต์ใช้สำหรับการคำนวณในวันทำงานดังนั้นการเลือกอัลกอริทึมที่ดีกว่านี้อาจช่วยได้มากฉันคิดว่า ... แต่เฮ้อย่างน้อยตอนนี้ก็ใช้งานได้แล้ว! :)


2

Python 2, 157 144 136 ไบต์

โซลูชันของฉันใช้อัลกอริทึม Gauss อินพุตเป็นปีเป็นจำนวนเต็ม ผลลัพธ์คือรายการของเดือนซึ่งมีวันศุกร์ที่ 13 เป็นตัวเลข (1-12) อาจเป็นไปได้ที่จะมีการตีกอล์ฟมากขึ้น แต่มันจะสายไป ... พรุ่งนี้จะแก้ไขสิ่งนี้และไม่ได้ทำให้มันแย่ไปกว่านี้อีกแล้ว ข้อเสนอแนะยินดีต้อนรับเสมอในระหว่างนี้!

def f(i):y=lambda m:(i-1,i)[m>2];print[m for m in range(1,13)if(13+int(2.6*((m-2)%12,12)[m==2]-.2)+y(m)%4*5+y(m)%100*4+y(m)%400*6)%7==5]

แก้ไข:ใส่ลงไปที่ 144 โดยแทนที่ for-loop ด้วย list comprehesion และทำการปรับแต่งเล็กน้อยอื่น ๆ

แก้ไข 2:ดึงมันลงไปที่ 136 ด้วยคำแนะนำจาก Morgan Thrapp และแก้ไขข้อผิดพลาดที่เขาค้นพบ ขอบคุณมาก! :)


1

Perl - 141 107 103 ไบต์

$y=<>-1;map{$y++if++$i==3;print"$i "if($y+int($y/4)-int($y/100)+int($y/400))%7==$_}'634163152042'=~/./g

วิธีนี้ใช้สูตรที่ได้รับการแก้ไขสำหรับวันจูเลียนในการคำนวณวันของสัปดาห์ที่ 13 มีนาคมจากนั้นใช้จำนวนวันของสัปดาห์ในแต่ละเดือนจะถูกชดเชยจากเดือนมกราคมเพื่อค้นหาวันในสัปดาห์สำหรับส่วนที่เหลือของ เดือนเริ่มต้นด้วย 2 เดือนสุดท้ายของปีก่อนหน้าเริ่มต้นในเดือนมีนาคมและ 10 เดือนแรกของปีปัจจุบัน (เพื่อหลีกเลี่ยงการคำนวณปีอธิกสุรทินสองครั้ง)


1

C - 164 153 112 ไบต์

ฉันพบวิธีแก้ปัญหาเล็ก ๆ น้อย ๆ ที่ดีโดยใช้วิธีการของ Schwerdtfeger รุ่นที่แก้ไขอย่างหนัก มันเข้ารหัสตารางที่จำเป็นในจำนวนเต็มโดยใช้ฐาน 7 แก้ไขเพื่อให้พอดีกับคำ 32- เซ็นชื่อ มันออกเดือนเป็น ASCII ตัวอักษรกับเดือนมกราคมเข้ารหัสเป็น1, กุมภาพันธ์2และอื่น ๆ กับเดือนตุลาคมเข้ารหัสเป็น:พฤศจิกายนเข้ารหัสเป็นและธันวาคมเข้ารหัสเป็น;<

t=1496603958,m;main(y){for(scanf("%d",&y),y--;(y%100+y%100/4+y/100%4*5+t+5)%7||putchar(m+49),t;t/=7)2-++m||y++;}

นี่มันเป็นสิ่งที่ไม่ดีเล็กน้อย:

t=1496603958,m;
main(y){
  for(
    scanf("%d",&y),y--;
    (y%100+y%100/4+y/100%4*5+t+5)%7||putchar(m+49),t;
    t/=7
  )
    2-++m||y++;
}

ฉันแน่ใจว่ามีหลายวิธีที่จะทำให้มันเล็กลง แต่ฉันคิดว่าอัลกอริทึมหรือการเปลี่ยนแปลงเล็กน้อยนั้นเหมาะอย่างยิ่งสำหรับการค้นหาเดือนที่วันศุกร์ที่ 13 เกิดขึ้น (เทียบกับขนาดโค้ด) หมายเหตุ:

  1. หากใช้คำแบบ 64- บิตได้อาจเป็นไปได้ที่จะกำจัดการเพิ่มที่น่ารำคาญ ( +5)
  2. ตัวแปรmไม่จำเป็นจริง ๆ เนื่องจากเดือนที่เราดูนั้นสามารถอนุมานtได้

ฉันทิ้งคำตอบเก่าไว้ด้านล่างเพราะเห็นว่าใช้วิธีการที่แตกต่างไปจากเดิมอย่างสิ้นเชิงโดยไม่เห็นในคำตอบอื่น


สิ่งนี้ขึ้นอยู่กับวิธีแก้ไขปัญหาที่เกี่ยวข้อง ( /codegolf//a/22531/7682 )

Y,M,D,d;main(y){for(scanf("%d",&y);Y<=y;++D>28+(M^2?M+(M>7)&1^2:!(Y&3)&&(Y%25||!(Y&15)))&&(D=1,M=M%12+1)<2&&Y++)(d=++d%7)^1||D^13||y^Y||printf("%d,",M);}

โดยทั่วไปจะจำลองปฏิทินเกรโกเรียนเพิ่มวันละครั้งพิมพ์เดือนที่เป็นวันศุกร์และวันที่ 13 นี่มันอยู่ในรูปแบบที่สามารถอ่านได้มากกว่า:

Y,M,D,d;
main(y){
  for(
    scanf("%d",&y);
    Y<=y;
    ++D>28+(
      M^2
        ?M+(M>7)&1^2
        :!(Y&3)&&(Y%25||!(Y&15))
    )&&(
      D=1,
      M=M%12+1
    )<2&&Y++
  )
    (d=++d%7)^1||D^13||y^Y||
      printf("%d,",M);
}

ecc ที่น่าประทับใจ แต่ไม่พบใน 123456789 -> มกราคม, ตุลาคมตุลาคม
RosLuP

อืมมันทำเพื่อฉัน ฉันอาจมีเหตุผลบางอย่างขึ้นอยู่กับแพลตฟอร์ม? มันทำงานได้ดีสำหรับฉันใน Macbook Pro ที่ค่อนข้างทันสมัยเมื่อรวบรวมกับ Clang โปรดทราบว่ามันจะส่งออก1:สำหรับ123456789ที่:ซึกตุลาคม ฉันชี้แจงการเข้ารหัสข้างต้น
Fors

ใช่ 1: เช่นกันที่นี่; ฉันไม่เข้าใจ ':' สำหรับเดือนตุลาคม ...
RosLuP

0

Excel, 137 ไบต์

ใช้เวลาป้อนปีใน A1 เอาต์พุตเป็นรายการที่ไม่คั่นด้วยเลขฐานสิบหก (มกราคม = 0, ธันวาคม = B)

ใช้อัลกอริทึมของเกาส์ในเดือนมกราคมและสิงหาคม

=CHOOSE(MOD(6+5*MOD(A1-1,4)+4*MOD(A1-1,400),7)+1,"","",1,"","",0,"")&CHOOSE(MOD(5*MOD(A1-1,4)+4*MOD(A1-1,400),7)+1,9,35,"8B",5,"2A",7,4)

คำตอบนี้ใช้ตัวสร้างวันที่และเวลาซึ่งระบุไว้อย่างชัดเจนว่าขัดกับกฎในการท้าทาย
Fors

@ สำหรับขอบคุณที่ชี้ให้เห็นว่า Updated
Wernisch

0

C, 276 219 ไบต์

#define R return
#define L(i) for(;i-->0;) 
u(y,m){R m-1?30+((2773>>m)&1):28+(y%4==0&&y%100||y%400==0);}s(y,m,g){g+=4;L(m)g+=u(y,m),g%=7;L(y)g+=1+u(y,1),g%=7;R g;}z(y,m,r){m=12;L(m)s(y,m,13)-4||(r|=1<<(m+1));R r;}

อินพุตจากเอาต์พุต stdin ใน stdout ลองhttp://ideone.com/XtuhGj [ฟังก์ชันดีบักคือ z]

w(y,m,r){m=12;L(m)s(y,m,u(y,m))||(r|=1<<(m+1));R r;}
/*    
// ritorna il numero dei giorni di anno=y mese=m con mese in 0..11
// m==1 significa febbraio   y%4?0:y%100?1:!(y%400) non funziona
u(y,m){R m-1?30+((2773>>m)&1):28+(y%4==0&&y%100||y%400==0);}

// argomenti anno:y[0..0xFFFFFFF]  mese:m[0..11]  giorno:g[1..u(y,m)]
// ritorna il numero del giorno[0..6]
s(y,m,g)
{g+=4; // correzione per il giorno di partenza anno mese giorno = 0,1,1
 L(m)g+=  u(y,m),g%=7; // m:0..m-1  somma mod 7 i giorni del mese dell'anno y
 L(y)g+=1+u(y,1),g%=7; // y:0..y-1  somma mod 7 gli anni da 0..y-1
                       // g+=1+u(y,1) poiche' (365-28)%7=1 e 1 e' febbraio
 R g;
}

// argomenti anno:y[0..0xFFFFFFF], m=0 r=0 
// calcola tutti gli ultimi giorni del mese dell'anno y che cadono di lunedi'
// e mette tali mesi come bit, dal bit 1 al bit 12 [il bit 0 sempre 0] in r
w(y,m,r){m=12;L(m)s(y,m,u(y,m))||(r|=1<<(m+1));R r;}

// argomenti anno:y[0..0xFFFFFFF], m=0 r=0 
//ritorna in r il numero dei mesi che ha giorno 13 di venerdi[==4]
// e mette tali mesi come bit, dal bit 1 al bit 12 [il bit 0 sempre 0] in r
z(y,m,r){m=12;L(m)s(y,m,13)-4||(r|=1<<(m+1));R r;}
*/

#define P printf
#define W while 
#define M main 
#define F for
#define U unsigned
#define N int
#define B break
#define I if
#define J(a,b)  if(a)goto b
#define G goto
#define P printf
#define D double
#define C unsigned char
#define A getchar()
#define O putchar
#define Y malloc
#define Z free
#define S sizeof
#define T struct
#define E else
#define Q static
#define X continue
M()
{N y,m,g,r,arr[]={1,297,1776,2000,2016,3385}, arr1[]={2016,1,1997,1337,123456789};
 C*mese[]={"gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic"};
 C*giorno[]={"Lun","Mar","Mer","Gio","Ven","Sab","Dom"};
 P("Inserisci Anno mese giorno>");r=scanf("%d %d %d", &y, &m, &g);
 P("Inseriti> %d %d %d r=%d\n", y, m, g, r);
 I(r!=3||m>12||m<=0||g>u(y,m-1))R 0;
 r=s(y,m-1,g);// 12-> 11 -> 0..10
 P("Risultato=%d giorno=%s\n", r, giorno[r]);
 r=w(y,0,0);P(" r=%d ", r);P("\n");
 F(m=0;m<6;++m)
        {P("N anno=%d -->",arr[m]); 
         r=w(arr[m],0,0); // ritorna in r i mesi tramite i suoi bit...
         F(y=1;y<13;++y) I(r&(1<<y))P("%s ",mese[y-1]);
         P("\n");
        }
 F(m=0;m<4;++m)
        {P("N anno=%d -->",arr1[m]); 
         r=z(arr1[m],0,0); // ritorna in r i mesi tramite i suoi bit...
         F(y=1;y<13;++y) I(r&(1<<y))P("%s ",mese[y-1]);
         P("\n");
        }

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.