ค้นหาจำนวนที่กำหนดที่มีการแทนทศนิยมดูเหมือนไบนารี


34

ฉันเจอคำถามเกี่ยวกับไซต์ตรวจสอบโค้ดที่น่าสนใจ ฉันคิดว่า OP กำลังทำผิด แต่ไม่แน่ใจ ... ดังนั้นเรามาไขปัญหาให้เขากันเถอะ! (เขียนโปรแกรมไม่ใช่ฟังก์ชัน / โพรซีเดอร์)

อินพุต (stdin หรือคล้ายกัน):

จำนวนเต็มxในรูปแบบทศนิยม มันมากกว่า 1 และน้อยกว่า 2 ^ 31

เอาท์พุท (stdout หรือคล้ายกัน):

จำนวนเต็มyในรูปแบบทศนิยม ผลิตภัณฑ์ที่ใช้x * yแทนทศนิยมจะต้องมีตัวเลขเพียง 0 และ 1 เท่านั้นและจะต้องมีจำนวนน้อยที่สุดดังกล่าวมากกว่า 0

หมายเหตุ: ผลลัพธ์ไม่ จำกัด - ถ้าค่าต่ำสุดyประมาณ 10 ^ 100 โปรแกรมของคุณจะต้องส่งออกทั้งหมด 100 หลัก (ฉันไม่รู้ว่ามีข้อ จำกัด ที่สมเหตุสมผลเช่น 2 ^ 64 เปิดy- ไม่ได้แก้ปัญหา )

โปรแกรมของคุณควรเสร็จในเวลาที่เหมาะสม (1 วินาทีหรือไม่ 1 ชั่วโมง - เป็นอย่างนั้น) สำหรับทุกคนxในระยะ

โบนัส:

หากโปรแกรมของคุณไม่มีข้อ จำกัด เกี่ยวกับขนาดของอินพุต (ยกเว้น RAM) และมีความซับซ้อนแบบพหุนามให้คูณจำนวนไบต์ของโปรแกรมของคุณด้วย0.8และปัดเศษ


ตัวอย่าง: อินพุต2; เอาต์พุต5เนื่องจาก 2 * 5 = 10

ตัวอย่าง: อินพุต21; เอาท์พุท481เพราะ 21 * 481 = 10101


คำแถลงการณ์ปฏิเสธความรับผิดชอบ: ฉันไม่รับผิดชอบต่อคำถามในเว็บไซต์ตรวจสอบรหัส ในกรณีที่มีความคลาดเคลื่อนควรให้คำอธิบายข้างต้นเป็นข้อมูลจำเพาะที่เหมาะสมเท่านั้น

OEIS A079339


6
ควรแก้ไขได้เสมอ เห็นได้ชัดว่าจะต้องมีอยู่อย่างน้อยหนึ่ง q ที่มีจำนวนอนันต์ของ n เช่นนั้น 10 ^ n mod x = q รับค่า x ดังกล่าวเป็น n และรวมเข้าด้วยกันตามกำลัง 10 ^ n
feersum

1
ผลคูณของ 9 ดูเหมือนจะให้ผลลัพธ์ที่สูงผิดปกติ
SuperJedi224

1
ปัญหาออยเลอร์โครงการที่เกี่ยวข้องสำหรับทุกคนที่คิดว่าคำถามนี้ดูคุ้นเคย
Sp3000

1
โดยความซับซ้อนของพหุนามคุณหมายถึงพหุนามในจำนวนหลักของอินพุตหรือพหุนามในมูลค่าของอินพุตหรือไม่
Reto Koradi

3
@anatolyg ของฉันไม่ดุร้าย
aditsu

คำตอบ:


8

Pyth, 9 ไบต์

f!-`*TQ10

สาธิต

สำหรับแต่ละตัวทวีคูณแปลงเป็นสตริงลบตัวเลขใน10(โดยใช้ Pyth ที่มีประโยชน์เพื่อ str cast ในกรณีนี้) จากนั้นจึงลบล้างผลลัพธ์อย่างมีเหตุมีผลยุติการค้นหาเฉพาะเมื่อพบจำนวนที่ถูกต้อง

โบนัสทางออก 10 ไบต์:

f.xi`*TQ2Z

วิธีการแก้ปัญหานี้จะตรวจสอบว่าการแสดงสตริงของจำนวนนั้นสามารถถือเป็นเลขฐานสอง ( i ... 2) และสิ้นสุดลงเมื่อไม่เกิดข้อผิดพลาดในความพยายามนี้


18

Python 2 โซลูชันที่มีประสิทธิภาพ 99

n=input()
d={n:0}
k=1
while min(d):[d.setdefault((x+k)%n,d[x]+k)for x in set(d)];k*=10
print d[0]/n

ขอบคุณ Sp3000 สำหรับเคล็ดลับการเล่นกอล์ฟ

ฉันขอท้าให้คนอื่นโพสต์ (ตามคำตอบของตนเอง) ใช้เวลานานแค่ไหนในการรับผลการป้อนข้อมูล72หรือ99:) ถ้ามันเร็วจริง ๆ ลองแบบ79992ต่อไป (ยัง <1 วินาทีที่นี่)

คำอธิบาย:

ฉันคิดว่ามันไม่จำเป็น (เนื่องจากโค้ดอ่านได้ค่อนข้างดี) แต่ฉันได้รับคำขอดังนั้นที่นี่จึงไป:

แนวคิดแรกคือตัวเลขที่มีลักษณะเป็นเลขฐานสองคือผลรวมของพลังที่แตกต่างกัน 1 ตัวหรือมากกว่าจาก 10 ดังนั้นเราสามารถลองเพิ่มพลังต่าง ๆ จำนวน 10 ด้วยวิธีต่าง ๆ จนกว่าเราจะได้ส่วนที่เหลือ 0

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

dเป็นพจนานุกรม / แผนที่ที่มีกุญแจเหลืออยู่และค่าเป็นตัวเลขที่มีลักษณะเป็นเลขฐานสองที่มีเศษเหลืออยู่ เริ่มต้นn:0เป็นกรณีพิเศษ: มันควรจะเป็น0:0เพื่อให้เราสามารถเริ่มเพิ่มพลังให้กับมัน แต่อัลกอริทึมหยุดเมื่อค้นหากุญแจ 0 ดังนั้นฉันใช้nแทนซึ่งรับประกันว่าจะมีผลเหมือนกันและไม่รบกวนค่าอื่น ๆ

จากนั้นเราเริ่มเพิ่มพลังของ 10 (เก็บไว้ในk) ไปยังหมายเลขที่มีอยู่ทั้งหมดและบันทึกส่วนที่เหลือ เราเพิ่มkส่วนที่เหลือ: (x+k)%nและไปยังหมายเลข: d[x]+k, และบันทึกเฉพาะในกรณีที่เป็นส่วนที่เหลือใหม่: d.setdefault(…), จากนั้นไปที่กำลังต่อไป: k*=10และทำซ้ำจนกว่าเราจะได้รับกุญแจ 0:while min(d)

ในตอนท้ายd[0]ให้ตัวเลขดูไบนารีที่เหลือ 0 mod nดังนั้นเราหารมันด้วยnการหาคำตอบ

หมายเหตุ: โปรแกรมสามารถทำให้มีประสิทธิภาพมากขึ้นโดยการหลีกเลี่ยงจำนวนมาก (การบันทึกเลขชี้กำลังแทนกำลัง 10 และการคำนวณส่วนที่เหลือของพลังจากค่าก่อนหน้า) แต่มันเป็นรหัสกอล์ฟดังนั้น ...

อันที่จริงฉันเขียนรุ่นที่เร็วกว่า:

n=input()
d={n:0}
k=1
b=0
while 0not in d:
 for x in list(d):d.setdefault((x+k)%n,b)
 k=(k*10)%n;b+=1
x=10**d[0]
while x%n:x+=10**d[n-x%n]
print x/n

1
คำตอบของฉันก็ไม่ได้เช่นกัน xD "Dangit, Java, สาปแช่งตัวเลือก Integer.MAX_VALUE ให้เลือกใช้ BigInteger โดยปริยาย!" - โปรแกรมเมอร์ Java ทุกคนเคย
ทำงาน

@VTCAKAVSMoACE ทำไมคุณไม่ใช้ Long
aditsu

อืมมม มันเป็นไบต์พิเศษ แต่ ... คุ้มค่า ขอบคุณ!
Addison Crump

หรือไม่. ที่จริงลดอย่างจริงจัง ขอบคุณ!
Addison Crump

1
กำหนดเวลาสำหรับการแก้ไข 99: aditsu: 0.001 วินาที; xnor: 5+ ชั่วโมงและยังไม่เสร็จสมบูรณ์
user193661

13

Python 2, 47 ไบต์

n=a=input()
while'1'<max(str(a)):a+=n
print a/n

แทรคจำนวนการป้อนข้อมูลและหลายปัจจุบันn aเมื่อดูเหมือนว่าไบนารีเอาท์พุทอัตราส่วนa a/nหากต้องการตรวจสอบว่าเป็นจำนวนที่ทำจาก0'และ1' s '1'เราเปรียบเทียบถ่านสูงสุดในการเป็นตัวแทนในการสตริง

ใช้str(a)แทน`a`เพื่อหลีกเลี่ยงการสิ้นสุดในระยะLยาว แต่น่าเสียดายที่มีขนาดใหญ่กว่า'L''1'


12

Perl, 27 ไบต์

#!perl -p
1while($_*++$\)=~/[2-9]/}{

นับ Shebang เป็นหนึ่งจะถูกนำเข้าจาก stdin

ตัวอย่างการใช้งาน

$ echo 2 | perl dec-bin.pl
5

$ echo 21 | perl dec-bin.pl
481

$ echo 98 | perl dec-bin.pl
112245

Perl, 25 ไบต์

#!perl -p
eval'0b'.++$\*$_||redo}{

การปรับปรุงที่สองไบต์โดย@skmrx

แทนที่จะตรวจสอบกับ regex นี้แทนที่จะพยายามประเมินผลิตภัณฑ์เป็นตัวอักษรไบนารี เมื่อความล้มเหลวมันย้ายไปยังถัดไป โดยทั่วไปแล้วoctฟังก์ชั่นนี้จะใช้สำหรับจุดประสงค์นี้ แต่จะตัดตัวเลขที่ไม่ถูกต้องแบบเงียบ ๆ ซึ่งไม่มีประโยชน์ในการท้าทายนี้


Perl, 40 ไบต์

#!perl -p
1while($b=sprintf"%b",++$i)%$_;$_=$b/$_

ทางออกที่มีประสิทธิภาพมากขึ้น เราวนซ้ำมากกว่าการเป็นตัวแทนไบนารีแปลว่ามันเป็นฐาน 10 แล้วตรวจสอบการหาร Runtimes สำหรับค่าทั้งหมดต่ำกว่า 100 จะเล็กน้อย

ตัวอย่างการใช้งาน

$ echo 72|perl dec-bin.pl
1543209875

$ echo 99|perl dec-bin.pl
1122334455667789

2
ดี :) ฉันได้เรียนรู้สิ่งใหม่สองสามอย่างจากโพสต์ของคุณวันนี้! ในขณะที่อ่านรหัสของคุณฉันพบวิธีที่จะตัดทิ้งสองสามไบต์จากรหัสแรก:eval"0b".$_*++$\||redo}{
svsd

แต่ฉันเดาว่าเราจะต้องรวมuse bigintเพื่อรองรับจำนวนมากที่ OP ได้รับคำสั่งให้ได้รับการสนับสนุน :(
svsd

1
@skmrn นั่นยอดเยี่ยม ฉันลองoct'0b'.++$\*$_แล้ว แต่มันย่อส่วนตัวเลขที่ไม่ถูกต้องออกไปอย่างเงียบ ๆ ฉันไม่คิดว่าจะใช้evalแทน
โม่

11

Javascript, 43 ไบต์

จบลงด้วยวิธีที่สั้นกว่าที่ฉันคิด มันเป็นพื้นเพิ่มyขึ้น 1 y * (input number) = (binary-looking number)จนกว่า เห็นได้ชัดว่าค่อนข้างไม่มีประสิทธิภาพ

for(x=prompt(y=0);!+('0b'+x*++y););alert(y)


Javascript (โซลูชันที่มีประสิทธิภาพยิ่งขึ้น), 53 ไบต์

การเพิ่มขึ้นนี้เป็นหนึ่งในไบนารีจนกว่าy y / (input number) = (number without a remainder)จากนั้นจะแสดงผลออก(number without a remainder)มา

for(x=prompt(y=1);(z=y.toString(2))%x;y++);alert(z/x)


Javascript (โซลูชันที่มีประสิทธิภาพยิ่งขึ้น), 76 ไบต์

วิธีนี้รวมวิธีการก่อนหน้านี้ทั้งสองที่อธิบายไว้ข้างต้น มันตรวจสอบการเพิ่มขึ้นyอย่างใดอย่างหนึ่งจนกว่าy * (input number) = (binary-looking number)(หมายถึงการส่งออกเป็นy) หรือy / (input number) = (number without a remainder)(หมายถึงการส่งออกเป็น(number without a remainder))

for(x=prompt(y=a=0);!a;a=+('0b'+x*++y)?y:(z=y.toString(2))%x?0:z/x);alert(a)


ควรให้ 1 เมื่อเป็นไปได้ (อินพุตตัวอย่าง: 1)
edc65

@ edc65 แก้ไข - ไม่มีการเปลี่ยนแปลงในจำนวนไบต์!
Mama Fun Roll

สิ่งนี้ขัดข้อง Safari 9.0 Jussayin' :)
แอดดิสันครัมพ์

1
แต่มันก็ จำกัด อยู่แค่จำนวนเล็กน้อยในเอาต์พุต หมายเลข Javascript มีความแม่นยำ 17 หลัก OP ขอสิ่งที่ใหญ่กว่า (และสามารถทำได้โดยใช้เลขคณิตแบบแยกส่วน)
edc65

Protip: อย่าลองอินพุต 72. Firefox 41 หยุดทำงานเป็นเวลา 15 นาทีแล้วจึงขัดข้อง ฉันค้นพบวิธีนี้ยาก
ETHproductions

9

Haskell, 72 70 64 60 58 ไบต์

main=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0

แก้ไข: @Jan Dvorak ช่วยฉันประหยัดได้ 4 ไบต์

แก้ไข: @BlackCap บันทึก 2 ไบต์โดยสลับเป็นdoสัญกรณ์ ขอบคุณ!


main=print.f=<<readLn
John Dvorak

คุณสามารถบันทึกไบต์ด้วยการอินไลน์ f:main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
BlackCap

2 จริงmain=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0
BlackCap

@BlackCap: ดีมาก! ขอบคุณมาก!
nimi

7

งูหลาม 2 67 65 63 60 ไบต์

a=input();b=1
while set(`a*b`)&set('23456789'):b+=1
print b

ขอบคุณสถานะ 2 ไบต์และShebang 5 ไบต์!


1
ฉันคิดว่าคุณต้องเริ่มต้นb=1
Anatolyg

2
คุณสามารถโกนได้ 2 ไบต์โดยทำany(c in`a*b`for c in'23456789')
สถานะ

1
ฉันไม่แน่ใจเกี่ยวกับเรื่องนี้ แต่จะnot c in`a*b`for c in'10'ทำงานได้อย่างไร
โคล

2
คุณสามารถบันทึก 6 set('a*b')&set('23456789')ไบต์โดยการเปลี่ยนสภาพในขณะที่คุณ
Kade

2
`ผลิตLสำหรับ longs 'L'>'1'และ
user193661

6

JavaScript (ES6) 222 250

การใช้คณิตศาสตร์ที่มีความแม่นยำตามอำเภอใจ (ปฏิบัติการกับสตริงทศนิยม)

สิ่งนี้สามารถเล่นกอล์ฟได้มากกว่า (ทำได้) แต่ฉันชอบความจริงที่ว่ามันไม่ได้ จำกัด อยู่ที่ตัวเลขมาตรฐานของ JS (ความแม่นยำ 17 หลักทศนิยม) และมันก็รวดเร็ว

ทดสอบการเรียกใช้ตัวอย่างข้อมูลด้านล่างในเบราว์เซอร์ที่สอดคล้องกับ EcmaScript 6 เวลายอมรับได้สูงสุด 9998 - อย่าลอง 9999 และอดทนกับ 999

// As a complete program with I/O via popup  
for(n=+prompt(a=[0],q=[t=1]);t;){for(c=1,t=i=0;i<a.length;i++)a[i]=a[i]&c?0:a[i]|c?(c=0,t+=q[i],1):c=0;c&&(a[i]=c,t+=q[i]=q[i-1]*10%n);t%=n}a.reverse().map(a=>(z+=[a],d=z/n|0,z%=n,r||d?r+=d:0),r='',z=0);alert([r,a.join``])

// As a testable function
f=n=>{
  for(a=[0],q=[t=1];t;)
  {
    for(c=1,t=i=0;i<a.length;i++)
      a[i]=a[i]&c?0:a[i]|c?(c=0,t+=q[i],1):c=0
    c&&(a[i]=c,t+=q[i]=q[i-1]*10%n);
    t%=n
  }  
  a.reverse().map(a=>(z+=[a],d=z/n|0,z%=n,r||d?r+=d:0),r='',z=0)
  return [r,a.join``]
}

// Test and timing
out = x => O.innerHTML += x + '\n'

setTimeout(_=>{
;[1,2,10, 21, 23, 98, 72, 9, 99, 999]
.forEach((test,i) => { 
  var t0 = ~new Date  
  var result = f(test)
  out('n='+test+' '+result+' time(ms) ' + (t0-~new Date))
})},100)  
<pre id=O>Timing test cases ...
</pre>

อ่านเพิ่มเติม

นี่เป็นรุ่นแรกที่มีโมดูลัสและการหารแบบยาวเป็นฟังก์ชันแยกออกจากกัน

// function M - Modulus with arbitrary precision - a is a string of decimal digits
M = (a, b, q = 1, t = 0, j = a.length) => {
  while (j--) + a[j] ? t += q : 0, q = (q * 10) % b;
  return t % b
}

// function D - Long division with arbitrary precision - a is a string of decimal digits
D = (a, b, r = '', z = 0) => [...a].map(a => (z += a, d = z / b | 0, z %= b, r || d ? r += d : 0)) && r

// Testable function 
f = n => {
  for (i = 0; ++i < 1e7 && (z = M(v = i.toString(2), n)););
  return z ? ['big'] : [D(v, n), v]
}

ฉันได้มันมาทำงานใน Firefox แต่ดูเหมือนจะไม่จัดการกับตัวเลขที่มากขึ้นเช่น 999
aditsu

ฉันมีรุ่นใหม่ที่สามารถจัดการ 999 ใน 36 วินาที แต่ไม่หวังว่าจะถึง 9999 ด้วยการหมดเวลาของจาวาสคริปต์ (เพิ่มแต่ละ '9' ต้องใช้ 2 ^ 9 (~ 500) เวลาที่จะทำให้เสร็จ)
edc65

@aditsu นั้นดีที่สุดที่ฉันสามารถทำได้ใน JavaScript (แต่ใน C # มันค่อนข้างเหมือนกัน) รอคำอธิบายขั้นตอนวิธีที่น่าเหลือเชื่อของคุณไว้ก่อน
edc65

ฉันได้เพิ่มคำอธิบายตอนนี้
aditsu



4

PHP, 50 ไบต์

while(preg_match('/[^01]/',$argv[1]*++$y));echo$y;

บางกรณีทดสอบ

1 > 1
2 > 5
12 > 925
21 > 481

1
จะทำอะไรแบบนี้นี่มันสั้นกว่าที่ฉันคิดเอาไว้
Martijn

4

CJam, 19 17 16 ไบต์

li:V!{)_V*sAs-}g

ลองออนไลน์

กำลังแก้ปัญหาสัตว์เดรัจฉานพยายามค่าตามลำดับจนกว่าจะพบเงื่อนไขหนึ่ง

รุ่นล่าสุดบันทึก 2 ไบต์ขอบคุณที่ใช้Asแทน"01"การสร้างสตริงที่มี0และ1ตามที่ @aditsu แนะนำ โซลูชันที่เสนอแบบเต็มในความคิดเห็นจะช่วยประหยัดอีกไบต์ แต่มันก็ดูค่อนข้างแตกต่างจากของฉันดังนั้นฉันไม่ต้องการโพสต์ภายใต้ชื่อของฉัน

และอีก 1 ไบต์ที่บันทึกโดย @Dennis

คำอธิบาย:

li      Get input and convert to int.
:V      Save it in variable V.
!       Negate the value. Since we saved it in V, we don't need it on the stack anymore.
        But we need 0 on the stack as the start value for y. This conveniently
        accomplishes both with a single operator, since the input is guaranteed to be
        larger than 0.
{       Loop over y.
  )       Increment y.
  _       Copy it.
  V*      Multiply with input in variable V.
  s       Convert to string.
  As      Push the string "10", as the number 10 converted to a string .
  -       Remove 0 and 1 digits. This will result in an empty list if there were only
          0 and 1 digits. The empty list is falsy, and will terminate the loop.
}g      End loop.

3
16:li0{1$+_sAs-}g\/
aditsu

ขอบคุณ @aditsu ฉันไม่ต้องการคัดลอกโซลูชันทั้งหมดของคุณภายใต้ชื่อของฉัน ฉันใช้เวลาในAsการสร้างสตริงเนื่องจากมันเป็นการเปลี่ยนแปลงในท้องถิ่นมากซึ่งในความเข้าใจย้อนหลัง (ซึ่งง่ายกว่ามากเสมอ ... ) ฉันควรจะคิด
Reto Koradi

1
@RetoKoradi 16 ไบต์การแก้ไขน้อย: li:V!{)_V*sAs-}gนอกจากนี้0{)_easi*sAs-}g(15 ไบต์) ทำงานร่วมกับตัวแปลภาษา Java และอาร์กิวเมนต์บรรทัดคำสั่ง
เดนนิส

4

Python 3 2, 101 76 Bytes

-25ไบต์ขอบคุณ @aditsu

เกือบมีประสิทธิภาพเท่ากับโซลูชันของ @ aditsu

99 -> 0.436 Seconds
72 -> 0.007 Seconds
b,m,n=1,1,input()
while b%n:
 b=int("{0:b}".format(m))
 m+=1
print b/n

แทนที่จะพยายามวนซ้ำทวีคูณเพื่อเพิ่มฉันพยายามวนผ่านผลิตภัณฑ์ที่ฉันสร้างในรูปแบบ 'ไบนารี'


ไม่เลว :) แล้วประมาณ 9999 ล่ะ?
aditsu

2
เคล็ดลับการเล่นกอล์ฟ: ใช้ python 2 ( n=input()), while b%n:(เริ่มต้นbที่ 1), ไม่มีการเยื้อง
aditsu

@aditsu ขอบคุณ! 9999 hmmm ดูเหมือนว่าจะใช้เวลาสองสามวันกลับไปที่กระดานวาดภาพ -_-
Rnet

1
bin(m)[2:]ควรสั้นกว่าสตริงรูปแบบ การกำหนดb=m=1ซ้ำสองครั้งบนควรประหยัดเช่นกัน
โม่

4

Java, 213 ไบต์

import java.math.*;class P{public static void main(String[]a){BigInteger b=new java.util.Scanner(System.in).nextBigInteger(),c,d=c=b.ONE;while(!(b.multiply(c)+"").matches("[01]+"))c=c.add(d);System.out.print(c);}}

ใช้BigIntegers และเช่นนั้นมี (สำหรับเจตนาและวัตถุประสงค์ที่เหมาะสมทั้งหมด) ขนาดอินพุตที่ไม่ จำกัด ไม่แน่ใจเกี่ยวกับความซับซ้อนที่ขึ้นอยู่กับอัตราการเติบโตของฟังก์ชันของเราที่นี่

ขอบคุณ geobits และ ypnypn สำหรับการบันทึกจำนวนหนึ่งไบต์


สวัสดีคุณจะเรียกสิ่งนี้ในวิธีการหลักของคุณได้อย่างไร ลองใช้ แต่ไม่ประสบความสำเร็จ
Yassin Hajaj

คุณต้องเพิ่มโมเดอเรเตอร์staticในเมธอด
SuperJedi224

1
คำถามบอกว่าการแก้ปัญหาควรเป็นโปรแกรมที่สมบูรณ์ไม่ใช่แค่ฟังก์ชั่น
raznagul

คุณสามารถตัด 15 ด้วยb.ONEและ!(b.multiply(c)+"")(แทนtoString())
Geobits

@raznagul: แก้ไข
SuperJedi224

4

C, 3675 ไบต์

ตราบใดที่ Code Golf ...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

#define min_n 1
#define max_n 10000

unsigned *mod_list; // list of mods to check
unsigned mod_list_length; // number of mods to check
char *graph; // for each mod, the power of 10 that gives it

void BuildGraph(unsigned n)
{
    unsigned mod10 = 10 % n;
    int pow = 1;

    memset(graph, 0, n);
    if (n == 1)
        return;
    mod_list[0] = 0; // mod 0 - no path coming to it yet
    mod_list[1] = 1; // mod 1 - 10^0 coming to it
    mod_list_length = 2;
    while (graph[0] == 0)
    {
        // We are going to change mod_list_length by adding new nodes.
        // This should not affect the set of nodes we check, so save its old value.
        unsigned mod_list_limit = mod_list_length;
        for (unsigned i = 0; i < mod_list_limit; ++i)
        {
            unsigned mod = mod_list[i] + mod10;
            if (mod >= n)
                mod -= n;
            if (graph[mod] == 0 && mod != 1) // new node?
            {
                graph[mod] = pow; // record the power of 10 with which we come to this node
                mod_list[mod_list_length++] = mod; // add it to the list of nodes
                if (mod == 0) // found the path to 0?
                    return; // stop calculating
            }
        }
        mod10 = (unsigned long long)mod10 * 10 % n; // go to next power of 10
        ++pow;
    }
}

void PrintPath(unsigned n, char *out)
{
    // Going to output powers of 10 in descending order
    unsigned mod = 0; // start at node 0
    int prev_pow = graph[mod] + 1; // happens to be an acceptable initialization
    do {
        int pow = graph[mod];
        while (--prev_pow > pow) // output the proper number of 0-digits
            *out++ = '0';
        *out++ = '1'; // output the digit 1, corresponding to current power of 10
        if (pow == 0)
            break;
        unsigned mod10 = 1;
        for (int p = 0; p < pow; ++p)
            mod10 = (unsigned long long)mod10 * 10 % n;
        mod = (mod + n - mod10 % n) % n; // go to the preceding node
    } while (mod != 0);
    while (--prev_pow >= 0) // output the proper number of 0-digits
        *out++ = '0';
    *out++ = 0;
}

// The long division algorithm
void DivideAndPrint(char *product, unsigned n, FILE* file)
{
    unsigned long long temp = 0;
    int print = 0;
    while (*product != '\0')
    {
        temp = temp * 10 + *product++ - '0';
        if (temp >= n)
            print = 1;
        if (print)
        {
            unsigned quotient = (unsigned)(temp / n);
            unsigned remainder = temp % n;
            fputc('0' + quotient, file);
            temp = remainder;
        }
    }
    fputc('\n', file);
    assert(temp == 0); // if not divisible, there is a bug somewhere
}

void Calc(unsigned n, FILE* file)
{
    char result[99];
    BuildGraph(n);
    PrintPath(n, result);
    DivideAndPrint(result, n, file);
}

int main(int argc, char* argv[])
{
    unsigned n;

    if (argv[1])
    {
        FILE* file = fopen(argv[1], "wt");
        mod_list = calloc(max_n, sizeof(int));
        graph = calloc(max_n, 1);
        clock_t before = clock();
        for (n = min_n; n <= max_n; ++n)
        {
            Calc(n, file);
        }
        clock_t after = clock();
        fprintf(stderr, "Time: %f\n", (after - before) / (double)CLOCKS_PER_SEC);
    }
    else
    {
        scanf("%u", &n);
        mod_list = calloc(n, sizeof(int));
        graph = calloc(n, 1);
        Calc(n, stdout);
    }
}

ทำงานด้วยไม่มีพารามิเตอร์บรรทัดคำสั่ง - จะได้รับnจากการและผลผลให้stdin stdoutเรียกใช้ด้วยชื่อไฟล์ - มันเขียนผลลัพธ์สำหรับn = 1...10000ลงในไฟล์นั้นและวัดเวลา

ประสิทธิภาพสำหรับ 1 ... 10,000: 140 ms

รหัสนี้ใช้อัลกอริทึมที่เสนอโดย aditsuนำมาใช้ใน C เพื่อความเร็ว ฉันไม่พยายามตีกอล์ฟดังนั้นรหัสจะอ่านง่ายขึ้น

ฉันใช้งานมันเป็นครั้งแรกใน C ++ โดยใช้std::mapเพื่อบันทึกผลลัพธ์ของการค้นหาและมันค่อนข้างช้า อย่างไรก็ตามกุญแจของmapจำนวนเต็มต่อเนื่องกัน (ฉันเรียกพวกมันว่าmods เพราะพวกมันแทนตัวเลขโมดูโลn) ดังนั้นมันจึงเป็นเรื่องธรรมดาที่จะใช้อาเรย์ - ดังนั้นฉันจึงเขียนมันใหม่ในซี

ความกังวลเพิ่มประสิทธิภาพเพิ่มเติมค่าของการทำแผนที่ที่ - เพื่อหลีกเลี่ยงการเก็บจำนวนเต็มใหญ่สำหรับแต่ละmodผมเก็บเฉพาะพลังงานที่ใหญ่ที่สุด 10 มี - modเป็นเพียงข้อมูลพอที่จะไปก่อนหน้านี้ ดังนั้นอาร์เรย์จึงเป็นแผนภูมิการค้นหา / กราฟ เมื่อการค้นหามาถึงการmod = 0ติดตามโหนดของต้นไม้กลับไปที่รูทจะให้กำลัง 10 จากลำดับถัดลงมา

เนื่องจากการค้นหามักจะหยุดค่อนข้างเร็วด้วยการเยี่ยมชมเพียงไม่กี่โหนดฉันจึงต้องการรายการโหนดที่ใช้งานอยู่ มันนำมาใช้เป็นอาร์เรย์ที่มีความยาวmod_listmod_list_length

สถิติรันไทม์บางอย่าง (บนเครื่องที่มี RAM ขนาด 16 GB ซึ่งดูเหมือนจะมีความสำคัญสำหรับขนาดใหญ่nเนื่องจากโปรแกรมจัดสรร5nหน่วยความจำไบต์):

  • อินพุต99999999- 2 วินาที
  • อินพุต999999999- 27 วินาที (ผลลัพธ์คือ111111111222222222333333333444444444555555555666666666777777777888888889- อาจเป็นผลลัพธ์ที่ใหญ่ที่สุดที่เป็นไปได้สำหรับจำนวนเต็ม 32 บิต)
  • อินพุต2147483647- 26 วินาที (ผลลัพธ์คือ4661316525084584315813)
  • อินพุต1999999998- 52 วินาที (อาจเป็นเวลารันนานที่สุดที่เป็นไปได้สำหรับจำนวนเต็ม 32 บิต)

2
ผมเข้าใจว่าคุณหลังจากที่โปรดปราน แต่แม้ดังนั้นนี่คือรหัสกอล์ฟคำถามและกฎระเบียบเว็บไซต์คุณต้องทำให้บางคนพยายามที่จะเล่นกอล์ฟรหัสของคุณ
Peter Taylor

โปรแกรมของคุณมี 3546 ไบต์
aditsu

@aditsu ฉันวัดนับไบต์ใน Windows ซึ่งใช้ CR / LF สไตล์
anatolyg

4

C ++ 11, หลายไบต์, เร็วมาก, ว้าว (1.5 วิเมื่อ 1999999998, 0.2 วิใน 1 … 10,000)

(เวอร์ชัน Python ที่ Golfed ด้านล่าง)

เราเริ่มต้นด้วยแนวคิดที่ค่อนข้างคล้ายกับโซลูชันของ aditsu ซึ่งเราได้สร้างชุดสะสมของชิ้นส่วนแยกส่วนที่สามารถเข้าถึงได้ในขั้นตอน n แต่แทนที่จะรอจนกว่าเราจะพบส่วนที่เหลือ 0 เราจะตรวจสอบหาส่วนที่เหลือ a และ b สองตัวที่· 10 ^ n + b = 0 วิธีการประชุมตรงกลางตรงนี้จะลดความลึกของต้นไม้การค้นหา เร็วกว่ามากสำหรับอินพุตขนาดใหญ่และใช้หน่วยความจำน้อยกว่ามาก

มาตรฐานบางอย่าง:

$ echo 99999999 | \time ./decbin
1111111122222222333333334444444455555555666666667777777788888889
0.18user 0.01system 0:00.20elapsed 99%CPU (0avgtext+0avgdata 69360maxresident)k
0inputs+0outputs (0major+16276minor)pagefaults 0swaps
$ echo 999999999 | \time ./decbin
111111111222222222333333333444444444555555555666666666777777777888888889
1.22user 0.04system 0:01.27elapsed 100%CPU (0avgtext+0avgdata 434776maxresident)k
0inputs+0outputs (0major+37308minor)pagefaults 0swaps
$ echo 2147483647 | \time ./decbin
4661316525084584315813
0.00user 0.00system 0:00.01elapsed 72%CPU (0avgtext+0avgdata 5960maxresident)k
0inputs+0outputs (0major+1084minor)pagefaults 0swaps
$ echo 1999999998 | \time ./decbin
555555556111111111666666667222222222777777778333333333888888889444444445
1.42user 0.08system 0:01.50elapsed 100%CPU (0avgtext+0avgdata 544140maxresident)k
0inputs+0outputs (0major+38379minor)pagefaults 0swaps
$ \time ./decbin 10000.out
0.19user 0.00system 0:00.20elapsed 100%CPU (0avgtext+0avgdata 3324maxresident)k
0inputs+264outputs (0major+160minor)pagefaults 0swaps

รหัส:

#include <algorithm>
#include <boost/iterator/transform_iterator.hpp>
#include <fstream>
#include <list>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

using namespace boost;
using namespace std;

static inline bool cmp_first_partnered(pair<int, pair<int, int>> a,
                                       pair<int, pair<int, int>> b) {
  return a.first < b.first;
}
static inline bool eq_first_partnered(pair<int, pair<int, int>> a,
                                      pair<int, pair<int, int>> b) {
  return a.first == b.first;
}

static pair<int, int> retrace(int modulus, int place, pair<int, int> state,
                              list<vector<int>>::iterator i,
                              list<vector<int>>::iterator j, string &ret) {
  if (i == j)
    return state;
  state = retrace(modulus, (place * 10LL) % modulus, state, next(i), j, ret);
  int remainder = state.first;
  long long k = state.second * 10LL;
  if (!binary_search(i->cbegin(), i->cend(), remainder)) {
    remainder = ((long long)remainder + modulus - place) % modulus;
    k += 1;
  }
  int digit = k / modulus;
  if (digit != 0 || ret.size())
    ret += '0' + digit;
  return make_pair(remainder, k % modulus);
}

static void mult(int modulus, int x, int y,
                 vector<pair<int, pair<int, int>>>::iterator i,
                 vector<pair<int, pair<int, int>>>::iterator j) {
  if (y - x == 1) {
    for (auto k = i; k != j; k++)
      k->first = (k->first * 10LL) % modulus;
    return;
  }

  int z = (x + y) / 2;
  vector<pair<int, pair<int, int>>>::iterator k = lower_bound(
      i, j, make_pair(int(((long long)modulus * z + 9) / 10), make_pair(0, 0)));
  mult(modulus, x, z, i, k);
  mult(modulus, z, y, k, j);
  inplace_merge(i, k, j,
                [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {
                  return make_pair(a.first, a.second.second) <
                         make_pair(b.first, b.second.second);
                });
}

static string go(int modulus) {
  if (modulus == 1)
    return "1";

  int sequence = 1;
  list<vector<int>> v = {{0}};
  vector<pair<int, pair<int, int>>> partnered;
  int place = 1;
  while (true) {
    v.emplace_back(v.rbegin()->size() * 2);
    vector<int> &previous = *next(v.rbegin()), &current = *v.rbegin();

    auto offset = [modulus, place, sequence](int a) {
      return (a + (long long)place) % modulus;
    };
    auto old_mid =
        lower_bound(previous.cbegin(), previous.cend(), modulus - place),
         new_mid = lower_bound(previous.cbegin(), previous.cend(), place);
    current.resize(
        set_union(new_mid, previous.cend(),
                  make_transform_iterator(previous.cbegin(), offset),
                  make_transform_iterator(old_mid, offset),
                  set_union(previous.cbegin(), new_mid,
                            make_transform_iterator(old_mid, offset),
                            make_transform_iterator(previous.cend(), offset),
                            current.begin())) -
        current.begin());

    int place2 = modulus - (long long)place * place % modulus;
    auto offset_partnered = [modulus, place, place2,
                             sequence](pair<int, pair<int, int>> a) {
      return make_pair((a.first + (long long)place2) % modulus,
                       make_pair((a.second.first + (long long)place) % modulus,
                                 sequence + a.second.second));
    };
    auto old_mid_partnered =
        lower_bound(partnered.cbegin(), partnered.cend(),
                    make_pair(modulus - place2, make_pair(0, 0))),
         new_mid_partnered = lower_bound(partnered.cbegin(), partnered.cend(),
                                         make_pair(place2, make_pair(0, 0)));
    vector<pair<int, pair<int, int>>> next_partnered(partnered.size() * 2 + 1);
    auto i =
        set_union(partnered.cbegin(), new_mid_partnered,
                  make_transform_iterator(old_mid_partnered, offset_partnered),
                  make_transform_iterator(partnered.cend(), offset_partnered),
                  next_partnered.begin(), cmp_first_partnered);
    if (new_mid_partnered == partnered.cend() ||
        new_mid_partnered->first != place2)
      *i++ = make_pair(place2, make_pair(place, sequence));
    next_partnered.resize(
        set_union(new_mid_partnered, partnered.cend(),
                  make_transform_iterator(partnered.cbegin(), offset_partnered),
                  make_transform_iterator(old_mid_partnered, offset_partnered),
                  i, cmp_first_partnered) -
        next_partnered.begin());
    partnered.swap(next_partnered);

    sequence += previous.size();

    place = (place * 10LL) % modulus;

    mult(modulus, 0, 10, partnered.begin(), partnered.end());
    partnered.resize(
        unique(partnered.begin(), partnered.end(), eq_first_partnered) -
        partnered.begin());

    auto with_first = [](int a) { return make_pair(a, make_pair(a, 0)); };

    vector<pair<int, pair<int, int>>> hits;
    set_intersection(partnered.cbegin(), partnered.cend(),
                     make_transform_iterator(current.cbegin(), with_first),
                     make_transform_iterator(current.cend(), with_first),
                     back_inserter(hits), cmp_first_partnered);

    if (hits.size()) {
      pair<int, pair<int, int>> best = *min_element(
          hits.begin(), hits.end(),
          [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {
            return a.second.second < b.second.second;
          });
      string ret = "";
      pair<int, int> state =
          retrace(modulus, 1, make_pair(best.second.first, 0), v.begin(),
                  prev(v.end()), ret);
      retrace(modulus, 1, make_pair(best.first, state.second), v.begin(),
              prev(v.end()), ret);
      return ret;
    }
  }
}

int main(int argc, const char *argv[]) {
  ios_base::sync_with_stdio(false);
  if (argc >= 2) {
    ofstream ofs(argv[1]);
    for (int modulus = 1; modulus <= 10000; modulus++)
      ofs << go(modulus) << '\n';
  } else {
    int modulus;
    cin >> modulus;
    cout << go(modulus) << '\n';
  }
  return 0;
}

Python, 280 ไบต์ (8.6 วินาทีใน 1999999998 กับ PyPy)

n=input()
if n<2:print 1;exit()
d={0:0}
l=[]
k=1
b=x=y=0
while 1:
 for a in[0]+l:
  m=(a+k)%n
  if m not in d:l.append(m);d[m]=b
 k=(k*10)%n;b+=1
 for a in l:
  if(-k*a)%n in d:
   while(a-x)%n:x+=10**d[(a-x)%n]
   while(-y-k*a)%n:y+=10**d[(-y-k*a)%n]
   print(10**b*x+y)/n;exit()

2
ผมเข้าใจว่าคุณหลังจากที่โปรดปราน แต่แม้ดังนั้นนี่คือรหัสกอล์ฟคำถามและกฎระเบียบเว็บไซต์คุณต้องทำให้บางคนพยายามที่จะเล่นกอล์ฟรหัสของคุณ
Peter Taylor

1
@PeterTaylor ดีมากฉันเพิ่มเวอร์ชัน golfed ใน Python
Anders Kaseorg

3

Mathematica 115 ไบต์

p=Drop[Union[FromDigits/@Flatten[Table[Tuples[{0,1},{k}],{k,2,12}],1]],2];
i=Input[];FirstCase[p,x_/;Divisible[x,i]]

3

Java 156 ไบต์

public class P{public static void main(String[]a){long x=Long.valueOf(a[0]),y;for(y=2;!(""+x*y).replaceAll("1|0","").isEmpty();y++);System.out.println(y);}}

ขอบคุณมากสำหรับ aditsu :)


คุณไม่จำเป็นต้องพื้นที่หลังจากที่[], yสามารถlongเกินไปคุณลืมx*y+""เคล็ดลับในโปรแกรมที่ 2 ใช้isEmptyแทนการตรวจสอบความยาวใช้;แทน{}
aditsu

อย่างไรก็ตามยินดีต้อนรับสู่ code golf :)
aditsu

ฉันต้องบอกว่าฉันประทับใจ แต่การทำให้คุณlongไม่ทำให้รหัสสั้นลง
Joba

ใช่จะ:long x=…,y;
aditsu

yต้องเริ่มต้นจาก 1 คุณสามารถเริ่มต้นได้ในการประกาศคลาสของคุณไม่จำเป็นต้องเป็นสาธารณะและคุณสามารถย้ายy++ไปยังx*yส่วน ( x*y++)
aditsu

2

Pyth - 12 11 ไบต์

ใช้ตัวกรองที่มี arg แบบตัวเลขเพื่อให้ได้จำนวนธรรมชาติเป็นอันดับแรกที่ตอบสนองเพรดิเคตค่าเริ่มต้นคือ 1 ซึ่งเป็นสิ่งที่เราต้องการ Setwise diff เพื่อตรวจสอบว่ามีค่าเป็นศูนย์

f!-j*QT10U2

Test Suite


"01แปลงสตริงและลบ ประหยัดถ่านหนึ่งตัว
Jakube

2

R, 45 ไบต์

x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y

การใช้งาน:

> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 2
2: 
Read 1 item
[1] 5
> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 21
2: 
Read 1 item
[1] 481
> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 42
2: 
Read 1 item
[1] 2405

2

Java, 198 193 181 ไบต์

ขอบคุณ @aditsu สำหรับการตัด 5 ไบต์และเพิ่มช่วงของจำนวนที่ทดสอบได้!

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

ฉันรู้ว่าฉันจะไม่ชนะ แต่ฉันหวังว่านี่จะเป็นแรงบันดาลใจให้คนอื่นตอบสั้นลง

class A {public static void main (String [] a) {สำหรับ (long i = 1 ;; i ++) {ลอง {long b = Long.parseLong (a [0]) ถ้า if (b * i <0) แตก; Long.parseLong (b * i + "", 2); System.out.println (i);} catch (ข้อยกเว้น e) {}}}}

Ungofled:

คลาส A {
   โมฆะคงที่สาธารณะหลัก (String [] a) {
      สำหรับ (long i = 1 ;; i ++) {// infinite loop เริ่มต้นที่ 1
         ลอง {// หากมีข้อผิดพลาดเกิดขึ้นจากการพยายามแยกวิเคราะห์เป็นไบนารีให้รีสตาร์ทขณะที่เพิ่ม 1 ลงใน i
            ยาว b = ยาว.parseLong (a [0]); // สำหรับภายหลัง - ประกาศสั้นกว่าใช้สองครั้ง
            ถ้า (b * ฉัน <0) แบ่ง; // แยกออกจากโปรแกรมถ้าเราวนลูป
            Long.parseLong (b * i + "" 2); // ทวีคูณออกมาแล้วดูว่ามันผ่านได้เป็นเลขฐานสองมิฉะนั้นจะเกิดข้อผิดพลาดและกลับไปที่ด้านบนของลูป
            System.out.println (ข); // พิมพ์ออกมา
         } catch (Exception e) {} // ไม่จับอะไรเลย
      }
   }
}

2
มันเป็นเรื่องตลกที่Longสั้นกว่าInteger:)
anatolyg

3
ประชดที่แท้จริงที่สุดก็คือ
Addison Crump

2

C, 107 101 ไบต์ ( 105 99 ไบต์สำหรับ 32- บิต)

มีการขาดคำตอบที่ชัดเจนใน C ในการเขียนโค้ดกอล์ฟ แน่นอน C ไม่ใช่ตัวเลือกที่ดีที่สุดสำหรับการเขียนโปรแกรมที่เล็กที่สุดเท่าที่จะเป็นไปได้ แต่ก็ไม่ได้แย่ขนาดนั้น:

main(d,b){char s[9];gets(s);for(b=atoi(s);sprintf(s,"%d",b*d),strspn(s,"01")[s];d++);printf("%d",d);}

คุณสามารถทำได้โดยไม่มี #includes แต่จากนั้นนิยามฟังก์ชันทั้งหมดจะเป็นนัย ข้อเสียเปรียบหลักคือสิ่งนี้ทำให้เกิดการสันนิษฐานว่าฟังก์ชั่นทั้งหมดกลับ ints นี่เป็นปัญหาในเครื่อง 64 บิตสำหรับฟังก์ชั่นที่ส่งคืนตัวชี้ หากคุณอยู่บนเครื่อง 32- บิตคุณสามารถลบออกได้ 2 ไบต์:

main(d,b){char s[9];for(b=atoi(gets(s));sprintf(s,"%d",b*d),strspn(s,"01")[s];d++);printf("%d",d);}

รุ่นที่อ่านได้ค่อนข้างมากกว่า:

int main()
{
  char s[9];
  gets(s);
  int d = 1;
  int b = atoi(s);
  for (; sprintf(s, "%d", b * d), strspn(s, "01")[s]; d++);
  printf("%d", d);
}

2

เวลา C # ใกล้ 5 วินาที (1 ถึง 10,000)

ตามที่ร้องขอนี่คือโปรแกรม C # ที่ตอบโจทย์ความท้าทายดั้งเดิม อินพุตเป็นอาร์กิวเมนต์บรรทัดรับคำสั่งเอาต์พุตไปยังคอนโซล

using System;using System.Collections.Generic;using System.Numerics;using System.Linq;
class P{static void Main(string[] a){int m,n=int.Parse(a[0]);var d=new Dictionary<int,long>();long b;int h;
for(d[n]=0,b=h=1;;b*=2,h=(h*10)%n)foreach(int k in d.Keys.Reverse())if(!d.ContainsKey(m=(h+k)%n)){
var w=d[k]|b;if(m==0){Console.Write(BigInteger.Parse(Convert.ToString(w,2))/n);return;}d.Add(m,w);}}}

จากนั้นสำหรับรางวัล: เงินรางวัลควรไปที่ aditsu เนื่องจากฉันคิดว่าอัลกอริทึมของเขาไม่สามารถถูกโจมตีได้ในแง่ของความสมบูรณ์ แต่การตอบคำถามด้วยตนเองเป็นสิ่งที่น่าอัศจรรย์เช่นกัน

นี่คือการใช้งานที่รวดเร็วของฉันใน C # ฉันคิดว่าใน C ++ มันอาจจะเร็วกว่า (อาจเป็น 2x) คอมไพล์และทดสอบด้วย Visual Studio 2010,. NET Framework 4, 64 bits เปลี่ยนเส้นทางเอาต์พุตไปเป็น nul เวลา: 00: 00: 05.2604315

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Diagnostics;

class Program
{
   static BigInteger Find(int n)
   {
      var d = new Dictionary<int, long>();
      long kb;
      int km;
      d[n] = 0;
      for (kb = km = 1; ; kb *= 2, km = (km * 10) % n)
      {
         foreach (int key in d.Keys.Reverse())
         {
            int m = (km + key) % n;
            if (!d.ContainsKey(m))
            {
               long w = d[key] | kb;
               if (m == 0)
               {
                  return BigInteger.Parse(Convert.ToString(w, 2));
               }
               d.Add(m, w);
            }
         }
      }
   }

   static void Exec(int n, out string sq, out string sa)
   {
      var v = Find(n);
      sq = (v/n).ToString();
      sa = v.ToString();
   }  

   static void Main(string[] args)
   {
      // string n = Console.ReadLine();
      int limit = int.Parse(args[0]);
      string q ="", a = "";
      Stopwatch x = new Stopwatch();
      x.Start();
      for (int n = 1; n <= limit; n++)
      {
         Exec(n, out q, out a);
         Console.WriteLine("{0} {1} {2}", n, q, a);
      }
      x.Stop();
      Console.Error.WriteLine("{0}", x.Elapsed);
   }
}

ครั้ง 4.1 ฉันสะกดผิดในค่าหัว ด้วย PyPy รุ่นล่าสุดรุ่นที่เร็วขึ้นของ aditsu คูณประมาณ 8 วินาทีดังนั้นนี่จึงเร็วเป็นสองเท่า
primo

ผมเข้าใจว่าคุณหลังจากที่โปรดปราน แต่แม้ดังนั้นนี่คือรหัสกอล์ฟคำถามและกฎระเบียบเว็บไซต์คุณต้องทำให้บางคนพยายามที่จะเล่นกอล์ฟรหัสของคุณ
Peter Taylor

ฉันไม่ได้อยู่หลังเงินรางวัลมันเป็นเพียงตัวอย่างของการนำไปปฏิบัติ แต่คุณถูกต้องฉันจะเพิ่มเวอร์ชัน golfed
edc65

@PeterTaylor เป็นไปได้ไหมในตอนนี้?
edc65

โดยวิธีการทำไมKeys.Reverse? คำสั่งซื้อสำคัญหรือไม่ หากเป็นเพียงเพื่อหลีกเลี่ยงปัญหาการเกิดพร้อมกันToListก็จะสั้นลง
Peter Taylor

2

C พร้อม GMP (621 ไบต์เร็ว)

ฉันพยายามที่จะเร็วและสั้น แต่โปรดปรานเร็ว การดำเนินการนี้จะใช้เป็นรุ่นที่ดีขึ้นเล็กน้อยของ speedup จำนวนทฤษฎีที่ผมกล่าวถึงในความคิดเห็นในคำตอบของ aditsu

บันทึกเป็นและรวบรวมกับpseudobinary.c gcc pseudobinary.c -lgmp -o pseudobinaryโปรดทราบว่านี่จะจัดสรรหน่วยความจำจำนวนมากสำหรับอินพุตขนาดใหญ่ที่คุณจะต้องรวบรวมสำหรับแพลตฟอร์ม 64 บิต

#include <gmp.h>
int main(int y,char*z[]){int i,n,b,c,e,f,m,*j,*k,*l,*r,*h;char *d,*s;mpz_t
B,I,Q;i=atoi(z[1]);n=i;for(b=0;n%10<1;++b)n/=10;for(;n%2<1;++b)n/=2;for(;n%5<1;++b)n/=5;if(n<2)--b;d=calloc(n,1);j=calloc(n,sizeof(int));r=calloc(99,sizeof(int));c=2;d[1]=1;*j=r[1]=e=1;l=j+1;for(s=0;!s;++c){r[c]=e=e*10%n;k=l;for(h=j;h<k;h++){f=*h;m=(e+f)%n;if(d[m]<1){*l++=m;if(m<1){s=malloc(99);memset(s,48,99);for(f=c;f;f=d[m=(m+n-r[f])%n])s[c-f]++;s[c]=0;h=k;}d[m]=c;}}}f=strlen(s);s[f]=48;s[f+b]=0;mpz_init_set_str(B,s,10);mpz_init_set_si(I,i);mpz_init(Q);mpz_divexact(Q,B,I);d=mpz_get_str(0,10,Q);printf("%s\n",d);return 0;}

เวอร์ชันลูปสำหรับการจับเวลา (751 ไบต์)

#include <gmp.h>
char **v;int main(){int i,n,b,c,e,f,m,*j,*k,*l,*r,*h;char *d,*s;mpz_t
B,I,Q;v=calloc(10001,sizeof(char*));v[1]=s=malloc(99);memset(s,48,99);*s=49;s[1]=0;for(i=0;++i<10001;){n=i;for(b=0;n%10<1;++b)n/=10;for(;n%2<1;++b)n/=2;for(;n%5<1;++b)n/=5;d=calloc(n,1);j=calloc(n,sizeof(int));r=calloc(99,sizeof(int));c=2;d[1]=1;*j=r[1]=e=1;l=j+1;for(;!v[n];++c){r[c]=e=e*10%n;k=l;for(h=j;h<k;h++){f=*h;m=(e+f)%n;if(d[m]<1){*l++=m;if(m<1){v[n]=s=malloc(99);memset(s,48,99);for(f=c;f;f=d[m=(m+n-r[f])%n])s[c-f]++;s[c]=0;h=k;}d[m]=c;}}}free(d);free(j);free(r);s=v[n];f=strlen(s);s[f]=48;s[f+b]=0;mpz_init_set_str(B,s,10);mpz_init_set_si(I,i);mpz_init(Q);mpz_divexact(Q,B,I);d=mpz_get_str(0,10,Q);printf("%s\n",d);free(d);s[f+b]=48;s[f]=0;}return 0;}

เวอร์ชันลูป Ungolfed

#include <gmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **cache;

int main() {
    int i,n,shift,_kb,km,key,m,*ks,*ksi,*nksi,*res,*ii;
    char *d,*s;
    mpz_t B,I,Q;

    cache = calloc(10001,sizeof(char*));
    if (!cache) { printf("Failed to malloc cache\n"); return 1; }
    cache[1]=s = malloc(99);
    memset(s,48,99);
    *s=49;
    s[1]=0;
    for (i=0;++i<10001;) {
        n=i;
        for(shift=0;n%10<1;++shift)n/=10;
        for(;n%2<1;++shift)n/=2;
        for(;n%5<1;++shift)n/=5;

        d = calloc(n,1);
        if (!d) { printf("Failed to malloc d\n"); return 1; }

        ks = calloc(n,sizeof(int));
        if (!ks) { printf("Failed to malloc ks\n"); return 1; }

        res = calloc(99,sizeof(int));
        if (!res) { printf("Failed to malloc res\n"); return 1; }

        _kb = 2;
        d[1] = 1;
        *ks = res[1] = km = 1;
        nksi = ks + 1;

        for(;!cache[n];++_kb) {
            res[_kb] = km = km*10%n;
            ksi = nksi;
            for (ii = ks; ii < ksi; ii++) {
                key = *ii;
                m = (km + key) % n;
                if (d[m] < 1) {
                    *nksi++ = m;
                    if (m < 1) {
                        cache[n] = s = malloc(99);
                        if (!s) { printf("Failed to malloc s\n"); return 1; }
                        memset(s,48,99);
                        for(key=_kb;key;key = d[m = (m + n - res[key]) % n])s[_kb-key]++;
                        s[_kb]=0;
                        ii = ksi; // break
                    }
                    d[m] = _kb;
                }
            }
        }

        free(d);
        free(ks);
        free(res);

        // Add shift * '0'
        s=cache[n];
        key=strlen(s);
        s[key]=48;
        s[key+shift]=0;

        // convert to big integer, divide, print
        mpz_init_set_str(B,s,10);
        mpz_init_set_si(I,i);
        mpz_init(Q);
        mpz_divexact(Q,B,I);
        d = mpz_get_str(0,10,Q);
        if (!s) { printf("Failed to malloc quotient\n"); return 1; }
        printf("%s\n", d);
        free(d);

        // Remove shift * '0'
        s[key+shift]=48;
        s[key]=0;
    }
    return 0;
}

2

C + GMP, 669

นี่มันเร็วมากสำหรับตัวเลขตัวเล็ก มันเริ่มที่จะทำให้หายใจไม่ออกเมื่อผลลัพธ์มีมากกว่า 64 หลัก

#include<gmp.h>
#define B(x)(int)((x*(long)k)%n);
int*M,*H,P[99],n,x,p,q=2,e=1,k=10,y,f,z;char*E,C[99];int b(int k,int t){int
j=E[k],a=1<<(j-2);if(j<2){C[t]=49;return 1;}x=(int)((k+n-P[j]*(long)H[k]%n)%n);if(x)b(x,t);return a+b(H[k],t-a);}int
main(){scanf("%d",&n);E=calloc(n+1,1);M=calloc(n+1,4);H=malloc(n*4);M[1]=E[1%n]=P[1]=1;while(!E[0]){P[++e]=k;p=q;for(x=0;++x<p;){y=B(M[x])if(E[n-y]){E[0]=e;H[0]=M[x];break;}}if(!E[x=0])while(++x<p){y=B(M[x])for(z=0;z<p;++z){f=y+M[z];if(f>=n)f-=n;if(!E[f]){E[f]=e;H[f]=M[x];M[q++]=f;}}}k=B(k)}memset(C,48,98);C[99]=0;x=b(0,97);mpz_t
m,r;mpz_init(r);mpz_init_set_str(m,C+98-x,10);mpz_fdiv_q_ui(r,m,n);puts(mpz_get_str(C,10,r));}

เวอร์ชันที่ลูปถึง 10,000 (671 ไบต์):

#include<gmp.h>
#define B(x)(int)((x*(long)k)%n);
#define N 10001
int M[N],H[N],P[99],n=0,x,p,q,e,k,y,f,z;char E[N],C[99];int b(int k,int t){int
j=E[k],a=1<<(j-2);if(j<2){C[t]=49;return 1;}x=(int)((k+n-P[j]*(long)H[k]%n)%n);if(x)b(x,t);return a+b(H[k],t-a);}int
main(){while(++n<N){memset(E,M[0]=0,n);M[1]=E[1%n]=P[1]=e=1;q=2;k=10;while(!E[0]){P[++e]=k;p=q;for(x=0;++x<p;){y=B(M[x])if(E[n-y]){E[0]=e;H[0]=M[x];break;}}if(!E[x=0])while(++x<p){y=B(M[x])for(z=0;z<p;++z){f=y+M[z];if(f>=n)f-=n;if(!E[f]){E[f]=e;H[f]=M[x];M[q++]=f;}}}k=B(k)}memset(C,48,98);C[99]=0;x=b(0,97);mpz_t
m,r;mpz_init(r);mpz_init_set_str(m,C+98-x,10);mpz_fdiv_q_ui(r,m,n);puts(mpz_get_str(C,10,r));}}

ต่อไปนี้เป็นคำสั่งสำหรับการทดสอบรหัสของฉันเช่นเดียวกับคู่แข่งของฉันและผลลัพธ์บนแล็ปท็อปของฉัน:

ls -l *.c*       
-rw-r--r-- 1 aditsu aditsu  669 Oct 27 15:01 mult-aditsu-single.c
-rw-r--r-- 1 aditsu aditsu  671 Oct 27 15:01 mult-aditsu.c
-rw-r--r-- 1 aditsu aditsu 3546 Oct 27 15:01 mult-anatoly.c
-rw-r--r-- 1 aditsu aditsu 6175 Oct 27 15:01 mult-anders.cpp
-rw-r--r-- 1 aditsu aditsu  621 Oct 27 15:01 mult-peter-single.c
-rw-r--r-- 1 aditsu aditsu  751 Oct 27 15:01 mult-peter.c

gcc -w -march=native -O3 mult-aditsu-single.c -lgmp -o mult-aditsu-single
gcc -w -march=native -O3 mult-aditsu.c -lgmp -o mult-aditsu
gcc -w -march=native -O3 mult-peter-single.c -lgmp -o mult-peter-single
gcc -w -march=native -O3 mult-peter.c -lgmp -o mult-peter
gcc -w -march=native -O3 --std=c99 mult-anatoly.c -o mult-anatoly
g++ --std=c++11 -march=native -O3 mult-anders.cpp -o mult-anders

for i in {1..5}; do time ./mult-anders mult-anders.txt; done
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.344 total
./mult-anders mult-anders.txt  0.36s user 0.00s system 99% cpu 0.358 total
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.346 total
./mult-anders mult-anders.txt  0.35s user 0.00s system 99% cpu 0.347 total
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.344 total

for i in {1..5}; do ./mult-anatoly mult-anatoly.txt; done
Time: 0.254416
Time: 0.253555
Time: 0.245734
Time: 0.243129
Time: 0.243345

for i in {1..5}; do time ./mult-peter > mult-peter.txt; done
./mult-peter > mult-peter.txt  0.14s user 0.00s system 99% cpu 0.137 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 97% cpu 0.153 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 99% cpu 0.149 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 99% cpu 0.150 total
./mult-peter > mult-peter.txt  0.14s user 0.00s system 99% cpu 0.138 total

for i in {1..5}; do time ./mult-aditsu > mult-aditsu.txt; done
./mult-aditsu > mult-aditsu.txt  0.06s user 0.00s system 95% cpu 0.058 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 97% cpu 0.055 total
./mult-aditsu > mult-aditsu.txt  0.06s user 0.00s system 99% cpu 0.056 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 99% cpu 0.054 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 98% cpu 0.055 total

md5sum *.txt
6eef8511d3bc5769b5d9218be2e00028  mult-aditsu.txt
6eef8511d3bc5769b5d9218be2e00028  mult-anatoly.txt
6eef8511d3bc5769b5d9218be2e00028  mult-anders.txt
6eef8511d3bc5769b5d9218be2e00028  mult-peter.txt

คำตอบที่สมควรได้รับจากความโปรดปราน ผมให้ความสนใจโดยเฉพาะอย่างยิ่งในปัญหานี้ (และวิธีการแก้ปัญหาของคุณเริ่มต้น) เพราะมันเป็นกรณีพิเศษของปัญหาเซตรวมซึ่งเป็นที่รู้จักกัน NP-ฉบับสมบูรณ์ (ได้รับรายชื่อของสารตกค้างของที่10ⁱ mod nหาเซตที่เก่าแก่ที่สุด ซึ่งผลรวมถึงn )
primo

@primo ขอบคุณ :) วิธีการของฉันที่นี่แตกต่างกัน - ฉันเพิ่มจำนวนหลักในแต่ละขั้นตอนมากกว่าการเพิ่มและฉันตรวจสอบก่อน (อย่างรวดเร็ว) หากตัวเลขใหม่ใด ๆ จะเป็นทางออกก่อนที่จะคำนวณจริง ๆ พวกเขา และฉันแน่ใจว่ายังมีห้องสำหรับเล่นกอล์ฟอยู่
aditsu

น่าสนใจ เมื่อฉันพยายามเพิ่มจำนวนของตัวเลขในแต่ละขั้นตอนมันจะช้าลง บางทีการตรวจสอบล่วงหน้าสำหรับโซลูชันอาจแตกต่างกันมาก
Peter Taylor

@ PeterTaylor เป็นไปได้ .. ดูเหมือนว่าคุณกำลังเรียก calloc ในลูปด้วยซึ่งอาจทำให้ช้าลง อย่างไรก็ตามฉันต้องการเพิ่มรหัสเวอร์ชันที่ไม่ดีเมื่อฉันหาเวลาและฉันก็มีความคิดว่าจะทำให้เร็วขึ้นสำหรับหมายเลขที่ใหญ่ขึ้น / น่ารังเกียจขึ้นได้อย่างไร
aditsu

2

T-SQL, 164 156 155 154 159 ไบต์

(-1 ไบต์ขอบคุณ Jonathan!)

(มากกว่า -1 เพราะเหตุใดฉันจึงมีช่องว่างต่อท้ายบนบรรทัด SMH)

(+5 ตระหนักว่าการตีกอล์ฟของฉันเป็นเรื่องยาก)

create function b(@ int)
returns int
as begin
declare @b varchar(max)='',@i int=@
while @>0SELECT @b=cast(@%2 as varchar)+@b,@/=2
return cast(@b as int)/@i
end

ฉันไม่รู้ว่าทำไมฉันถึงกลับมาที่คำถามเหล่านี้ซึ่งฉันควรจะแปลงเป็น Binary ... T-SQL ไม่รู้ว่าจะทำอย่างไร

ในกรณีใด ๆ นี่เป็นSQLFiddle

ยกเลิกแข็งแรงเล่นกอล์ฟ:

create function binarySquare(@id int)
returns int 
as BEGIN

สิ่งนี้ส่วนใหญ่จะต้องเขียนฟังก์ชันใน T-SQL เท่าที่ฉันทราบ

    declare @bin nvarchar(max) = ''

สร้างสตริงว่างที่เราจะเก็บเป็นเลขฐานสองของเรา

    declare @id2 int = @id

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

    while @id>0
      BEGIN
        SET @bin = cast(@id%2 as varchar(1)) + @bin

ดังนั้นเราจึงนำอินพุตดั้งเดิมของเราดัดแปลงด้วย 2 เพื่อหาส่วนที่เหลือและนั่นจะเป็นหลักที่เล็กที่สุดของเรา ตัวอย่างเช่น 5% 2 = 1

        SET @id = @id/2

จากนั้นเราก็นำหมายเลขของเรามาหารครึ่ง เพราะมันเป็นintประเภทมันจะปัดเศษลงเป็นจำนวนเต็มที่ใกล้ที่สุดดังนั้น 5/2 = 2 END เราจึงวนรอบนี้จนกว่าค่าจะเป็น 0 ดังนั้นเราจะได้ 5% 2 = 1 5/2 = 2 2 % 2 = 0 2/2 = 1 1% 2 = 1 1/2 = 0 ซึ่งให้ค่าสตริงไบนารีของเราที่ 101

    declare @binNum int = (SELECT cast(@bin as int))

เราใช้สตริงไบนารี่ของเราแล้วแปลงกลับมาเป็นสตริงintอีกครั้ง

    return @binNum/@id2

เราส่งคืนสตริงไบนารีของเราintหารด้วยค่าดั้งเดิมของเราตามที่มาของคำถาม

END

พื้นที่@>0 SELECTไม่สามารถข้ามได้หรือไม่?
Jonathan Frech

รับได้สวย! ฉันไม่สามารถจำได้ว่าช่องว่างใดที่ไม่สามารถ ...
phroureo

เวลาส่วนใหญ่คุณสามารถเว้นช่องว่างระหว่างตัวอักษรและตัวแปร / คำหลักเนื่องจากไม่สามารถขึ้นต้นด้วยตัวเลข
Jonathan Frech

1

ทับทิมขนาด 46 ไบต์

ฉันควรกำจัด while loop ด้วยลูปทางเลือกจริงๆ

n,k=gets,0;$_="#{n.to_i*k+=1}"while/[^01]/;p k

แก้ไข: ขอบคุณ @manatwork สำหรับการลบ 1 ไบต์!

แก้ไข 2: ขอบคุณ @histocraft สำหรับบ้า 9 ไบต์!

แก้ไข: ขอบคุณ @manatwork อีกครั้งสำหรับการตัดออก 7 ไบต์!


z!=z[/[01]+/]สั้นกว่า z[/[^01]/]ยิ่งสั้น
จัดการ

@ การจัดการขอบคุณ! น้อยกว่า 1 ไบต์!
Peter Lenkefi

2
บรรทัดเดียวในขณะที่ลูปมีแนวโน้มที่จะสั้นที่สุด:z="#{n.to_i*k+=1}"while z[/[^01]/]
ฮิสโทแค

@histocrat นั่นคือ 9 ไบต์! และฉันก็ไม่รู้ด้วยซ้ำว่าทับทิมมีความสามารถนี้ ขอบคุณ!
Peter Lenkefi

ที่น่าสนใจว่าคุณไม่ได้เปลี่ยนการทดสอบเป็นชุดอักขระที่ถูกทอดทิ้งและหลังจากนั้นไม่แนะนำให้ใช้ครั้งที่ 2 ด้วยเหตุผลใด
จัดการ

1

สกาลา, 114 ไบต์

val i=scala.io.StdIn.readInt;Stream.from(1).foreach{x=>if((i*x+"").map{_.asDigit}.max<2){print(x);System.exit(0)}}

เวอร์ชันที่อ่านได้

val i=scala.io.StdIn.readInt
Stream.from(1).foreach{x => 
    if((i*x+"").map{_.asDigit}.max<2) {
        print(x)
        System.exit(0)
    }
}

1

gawk4 กำลังดุร้าย, 28 + 2 = 30 ไบต์

{while(++n*$0~/[2-9]/);}$0=n

จะต้องมีการเรียกพร้อมกับ-Mตัวเลือกสำหรับการใช้ตัวเลขขนาดใหญ่ แน่นอนว่านี่เป็นเรื่องน่าขันที่ช้าโดยใช้ตัวเลขจำนวนมากทำให้มันช้าลงมากขึ้น แต่ในทางทฤษฎีแล้วอินพุตไม่ จำกัด และการใช้ RAM ก็น้อยมาก

ตัวอย่างการใช้งาน (ถ้าคุณมีเวลาให้เสียเปล่า;))

echo 27 | awk -M '{while(++n*$0~/[2-9]/);}$0=n'

ปรับให้เหมาะสม gawk4, 69 + 2 = 71 ไบต์

{for(;!a[0];NR*=10)for(i in a)a[j=(s=a[i]+NR)%$0]?0:a[j]=s}$0=a[0]/$0

นี่มันเป็นโคลนของคำตอบของ aditsu หลังจากดูคำถามนี้ฉันยังคงหาวิธีเขียนโค้ดส่วนย่อยของผลรวมเมื่อฉันไม่สามารถต้านทานการดูคำตอบอื่น ๆ ได้ที่นี่

ในองค์ประกอบอาร์เรย์ awk มีพฤติกรรม (แปลก?) ที่ถ้าคุณเปรียบเทียบองค์ประกอบที่ไม่มีอยู่กับบางสิ่งบางอย่างมันถูกเตรียมใช้งานเป็นว่างเปล่าก่อนที่จะถูกเปรียบเทียบ (ฉันจะยอมรับว่าฉันไม่แน่ใจเกี่ยวกับสิ่งที่เกิดขึ้นที่นั่น) ดังนั้นหลังจากการตรวจสอบห่วงเริ่มต้นได้โดยไม่ต้องเริ่มต้นที่จะเป็น aditsu ได้!a[0]for(i in a)a[$0]0

แน่นอนว่าต้องใช้-Mตัวเลือกสำหรับสิ่งนี้ด้วย

แม้ว่ามันจะค่อนข้างเร็ว แต่ก็ยังช้ากว่า Python อย่างมาก สำหรับ79992เรื่องนี้ใช้เวลาประมาณ 14 วินาทีใน Core2Duo 2GHz ของฉัน และฉันจะไม่บอกว่ามันใช้งานได้กับอินพุตสูงสุด 2 ^ 31 เพราะในกรณีที่เลวร้ายที่สุดมันต้องสร้างอาร์เรย์จำนวนมาก (gawk4 ใช้ GMP สำหรับสิ่งนี้) ซึ่งมีขนาดของหมายเลขอินพุต ในฐานะที่เป็น 'โบนัส' อาร์เรย์ขนาดใหญ่ช้ามากในเวลาอันรวดเร็ว ...


1

Dyalog APL , 25

นี่เป็นการกำหนดโปรแกรมที่เหมาะสม "P" (ไม่ใช่แค่ฟังก์ชันที่ไม่มีชื่อ):

P←2∘{0::⍵∇⍨1+⍺⋄⍺⊣~⍎¨⍕⍺×⍵}

2∘เริ่มต้นด้วย 2 เป็นอาร์กิวเมนต์ด้านซ้าย
0::หากมีข้อผิดพลาดใด ๆ ...
⍵∇⍨1+⍺เรียกตัวเองด้วยอาร์กิวเมนต์ซ้ายที่เพิ่มขึ้น
⍺×⍵คูณซ้ายและอาร์กิวเมนต์ที่เหมาะสม
ทำให้เป็นสตริง
⍎¨ทำให้ตัวละครแต่ละตัวเป็นจำนวน
~ความพยายามที่ไม่ตรรกะตรรกะ (ถ้ามันล้มเหลวไปที่ อื่น ... )
⍺⊣ส่งคืนอาร์กิวเมนต์ซ้ายปัจจุบัน

      P 2
50
      P 21
481
      P¨⍳8    ⍝ 1 through 8
10 5 37 25 2 185 143 125
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.