ช่วงทั้งหมดตั้งแต่ 0 ถึง 1,000


9

เป็นไปได้ไหมที่จะทำให้รหัส C นี้เล็กลง? มันพิมพ์จำนวนเฉพาะจาก 0 ถึง 1,000

C, 89 ตัวอักษร

int i,p,c;for(i=2;i<1e3;i++){c=0;for(p=2;p<i;p++)if(i%p==0)c++;if(c==0)printf("%u\n",i);}

6
เพียงแค่เตรียมไว้ล่วงหน้าบางส่วน "เราไม่ต้องการความท้าทายเฉพาะภาษา" การขอความช่วยเหลือจากการเล่นกอล์ฟบางรหัสเป็นหัวข้อและเรื่องราวที่แตกต่างจากความท้าทาย
Martin Ender

4
เราจำเป็นต้องรักษาอัลกอริทึมหรือเฉพาะผลลัพธ์สุดท้ายหรือไม่
John Dvorak

ฉันจะเริ่มต้นที่ 2 เพื่อความถูกต้องอย่างแม่นยำเนื่องจากนี่พิมพ์ 0 และ 1
ชำนาญการ

คุณพยายามทำให้โค้ดทำงานเร็วขึ้นหรือพยายามใช้อักขระน้อยลงในซอร์สโค้ดหรือไม่?
user3629249

1
เมื่อคุณขอความช่วยเหลือเกี่ยวกับการเล่นกอล์ฟการนับจำนวนตัวอักษรของโซลูชันปัจจุบันของคุณในโพสต์ของคุณจะเป็นประโยชน์อย่างมาก (ฉันทำมันให้เป็น 89)
Mark Reed

คำตอบ:


7

59 57 ไบต์

ขึ้นอยู่กับวิธีการแก้ปัญหา @feersum แต่การตรวจสอบเบื้องต้นสามารถตีเพิ่มเติม

for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);

แก้ไขตามความเห็นของ Runer112


2
ตรวจสอบที่ถูกผูกไว้สามารถ golfed อีกเล็กน้อย: d=p++%999. ไม่งั้นนี่มันดูเป็นงานตีกอล์ฟที่แน่นหนา!
Runer112

10

67 ไบต์

ใน C ไม่มีทางเลือกอื่นสำหรับแผนกทดลอง แต่สามารถตีกอล์ฟได้เล็กน้อย

for(int p=1,d;p++<999;d&&printf("%d\n",p))for(d=p;--d>1;)d=p%d?d:1;

ต้องการการประกาศเริ่มต้น C99 ซึ่งบันทึกได้ 1 ไบต์


6

(ฉันเขียนสิ่งนี้โดยไม่ตระหนักถึงข้อ จำกัด ด้านขนาดของจำนวนเต็มใน C ดังนั้นจึงไม่มีประโยชน์ที่จะทำให้รหัสสั้นลง)

ก่อนคำเกี่ยวกับอัลกอริทึม ก่อนตีกอล์ฟรหัสของคุณคุณควรคิดถึงกลยุทธ์โดยรวมที่ดีที่สุดเพื่อให้ได้ผลลัพธ์

คุณกำลังตรวจสอบ primality โดยการทำส่วนการพิจารณาคดี - การทดสอบแต่ละตัวหารที่มีศักยภาพของp iนั่นเป็นค่าใช้จ่ายเป็นตัวละครเพราะมันใช้เวลาสองลูป ดังนั้นการทดสอบแบบดั้งเดิมโดยไม่มีลูปจึงมีแนวโน้มที่จะบันทึกอักขระ

วิธีที่สั้นกว่ามักจะใช้ทฤษฎีบทของวิลสัน : จำนวนnนั้นเป็นจำนวนเฉพาะถ้าหากว่า

fact(n-1)%n == n-1

ซึ่งfactเป็นฟังก์ชั่นแฟกทอ เนื่องจากคุณกำลังทดสอบความเป็นไปได้ทั้งหมดnตั้งแต่1ถึงจนถึง1000เป็นเรื่องง่ายที่จะหลีกเลี่ยงการใช้แฟกทอเรียลโดยการติดตามผลิตภัณฑ์ที่กำลังทำงานอยู่PและอัปเดตโดยP*=nหลังจากแต่ละลูป นี่คือการใช้งาน Python ของกลยุทธ์นี้เพื่อพิมพ์จำนวนมากถึงล้านครั้ง

หรือความจริงที่ว่าโปรแกรมของคุณจะต้องมีสิทธิ์มากถึง 1,000 รายการเท่านั้นที่เปิดใช้กลยุทธ์อื่น: การทดสอบแบบดั้งเดิมของแฟร์มาต์ สำหรับบางคนaทุกคนnพึงพอใจ

pow(a,n-1)%n == 1

แต่น่าเสียดายที่บางคอมโพสิตยังผ่านการทดสอบนี้สำหรับบางคนn aเหล่านี้เรียกว่าpseudoprimes แฟร์มาต์ แต่a=2และa=3ไม่ล้มเหลวด้วยกันจนกว่าn=1105พวกเขาจะพอเพียงเพื่อจุดประสงค์ของคุณในการตรวจสอบเฉพาะช่วงเวลาจนถึง 1,000 (ถ้า 1,000 เป็น 100 แทนที่จะเป็นคุณจะสามารถใช้งานได้เท่านั้นa=2) ดังนั้นเราจึงตรวจสอบขั้นแรกด้วย (ungolfed code)

pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1

สิ่งนี้ก็ล้มเหลวในการรับรู้เฉพาะช่วงที่ 2 และ 3 ดังนั้นสิ่งเหล่านั้นจำเป็นต้องได้รับการดูแลเป็นพิเศษ

วิธีการเหล่านี้สั้นลงหรือไม่? ฉันไม่ทราบเพราะฉันไม่ได้เขียนโค้ดใน C. แต่พวกเขาเป็นแนวคิดที่คุณควรลองก่อนที่คุณจะตกลงบนชิ้นส่วนของรหัสเพื่อเริ่ม eking out ตัวอักษร


1
ทฤษฎีบทของวิลสันไม่ได้มีประโยชน์ใน C เพราะints เป็น 32 บิต กันไปสำหรับแฟร์มาต์
feersum

@feersum โอ้ยิง นั่นเป็นปัญหาสำหรับแฟคทอเรียลด้วย มีประเภทใหญ่ int?
xnor

@xnor ไม่ใช่ในตัว
Martin Ender

1
หากกำหนดfact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }แล้วผลจะไม่ท่วมจำนวนเต็ม 32 nบิตสำหรับค่าแม้จะมีขนาดใหญ่พอสมควร ( mเป็นโมดูลัส)
apnorton

@anorton (n*fact(n-1,m)) % mฉันคิดว่าคุณหมายถึง ซึ่งเน้นปัญหา: คุณไม่สามารถหลีกเลี่ยงการเรียกซ้ำในการดำเนินการfactเพราะmจะแตกต่างกันสำหรับการวนซ้ำของลูปด้านนอกแต่ละครั้ง
hvd

4

78 77 ตัวอักษร

(เพียงใช้เทคนิคบางอย่างที่เรียนรู้ในภาษาอื่น)

int i=0,p,c;for(;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

76 ตัวอักษรในโหมด C99

for(int i=0,p,c;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

2

58 chars (หรือ 61 สำหรับโปรแกรมทั้งหมด)

การนำคำตอบของฉันไปใช้กับคำถามที่คล้ายกันอีกครั้ง
แก้ไข : ชิ้นส่วนรหัสสแตนด์อะโลนไม่มีฟังก์ชั่นที่จะโทร

for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));

โปรแกรมที่สมบูรณ์:

n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}

1

67 64 ไบต์

แรงบันดาลใจจากโซลูชันของ Alchymist:

int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.