นับถอยหลังจาก "ไม่มีที่สิ้นสุด"


47

ดูเหมือนว่าเป็นงานที่เป็นไปไม่ได้ใช่มั้ย จริงๆแล้วมันไม่ได้ยากขนาดนั้น ถ้าเราเขียนคำว่าInfinityเป็นรหัส ASCII ไบนารี 8 บิตเราจะได้รับ:

01001001 01101110 01100110 01101001 01101110 01101001 01110100 01111001

5291279215216915577นี้สามารถตัดแบ่งและแปลงเป็นค่าทศนิยม ตอนนี้เป็นจำนวนที่เราสามารถทำงานร่วมกับ ...

วิธีที่คุณจะนับถอยหลังคือ:

  1. ส่งออกสตริงเดิมเป็นตัวเลขทศนิยม (ตามที่แสดงด้านบน)
  2. ลบ 0s นำหน้าในการนำเสนอแบบไบนารี (ถ้ามี)
  3. สลับบิตในการแทนเลขฐานสอง (1-> 0, 0-> 1)
  4. เอาท์พุทตัวเลขเป็นทศนิยม
  5. ทำซ้ำขั้นตอนที่ 2-4 จนกระทั่งถึง 0

ท้าทาย:

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

กรณีทดสอบ:

ฉันคิดว่าความท้าทายจะค่อนข้างง่ายที่จะเข้าใจแม้ว่าจะเป็นเพียงกรณีทดสอบเดียว ฉันจะใช้InfแทนInfinityเพื่อให้มันค่อนข้างสั้น

Inf
4812390  (10010010110111001100110)
3576217  ( 1101101001000110011001)
618086   (   10010110111001100110)
430489   (    1101001000110011001)
93798    (      10110111001100110)
37273    (       1001000110011001)
28262    (        110111001100110)
4505     (          1000110011001)
3686     (           111001100110)
409      (              110011001)
102      (                1100110)
25       (                  11001)
6        (                    110)
1        (                      1)
0        (                      0)

Input: Inf 
Output:
4812390, 3576217, 618086, 430489, 93798, 37273, 28262, 4505, 3686, 409, 102, 25, 6, 1, 0 

Input: Infinity
Output:
5291279215216915577, 3932092821637860230, 679593196789527673, 473328307817319302, 103132444486104185, 40982743589751686, 31074850448176249, 4953946570787718, 4053252683953273, 450346943417222, 112603010004089, 28134478351238, 7049893737593, 1746199284614, 452823970937, 96931842950, 40507110521, 28212366214, 6147372153, 2442562438, 1852404857, 295078790, 241792121, 26643334, 6911097, 1477510, 619641, 428934, 95353, 35718, 29817, 2950, 1145, 902, 121, 6, 1, 0

รหัสของคุณต้องรองรับสตริงที่สามารถแสดงเป็นเลขฐานสองได้จนถึงขีด จำกัด ของภาษาของคุณ สตริงทั้งหมดจะมีเฉพาะอักขระ ASCII ที่พิมพ์ได้จาก 32-126 (เว้นวรรคจนถึงตัวหนอน)


ลีดเดอร์บอร์ด


31
Chuck Norris , 8 bytes:Inf:-1:0
Luis Mendo

2
@LuisMendo Chuck Norris 'NARS-APL:∞..0
2559

5
@LuisMendo คุณแน่ใจหรือว่าคุณไม่ได้หมายถึงJon Skeet ?
mbomb007

คำตอบ:


12

เยลลี่ , 15 10 ไบต์

-5 ไบต์ขอบคุณ @Dennis (แปลงโดยตรงจากฐาน 256 หลังจากการร่ายลำดับ)

Oḅ⁹µBCḄµÐĿ

TryItOnline!

อย่างไร?

Oḅ⁹µBCḄµÐĿ - Main link: s                     e.g. "Inf"
O          - cast to ordinals                 e.g. [73,110,102]
 ḅ⁹        - convert from base 256 to integer e.g. 4812390
   µ   µ   - monadic chain separations
    B      -     convert to binary
     C     -     complement
      Ḅ    -     convert to integer
        ÐĿ - loop until no longer unique and collect results 

1
Oḅ⁹ส่วนแรกเป็นเพียง
เดนนิส

โอ้ฉันจะพลาดได้อย่างไร!
Jonathan Allan

11

Python 2, 89 82 77 76 75 ไบต์

n=0
for c in input():n=n<<8|ord(c)
while 1:print n;n^=2**n.bit_length()-n/n

ทดสอบบนIdeone

มันทำงานอย่างไร

หลังจากเริ่มต้นnเป็น0บรรทัดที่สองจะทำการแปลงแบบสตริงเป็นจำนวนเต็มที่ระบุในความท้าทายดังต่อไปนี้

ในแต่ละขั้นตอนnจะเลื่อน8หน่วยไปทางซ้ายแล้วค่าที่เหมาะสมหรือ -ed กับจุดรหัสของตัวละครต่อไปค สำหรับอินพุตInfจะดำเนินการดังนี้

n                                  0
a = n<<8                           0
b = 'I'                      1001001
n = a ^ b                    1001001
a = n<<8             100100100000000
b = 'n'                      1101110
n = a ^ b            100100101101110
a = n<<8     10010010110111000000000
b = 'f'                      1100110
n = a ^ b    10010010110111001100110

ตอนนี้เราพร้อมที่จะสร้างผลลัพธ์แล้ว ในการกลับค่าบิตของnเราดำเนินการดังนี้

อันดับแรกเราคำนวณบิตในการแทนเลขฐานสองของnโดยไม่มีเลขศูนย์นำหน้า มาเรียกผลลัพธ์kกัน จากนั้นเราคำนวณk kอำนาจของ2ซึ่งมีk + 1ตัวเลขไบนารี: เดี่ยว1ตามด้วยk 0 's เราลบ1จากผลลัพธ์โดยให้ผลเป็นจำนวนที่ประกอบด้วยkอันซึ่งเราก็ XOR กับnเพื่อกลับด้านบิตของมัน สำหรับอินพุตinfสิ่งนี้จะเป็นดังนี้

n         4812390   10010010110111001100110
k              23 
t = 2**k           100000000000000000000000
t -= 1              11111111111111111111111
n ^= t    3576217    1101101001000110011001
k              22
t = 2**k            10000000000000000000000
t -= 1               1111111111111111111111
n ^= t     618086      10010110111001100110
.
.
.
n               6                       110
k               3
t = 2**k                               1000
t -= 1                                  111
n ^= t          1                         1
k               1
t = 2**k                                 10
t -= 1                                    1
n ^= t          0                         0

ในอุปสรรค์เพิ่มเติมในการใช้งานคือเราต้องพิมพ์nก่อนขั้นตอนแรกหลังจากขั้นตอนสุดท้ายและในทุกขั้นตอนในระหว่าง Python ไม่มีลูปทำในขณะที่คำสั่งพิมพ์เดียวมีราคา8ไบต์ดังนั้นเราจะทำสิ่งต่อไปนี้แทน

ในการดำเนินการตามขั้นตอนที่ตรงไปตรงมาคือ:

while n:print n;n^=2**n.bit_length()-1
print n

เราแทนที่วงด้วยหนึ่งอนันต์ ( while 1) และคำนวณในวงเป็น1 n/nนี่คือในขณะที่เทียบเท่าn> 0

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


2
ฉันชอบ-n/nเคล็ดลับนั้น:-)
ETHproductions

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

@StewieGriffin n / n คือ 1 จนกระทั่ง n คือ 0 จากนั้นจะเกิดข้อผิดพลาดและทำให้โปรแกรมหยุดทำงาน
jazzpi

มีข้อความแสดงข้อผิดพลาด (ฉันหวังว่า)
Stewie Griffin

1
@StewieGriffin แน่นอน Python เจ็บปวดอย่างมากเมื่อพูดถึงการรายงานข้อผิดพลาด ฉันได้แก้ไขคำตอบเพื่อรวมคำอธิบายแล้ว
Dennis

8

JavaScript, 82 ไบต์

บันทึกเป็นไบต์ด้วย @Arnuald

for(y of prompt(n=0))n=n<<8|y.charCodeAt()
for(;alert(n)|n;)for(i=1;i<=n;i*=2)n^=i

หนึ่งในไม่กี่ครั้งเมื่อโปรแกรมเต็มรูปแบบมีประสิทธิภาพสูงกว่าฟังก์ชั่น (และ ES6 ไม่ทำได้ดีกว่า ES5) ...


ด้านบนรองรับคำได้มากถึง 4 ตัวอักษร เพิ่ม 4 ไบต์เพื่อรองรับคำสูงสุด 6 ตัวอักษร:

for(y of prompt(n=0))n=n*256+y.charCodeAt()
for(;alert(n)|n;n=i-n-1)for(i=1;i<=n;)i*=2


g=a=>a[0]?a.pop().charCodeAt()+g(a)*256:0(-1)
ติตัส

@Titus ขอบคุณ! ไม่แน่ใจว่าทำไมฉันไม่คิดอย่างนั้น
ETHproductions

n<<8|y.charCodeAt()ควรบันทึกไบต์ for(;n;)for(i=!alert(n);i<=n;i*=2)n^=iจะบันทึกไบต์อื่น แต่คุณจะไม่แสดง0ซึ่งอาจจำเป็นต้องใช้
Arnauld

@ Arnauld ขอบคุณ ฉันคิดเกี่ยวกับการทำn<<8ก่อนหน้านี้ แต่ตัดสินใจว่าจะไม่ทำงานเพราะจะทำให้ n มีมากกว่า 31 บิต ฉันคิดว่ามันไม่สำคัญว่าตอนนี้ฉันแยกแล้วระหว่างรุ่น 31 บิตและรุ่น 53 บิต ... และน่าเศร้าที่ฉันไม่คิดว่าฉันสามารถบันทึกสิ่งใดในการแจ้งเตือนได้ในขณะที่แจ้งเตือนทั้งคู่ก่อน ซ้ำและครั้งสุดท้าย
ETHproductions

7

จริงแล้ว 14 ไบต์

2@├¿W■├♂≈♂Y2@¿

ลองออนไลน์!

คำอธิบาย:

2@├¿W■├♂≈♂Y2@¿
 @├             encode input in binary
2  ¿            convert from binary to decimal
    W           while the number is not 0:
     ■            print the number without popping
      ├           convert number to binary
       ♂≈         convert each character to an int
         ♂Y       boolean negate each int
           2@¿    convert from binary to decimal

6

05AB1E , 18 ไบต์

ใช้การเข้ารหัสCP-1252

Çžz+b€¦J[CÐ,_#bS_J

ลองออนไลน์!

คำอธิบาย

Ç                     # convert string to list of ascii codes
 žz+                  # add 256 to each
    b                 # convert to binary
     €¦               # remove the first digit of each list of digits
       J              # join
        [             # start loop
         C            # convert to decimal
          Ð           # triplicate
           ,          # print 1 copy
            _#        # if the 2nd copy is 0, break loop
              b       # convert 3rd copy to binary
               S      # split to list
                _     # negate each in list
                 J    # join


4

Mathematica, 99 ไบต์

a=FromDigits;b=IntegerDigits;NestWhileList[a[1-#~b~2,2]&,a[Join@@b[ToCharacterCode@#,2,8],2],#>0&]&

ฟังก์ชั่นไม่ระบุชื่อ รับสตริงเป็นอินพุตและส่งคืนรายการตัวเลขเป็นเอาต์พุต


4

Haskell, 109 123 118 102 97 ไบต์

ขอบคุณ @nimi สำหรับการบันทึก 5 ไบต์!

c 0=0
c n=1-mod n 2+2*c(div n 2)
(++[0]).fst.span(>0).iterate c.foldl((+).(256*))0.map fromEnum

การใช้งาน: (++[0]).fst.span(>0).iterate c.foldl((+).(256*))0.map fromEnum $ "Infinity"

รับประกันการทำงานกับตัวเลขมากถึง 29 บิตโดยภาษาโดยปกติแล้วจะทำงานได้มากถึง 63 บิตในระบบ 64 บิต ใช้map(fromIntegral.fromEnum)แทน (+14 ไบต์) เพื่อรองรับตัวเลขขนาดใหญ่โดยพลการ

[0..255]ธิการสำหรับช่วง Unicode พลิกบิตซ้ำ ๆ


1
คุณสามารถแทนที่ด้วยtakeWhile(>0) fst.span(>0)ถ้าคุณไป pointfree คุณสามารถวางชื่อเพื่อฟังก์ชั่นหลักของคุณคือf (++[0]) ... map fromEnum
nimi

ขอบคุณ @nimi fทิ้งชื่อแก้ปัญหาอนุมานชนิดที่ผมมีกับ
Angs

ทำไมfromIntegral? จากความท้าทาย: "ต้องรองรับ ... มากถึง 63 บิต ... หรือขีด จำกัด ของภาษาของคุณ" ดังนั้นIntควรจะดี หากคุณต้องการที่จะให้มันย้ายไปmapคือรุ่นเก่าของคุณและfoldl1 map(fromIntegral.fromEnum)
nimi

@nimi OP โพสต์ความคิดเห็นที่นี่ (ตั้งแต่ถูกลบ) ถามว่ารองรับ 63 บิตได้ไหม เอาชนะฉัน
Angs

4

PHP, 132 126 123 120 108 107 ไบต์

foreach(unpack("C*",$argv[1])as$i)$n=$n*256+$i;for(print$n;$n;)echo _.$n=bindec(strtr(decbin($n),"01",10));
  • การพิมพ์ 0 หลังจากวนแทนค่าเริ่มต้นก่อนวนซ้ำจะบันทึก 6 ไบต์
  • unpackแทนที่จะstr_splitแสดงผลord()ล้าสมัย -> -3 ไบต์
  • ขีดเส้นใต้_เป็นตัวแยกบันทึก 3
  • bindecแทนltrimการลบศูนย์นำ: -12
  • echoin body body จะช่วยประหยัด 1 ไบต์ไปprintในหัว loop

ไม่สามารถ$n=$n*256+$i;for(print$n;$n;)จะเขียนเป็นfor(print$n=$n*256+$i;$n;)? เนื่องจากส่วนที่ได้รับมอบหมายจะดำเนินการหนึ่งครั้งจึงควรใช้งานได้ และแทนที่จะเป็น echo _.$n=[...]คุณควรใช้echo _,$n=[...]แทน มันจะไม่บันทึกไบต์ใด ๆ แต่จะเพิ่มความเร็วโค้ดเป็นบิตจิ๋วจิ๋วจิ๋วเล็กน้อยและจะแยกข้อความสั่ง นั่นหมายความว่าตัวอย่างเช่นสามารถเขียนแทนecho _,$a?5:6; echo _.($a?5:6);สิ่งนี้อาจมีประโยชน์ในอนาคต
Ismael Miguel

@IsmaelMiguel ส่วนที่ได้รับมอบหมายเป็นวง ฉันใช้เครื่องหมายจุลภาคเมื่อไม่ต้องการจุด มันเป็นส่วนที่เหลือจากprintในกรณีนี้ ไม่ควรแก้ไขเพียงอย่างเดียว แต่ขอบคุณ.
ติตัส

โอ้ใช่แล้ว ... มันอยู่ในforeach(unpack("C*",$argv[1])as$i)... โง่ฉัน ... และใช่การเปลี่ยนช่วงเวลาเพื่อให้เครื่องหมายจุลภาคมีผลเหมือนกันไม่คุ้มค่ากับปัญหา
Ismael Miguel

4

Perl, 65 ไบต์

53 รหัสไบต์ + -Mbigint -p12

ขอบคุณ @ Dada ที่ช่วยฉันประหยัด 13 ไบต์!

$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0

แนวทางที่ตรงไปตรงมาค่อนข้างแตกต่างจากที่กล่าวมาส่วนใหญ่เท่านั้นคือจำนวนที่จัดเก็บเป็นไบนารีและพิมพ์ออกมาเป็นทศนิยม ฉันแน่ใจว่าสามารถปรับปรุงได้อาจมีการจัดเก็บรายละเอียดในอาร์เรย์ -Mbigintค่อนข้างไม่สะดวก แต่จำเป็น

การใช้

echo -n 'Inf' | perl -Mbigint -pE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'
4812390
3576217
618086
430489
93798
37273
28262
4505
3686
409
102
25
6
1
0
echo -n 'Infinity' | perl -Mbigint -pE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'
5291279215216915577
3932092821637860230
679593196789527673
473328307817319302
103132444486104185
40982743589751686
31074850448176249
4953946570787718
4053252683953273
450346943417222
112603010004089
28134478351238
7049893737593
1746199284614
452823970937
96931842950
40507110521
28212366214
6147372153
2442562438
1852404857
295078790
241792121
26643334
6911097
1477510
619641
428934
95353
35718
29817
2950
1145
902
121
6
1
0

1
แกะเพื่อนของฉันแกะออก! perl -Mbigint -lpE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'(ฉันไม่รู้ว่าจะใช้unpack แบบปกติได้อย่างไรฉันเพิ่งโชคดีเมื่อ googling วิธีแปลงสตริงเป็นไบนารี ;-))
Dada

Ahhh ฉันมักจะลืมเกี่ยวกับunpackไวยากรณ์ที่พัดใจของฉัน! ฉันจะอัปเดตขอบคุณ!
Dom Hastings

มีperlpacktutที่จะช่วยได้ ... ฉันอ่าน 10 บรรทัดแรกหลายสิบครั้ง แต่ฉันควรใช้เวลาอ่านที่เหลือจริงๆ!
Dada

@ ดาด้าฉันแน่ใจว่าฉันได้อ่านมันหลายครั้งมันไม่เคยอยู่ ... ขอบคุณอีกครั้ง -13 ไม่มีความสำเร็จขนาดเล็ก! ฉันต้องเปลี่ยนไปecho -nเป็นการเปลี่ยนแปลงอื่นเท่านั้น
Dom Hastings

4

Pyth, 12 ไบต์

.usi!MjN2 2C

โปรแกรมที่รับอินพุตของสตริงที่ยกมาและพิมพ์ผลลัพธ์เป็นรายการจำนวนเต็ม

ตรวจสอบกรณีทดสอบทั้งหมด

มันทำงานอย่างไร

.usi!MjN2 2C  Program. Input: Q
           C  Convert Q to an integer by code-points using base-256 (implicit input)
.u            Apply the following function A(N) until a repeat occurs, storing the results
              in a list:
      jN2       Convert to binary as a list
    !M          Map negation over the above
   i      2     Convert from binary to integer
  s             Integer (Converts final False to 0)
              Implicitly print

3

Python 3, 99 95 ไบต์

x=int.from_bytes(bytes(input(),'utf-8'),'big')
while x:print(x);x^=2**x.bit_length()-1
print(0)

แนวคิดหลักคือการแปลงสตริงเป็นไบต์เป็นจำนวน การวนซ้ำแต่ละครั้งจะพิมพ์เอาต์พุตและ XOR ด้วยทั้งหมด 1 วินาทีเพื่อไปยังศูนย์


2**x.bit_length()-1คุณไม่จำเป็นต้องวงเล็บรอบ ลำดับการทำงานของกำลังและการลบสูงกว่า xor นอกจากนี้ที่whileสามารถอยู่ในบรรทัดเดียว
mbomb007

เขียน while loop บนหนึ่งบรรทัด (ลบ newline และย่อหน้า)
FlipTack

ลองเริ่มโปรแกรมด้วยP=printแล้วใช้P()แทนprint()
Cyoce

3

Python 2, 117 115 ไบต์

ประหยัด 2 ไบต์ขอบคุณ Cyoce

สมมติว่าอินพุตอยู่ในเครื่องหมายคำพูดเช่น "Inf"

s=input()
n=sum(ord(s[-i-1])<<i*8for i in range(len(s)))
while n:
 print n;k,m=n,1
 while k:k/=2;m*=2
 n^=m-1
print 0

mนับได้ถึงจำนวนสูงสุดดังนั้นจึงm-1เป็นหน้ากาก XOR เพื่อดำเนินการตามที่ต้องการ ส่วนที่ยาวที่สุดคือการแปลงอินพุตเป็นลำดับบิตเริ่มต้น

ตัวอย่าง:

"Inf"
4812390
3576217
618086
430489
93798
37273
28262
4505
3686
409
102
25
6
1
0

"Infinity"
5291279215216915577
3932092821637860230
679593196789527673
473328307817319302
103132444486104185
40982743589751686
31074850448176249
4953946570787718
4053252683953273
450346943417222
112603010004089
28134478351238
7049893737593
1746199284614
452823970937
96931842950
40507110521
28212366214
6147372153
2442562438
1852404857
295078790
241792121
26643334
6911097
1477510
619641
428934
95353
35718
29817
2950
1145
902
121
6
1
0

คุณสามารถแทนที่-i-1ด้วย~i
Cyoce

3

Ruby, 104 101 100 81 80 65 ไบต์

บันทึกไปแล้ว 19 ไบต์ด้วย @WayneConrad!
บันทึก 15 ไบต์ด้วย @philomory!
บันทึก 1 ไบต์ขอบคุณ @LeeW!

p n=$*[0].unpack('B*')[0].to_i(2)
p n^=2**n.bit_length-1while n>0

รับอินพุตผ่านอาร์กิวเมนต์บรรทัดคำสั่ง

แรงบันดาลใจจากคำตอบ Pythonของ @ JimmyJohnson


คุณอาจบันทึกตัวละครไม่กี่ตัวโดยแทนที่i.to_s(2).rjust 8,'0'ด้วย"%08b"%i
Wayne Conrad

นอกจากนี้ฉันคิดว่าinject(:+)สามารถถูกแทนที่ด้วยjoin
เวย์นคอนราด

@WayneConrad ขอบคุณสำหรับความช่วยเหลือ! ไม่แน่ใจว่าฉันลืมเรื่องเหล่านี้ได้อย่างไร
Cyoce

ดีใจที่ฉันช่วยได้! ขอบคุณที่สอนวิธี #bit_length ให้ฉันซึ่งฉันไม่รู้
Wayne Conrad

1
การสลับไปยังการunpackตามด้วย[0]แทนที่จะไปกับ messing gsubจะเป็นการประหยัด 11 ไบต์ สลับไป$*[0]แทนgets.chop(ใช้อาร์กิวเมนต์บรรทัดคำสั่งแทนการป้อนข้อมูลคอนโซล) จะประหยัดอีก 9 p n=$*[0].unpack('B*')[0].to_i(2)บรรทัดแรกจะกลายเป็น
ปรัชญา

3

เขาวงกต , 104 103 ไบต์

'  )25 }_';:_';_2/;{
''', 6 2 1   1   { (
 ' | / _ _   _}*2_ $
 * _ :!\ }2_\     !:
 652       @'''''''

ลองออนไลน์!

คำอธิบาย:

รูปภาพรหัสสีของรหัสต้นฉบับ

ตัวชี้การเรียนการสอนเริ่มต้นที่ตัวอักษรที่ไม่ใช่ผนังด้านซ้ายบนสุด (ผนังจะมีช่องว่างและตัวอักษรใด ๆ ยกเว้นv)

ส้ม:

การวนซ้ำนี้รับอินพุตครั้งละหนึ่งตัวอักษรเป็นรหัส ASCII เพิ่มเข้าไปในค่าปัจจุบันและคูณค่าปัจจุบัน 256

  • ' ไม่มี-op
  • ,กดรหัส ascii ของอินพุตถ่านตัวถัดไปไปที่ด้านบนของสแต็กหรือ -1 ถ้า EOF ณ จุดนี้หากได้รับอินพุตรหัสจะเลี้ยวขวา (เลื่อนลง) เนื่องจากด้านบนสุดของสแต็กนั้นมีประสิทธิภาพ มิฉะนั้นจะเลี้ยวซ้ายเพราะด้านบนสุดของกองซ้อนเป็นลบ
  • | เปิดไอเท็มสองอันดับแรกจากสแต็กและดันผลลัพธ์เป็นบิตหรือ
  • _ ดันศูนย์
  • 256แต่ละหลักเห็นปรากฏและผลักดันx x*10+digitดังนั้นสิ่งนี้จึงรวมกับการผลักศูนย์ก่อนหน้านี้ดัน 256 ถึงด้านบนสุดของสแต็ก
  • *ป๊อปอัพy, ป๊อปx, x*yการผลักดัน ณ จุดนี้เนื่องจากส่วนบนสุดของสแต็กเป็นบวกรหัสจะเลี้ยวขวาเพื่อดำเนินการต่อรอบวง

สีน้ำเงิน:

  • )เพิ่มส่วนบนสุดของสแต็ก เมื่อถึงจุดสิ้นสุดของอินพุตรหัสจะเลี้ยวซ้ายเพื่อไปที่จุดนี้โดยมี -1 บนสแต็กซึ่งจะเพิ่มขึ้นเป็นศูนย์
  • 256 การมีด้านบนของสแต็ค 0 ทำให้เราสามารถกด 256 ได้
  • /ป๊อปป๊yอปxพุชx/y(การหารจำนวนเต็ม) เนื่องจากเราคูณการป้อนข้อมูลด้วย 256 แต่ละวงเราต้องเปลี่ยนการคูณครั้งล่าสุด
  • : ทำซ้ำส่วนบนสุดของสแต็กเพื่อให้เรามีสำเนาของค่าปัจจุบันในภายหลัง
  • ! เปิดที่ด้านบนของสแต็กและพิมพ์ค่าจำนวนเต็มไปที่ STDOUT
  • \ พิมพ์บรรทัดใหม่
  • _2 ดันสองไปด้านบนสุดของสแต็ก
  • } ย้ายด้านบนของสแต็กไปที่ด้านบนของสแต็คเสริม

สีแดง:

ลูปนี้พลิกบิตของค่าปัจจุบันโดย XOR ด้วยค่าเฉพาะที่คำนวณในลูปภายใน (สีเขียว) จากนั้นจะส่งออกค่าปัจจุบันและออกจากโปรแกรมหากค่าปัจจุบันเป็นศูนย์

  • _ ผลักศูนย์ (ควบคุมการไหล)
  • ; ทิ้งส่วนบนสุดของสแต็ค (โฟลว์ควบคุม)
  • :ทำซ้ำค่าปัจจุบัน สำเนาจะใช้ในการคำนวณ XOR
  • _ ผลักศูนย์ (ควบคุมการไหล)
  • (ห่วงสีเขียว)
  • $ป๊อปอัพy, ป๊อปx, x XOR yกด
  • :! ทำซ้ำค่าปัจจุบันและพิมพ์การแทนจำนวนเต็ม
  • หากค่าปัจจุบันเป็น 0 เราจะดำเนินการตรงไปยัง@และสิ้นสุด
  • \ พิมพ์บรรทัดใหม่
  • _2} กด 2 และย้ายไปที่สแต็ค aux
  • _1 กด 1 (ควบคุมการไหล)

เขียว:

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

  • _ ผลักศูนย์ (ควบคุมการไหล)
  • ; ละทิ้งค่าปัจจุบันซึ่งใช้เพื่อบังคับใช้โฟลว์ควบคุมเท่านั้น
  • _2 กด 2 เพื่อลดค่าปัจจุบันลงครึ่งหนึ่ง
  • / หาร
  • { ย้ายด้านบนของสแต็ค aux ไปที่ด้านบนของสแต็กหลัก
  • _2* เพิ่มด้านบนสุดของสแต็กเป็นสองเท่า
  • } ย้ายด้านบนของสแต็กหลักกลับไปที่สแต็ค aux
  • _1 กดหนึ่งเพื่อควบคุมการไหล
  • หลังจากออกจากลูป:
  • ; ละทิ้งซ้ายไปเป็นศูนย์จากการคำนวณ XOR
  • { ย้าย XOR จากการคำนวณไปยังสแต็กหลัก
  • ( ลบหนึ่งจากค่า XOR

2

PowerShell v2 +, 158 ไบต์

for($a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)});$a){[convert]::ToInt64($a,2);$a=$a.TrimStart('0')-split0-replace1,0-join1}

ใช่ดังนั้นการแปลงฐานใน PowerShell เป็น sucky และเราจะทำมันสองครั้งตรงนี้

ตกลงดังนั้นนี่เป็นเพียงการforวนรอบ$a- กล่าวคือเราวนซ้ำตราบใดที่$aมีอยู่ ในที่สุดเราก็จะไปถึงสตริงที่ว่างเปล่า (ซึ่งเป็นเท็จ) ดังนั้นนั่นคือวิธีที่เราจะยุติ

การตั้งค่าของลูป, $a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)})รับอินพุต$args[0], ปลดเปลื้องมันเป็นchar-array และวนซ้ำผ่านแต่ละอักขระ เราใช้. NET [convert]::ToString(int,base)เพื่อแปลงให้เป็นสตริงไบนารี่ แต่ที่ไม่ได้รวมศูนย์ชั้นนำดังนั้นเราจึงจำเป็นต้องโยนว่าเป็นสตริง[int]และเรียกมัน .ToString()ด้วยวิธี8ศูนย์เป็นหน้ากาก จากนั้นสตริงเหล่านั้นจะถูกห่อหุ้มใน parens และ-joined $aด้วยกันแล้วบันทึกลงใน

ภายในวงเรา[convert]::ToInt64(string,base)จะแปลงเลขฐานสองเป็นตัวเลขทศนิยม สิ่งนั้นจะถูกทิ้งไว้บนไปป์ไลน์และจะถูกฟลัชเมื่อลูปรีเซ็ต (และพิมพ์โดยปริยาย) ส่วนถัดไปทำการคำนวณ - เรา.TrimStart()จะลบศูนย์นำหน้า-split0เพื่อแยกศูนย์และรับ - stringอาร์เรย์ของ1s, -replaceคนที่มีศูนย์และสุดท้าย-joinอาร์เรย์กลับมารวมกันกับ1s จากนั้นการวนซ้ำจะเริ่มขึ้นอีกครั้ง

PS C:\Tools\Scripts\golfing> .\count-down-from-infinity.ps1 'PPCG'
1347437383
800046264
273695559
263175352
5260103
3128504
1065799
1031352
17223
15544
839
184
71
56
7
0

2

CJam , 17 16 18 ไบต์

q256b0{_p2b:!2bj}j

ลองออนไลน์!

q256b   e# read printable ascii to integer
0       e# value for terminal case
{       e# recursive function
  _p    e#   print current number
  2b    e#   create binary representation with no leading zeros
  :!    e#   flip bits
  2b    e#   convert binary back to integer
  j     e#   recursive call
}j      e# end

หมายเหตุ:เวอร์ชัน 16 ไบต์เก่าไม่ทำงานอย่างถูกต้องกับสตริงว่าง:

q256b{_p2b:!2b}h

นอกจากนี้ขอขอบคุณเดนนิสที่แนะนำpว่าประหยัด 1 ไบต์ในN\การวางบรรทัดใหม่ลงในสแต็ก


_p2b:!2bบันทึกเป็นไบต์ นอกจากนี้คุณควรใช้l; rจะล้มเหลวหากอินพุตมีช่องว่าง
Dennis

@Dennis ขอบคุณ แต่ตอนนี้ทำให้ฉันกังวลว่าสตริงว่างเป็นปัญหา
Linus

ขวา. qจะทำงานอย่างถูกต้องกับสตริงว่าง
เดนนิส


1

เรติน่า, 116 ไบต์

จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1 บรรทัดที่ 5 มีไบต์ที่ไม่สามารถพิมพ์ได้ T`\x00-\xFFมัน

-2`
±
s{`±(.)
$&$1
}T`-`_o`±.
[^±]+
$.&
±

\d+
$*
+`(1+)\1
${1}0
01
1


{*(`1
01
+`10
011
^0+

)M`1
^0+

T`01`10

ลองออนไลน์

อย่าลองด้วยการป้อนข้อมูลที่มีความยาวมากกว่าสองตัวอักษร (มันหมดเวลาใช้ล่ามออนไลน์) เราต้องแปลงไบนารี่ให้เป็นเอกฐานก่อนทศนิยม : D

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

คำอธิบาย

-2`         # Convert ASCII to decimal (ord)
±
s{`±(.)
$&$1
}T`-`_o`±.
[^±]+
$.&
±

\d+         # Decimal to binary
$*
+`(1+)\1
${1}0
01
1


{*(`1       # Loop; Loop print and undo; Convert binary to unary
01
+`10
011
^0+

)M`1        # Unary to decimal; End print and undo
^0+         # Remove leading zeros

T`01`10     # Flip bits; (implicit loop end)

1

Ruby - 70 ไบต์

λ cat inf.rb
n,=$*[0].unpack 'B*';loop{p n.to_i(2);n.tr!('10','01').sub!(/^0*/,'')}
λ ruby inf.rb Hello
310939249775
788572378000
310939249775
238816564112
36061342831
32658133904
1701604463
445879184
90991727
43226000
23882863
9671568
7105647
1282960
814191
234384
27759
5008
3183
912
111
16
15
0
inf.rb:1:in `block in <main>': undefined method `sub!' for nil:NilClass (NoMethodError)
        from inf.rb:1:in `loop'
        from inf.rb:1:in `<main>'

โปรแกรมออกจากข้อยกเว้นหลังจากเสร็จสิ้น แต่ความเข้าใจของฉันคือว่าใช้ได้ตราบใดที่เอาต์พุตข้อผิดพลาดไปที่ STDERR แทนที่จะเป็น STDOUT (ซึ่งเป็นเช่นนั้น)


1

C, 147 135 133 125 122 121 117 115 103 ไบต์

บันทึก 5 ไบต์ด้วย @Cyoce!

บันทึก 2 ไบต์ขอบคุณ @Cyoce และ @cleblanc!

บันทึก 12 ไบต์ด้วย @ceilingcat

i,n;main(p,v)char**v;{while(*v[1])i=i*256+*v[1]++;for(;printf("%d\n",n=i),i;i^=p-1)for(p=2;n/=2;)p*=2;}

Ungolfed:

int i;
int main (c,v) {
    char**v;
    while (*v[1]) /* put first command line argument into i as binary */
        i = i*256 + *v[1]++;
    while (i != 0) { 
        printf("%d\n",i);
        int p = 2,n = i;
        while (n /= 2) /* calculate smallest power of 2 > i */
            p *= 2;
        i ^= p - 1; /* flip bits */
    }
}

ฉันคิดว่าคุณสามารถออกจากการintประกาศ
Cyoce

คุณยังสามารถบันทึกไบต์ด้วยการแปลงwhileลูปสุดท้ายเป็นforลูป
Cyoce

และคุณสามารถเปลี่ยนwhile(1)เป็นfor(;;)
Cyoce

@Cyoce ฉันพยายามลบการintประกาศทุกที่และมีgcc -std=89ข้อผิดพลาด แต่ขอบคุณสำหรับfor(;;)เคล็ดลับ ฉันจะพยายามลบintคำแถลงต่อไปนี้ :)))
Noodle9

ขอโทษฉันไม่ได้ทดสอบ ฉันคิดว่ามันจะทำงานถ้าคุณย้ายพวกเขาไปด้านบน ( i;main(c,v)char**v;{...}) บนมือถือตอนนี้ฉันไม่แน่ใจ
Cyoce

0

C, 129 120 117 110 107 105 ไบต์

long long i,m,n;f(char*v){for(;*v;i<<=8,i+=*v++);for(;printf("%llu,",i),n=i;i^=m-1)for(m=2;n>>=1;m<<=1);}

ทดสอบกับ

main (int c, char**v) {
    f(v[1]);
}

เอาท์พุต

5291279215216915577,3932092821637860230,679593196789527673,473328307817319302,103132444486104185,40982743589751686,31074850448176249,4953946570787718,4053252683953273,450346943417222,112603010004089,28134478351238,7049893737593,1746199284614,452823970937,96931842950,40507110521,28212366214,6147372153,2442562438,1852404857,295078790,241792121,26643334,6911097,1477510,619641,428934,95353,35718,29817,2950,1145,902,121,6,1,0,

ฉันคิดว่าคุณสามารถย้ายi=0การประกาศของiและออกจากส่วนเริ่มต้นของforว่างเปล่าห่วง
Cyoce

@Cyoce ฟังก์ชั่นจะต้องทำงานทุกครั้งที่มีการเรียกและเนื่องจากiเป็น int ทั่วโลกโดยปริยายมันจะต้องมีการเริ่มต้นทุกครั้งที่เรียกว่า f (... )
cleblanc

@Cyoce คุณถูกต้องหลังจากทั้งหมด ฟังก์ชั่นไม่ออกจนกว่าiจะเป็นศูนย์อีกครั้งดังนั้นจึงยังใช้งานได้อีกครั้ง
cleblanc


0

C #, 360 359 ไบต์

using w=System.Console;using q=System.Convert;s={System.Func<int,int,string>S=q.ToString;string t="",f="";for(int i=0;i<s.Length;i++)t+=i>0?S(s[i],2).PadLeft(8,'0'):S(s[i],2);w.WriteLine(q.ToInt64(t,2).ToString());while(t!="0"){f="";foreach(var n in t)f+=n=='0'?'1':'0';t=f.TrimStart(new char[]{'0'});t+=t==""?"0":"";w.WriteLine(q.ToInt64(t,2).ToString());}};

โปรแกรมเต็มรูปแบบ:

using w = System.Console;
using q = System.Convert;

class a
{
    static void Main()
    {
        System.Action<string> b = s =>
        {
            System.Func<int,int,string> S = q.ToString;
            string t = "", f = ""; // Var does not work here
            for(int i = 0; i < s.Length; i++)
                t += i > 0 ? S(s[i], 2).PadLeft(8, '0') : S(s[i], 2);
            w.WriteLine(q.ToInt64(t, 2).ToString());
            while(t != "0")
            {
                f = "";
                foreach (var n in t) f += n== '0' ? '1' : '0';
                t = f.TrimStart(new char[] { '0' });
                t += t == "" ? "0" : "";
                w.WriteLine(q.ToInt64(t, 2).ToString());
            }
        };

        b("Inf");
        b("Infinity");
        w.Read(); // prevent close in VS
    }
}

ฉันจะไม่ทำ C # แต่สามารถvar t="";var f="";จะvar t="",f=""แทน? บันทึก 5 ไบต์
corsiKa

@corsiKa ใช่ฉันพยายาม แต่มันทำให้ฉันมีข้อผิดพลาดฉันเดาว่ามันเป็น var และไม่ใช่สตริง
Yodle

ที่จริงแล้วสายอักขระจะบันทึกหนึ่งไบต์ดังนั้นฉันเดาว่าฉันจะทำอย่างนั้น
Yodle

คุณสามารถสร้างตัวแปร az เป็นศูนย์เพื่อบันทึกราคาที่น่ารังเกียจเหล่านั้นได้หรือไม่
corsiKa

เพิ่งลองจริง ๆ แล้วมันจะเพิ่ม bytecount เพราะฉันไม่สามารถแทนที่ทั้งสตริง "0" และถ่าน '0' :(
Yodle
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.