Đếm ngược từ Infinity Infinity


47

Có vẻ như là một nhiệm vụ bất khả thi phải không? Chà, thật ra không khó lắm đâu. Nếu chúng ta viết từ Infinitydưới dạng mã nhị phân 8 bit 8 bit, chúng ta sẽ nhận được:

01001001 01101110 01100110 01101001 01101110 01101001 01110100 01111001

Điều này có thể được nối và chuyển đổi thành giá trị thập phân 5291279215216915577. Bây giờ đó là một số chúng ta có thể làm việc với ...

Cách bạn sẽ đếm ngược là:

  1. Xuất chuỗi gốc dưới dạng số thập phân (như hình trên)
  2. Xóa các số 0 đứng đầu trong biểu diễn nhị phân của nó (nếu có)
  3. Chuyển đổi các bit trong biểu diễn nhị phân (1-> 0, 0-> 1)
  4. Xuất số theo số thập phân
  5. Lặp lại các bước 2-4 như cho đến khi bạn đạt 0.

Thử thách:

Tạo một chương trình hoặc hàm lấy một chuỗi làm đầu vào và đầu ra (trên bất kỳ định dạng phù hợp nào) các số bạn sẽ nhận được khi thực hiện quy trình trên.

Trường hợp thử nghiệm:

Tôi nghĩ rằng thử thách sẽ khá dễ hiểu, mặc dù đó chỉ là một trường hợp thử nghiệm. Tôi sẽ sử dụng Infthay vì Infinityđể giữ điều này khá ngắn.

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

Mã của bạn phải hỗ trợ các chuỗi có thể được biểu diễn dưới dạng số nhị phân cho đến giới hạn ngôn ngữ của bạn. Tất cả các chuỗi sẽ chỉ chứa các ký tự ASCII có thể in từ 32-126 (khoảng trắng đến dấu ngã).


Bảng xếp hạng


31
Chuck Norris , 8 byte:Inf:-1:0
Luis Mendo 2/11/2016

2
@LuisMendo Chuck Norris 'NARS-APL:∞..0
Adám

5
@LuisMendo Bạn có chắc là bạn không có ý nói Jon Skeet ?
mbomb007

Câu trả lời:


12

Thạch , 15 10 byte

-5 byte nhờ @Dennis (chuyển đổi trực tiếp từ cơ sở 256 sau khi truyền thứ tự)

Oḅ⁹µBCḄµÐĿ

Dùng thử trực tuyến!

Làm sao?

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
Phần đầu tiên chỉ là Oḅ⁹.
Dennis

Ôi trời, sao tôi lại nhớ thế?!
Jonathan Allan

11

Python 2, 89 82 77 76 75 byte

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

Kiểm tra nó trên Ideone .

Làm thế nào nó hoạt động

Sau khi khởi tạo n thành 0 , dòng thứ hai thực hiện chuyển đổi chuỗi thành số nguyên được chỉ định trong các thách thức như sau.

Trong mỗi bước, n được dịch 8 đơn vị sang trái, sau đó bit OR -ed với điểm mã của ký tự tiếp theo c . Đối với Inf đầu vào , điều này diễn ra như sau.

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

Bây giờ chúng tôi đã sẵn sàng để tạo đầu ra. Để đảo ngược các bit của n , chúng tôi tiến hành như sau.

Đầu tiên, chúng tôi tính toán các bit trong biểu diễn nhị phân của n mà không có các số 0 đứng đầu. Hãy gọi kết quả k . Sau đó, chúng tôi tính toán k k sức mạnh của 2 , trong đó có k + 1 chữ số nhị phân: a single 1 , tiếp theo là k 0 's. Chúng tôi trừ đi 1 từ kết quả, thu được một số gồm k cái, sau đó chúng tôi XOR với n để đảo ngược các bit của nó. Đối với đầu vào inf, điều này diễn ra như sau.

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

Về trở ngại bổ sung trong việc thực hiện là chúng ta phải in n trước bước đầu tiên, sau bước cuối cùng và trong tất cả các bước ở giữa. Python không có các vòng lặp do-while và một câu lệnh in có giá 8 byte, vì vậy chúng tôi thực hiện như sau.

Trong việc thực hiện đơn giản của bước cập nhật, nghĩa là,

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

chúng ta thay thế vòng lặp bằng một vô hạn ( while 1) và tính toán 1trong vòng lặp là n/n. Điều này là tương đương trong khi n> 0 .

Khi n = 0 , chúng tôi ở lại vòng lặp, in trạng thái một lần nữa, sau đó thử cập nhật nó. Tuy nhiên, 0/0kích hoạt ZeroDivisionError , thoát ra khỏi vòng lặp và thoát với một lỗi. Lưu ý rằng điều này gây ra đầu ra đi lạc đến STDERR, được cho phép theo mặc định .


2
Tôi thích -n/nmánh khóe đó :-)
ETHproductions 2/11/2016

Bạn có thể giải thích hơn n/nlừa? Có lẽ nó đã được giải thích trong một câu trả lời khác ở đâu đó nhưng tôi không tìm thấy nó. Nó làm gì ở đây?
Stewie Griffin

@StewieGriffin n / n là 1 cho đến n bằng 0, sau đó nó sẽ báo lỗi và khiến chương trình dừng lại.
jazzpi

Với một thông báo lỗi (tôi hy vọng)?
Stewie Griffin

1
@StewieGriffin Thật vậy. Python rất dài dòng khi báo cáo lỗi. Tôi đã chỉnh sửa câu trả lời của mình để kết hợp một lời giải thích.
Dennis

8

JavaScript, 82 byte

Đã lưu một byte nhờ @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

Một trong số rất ít lần một chương trình đầy đủ vượt trội hơn một chức năng (và ES6 không vượt trội so với ES5) ...


Ở trên hỗ trợ tối đa 4 chữ cái. Thêm 4 byte để hỗ trợ tối đa 6 chữ cái:

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)
Tít

@Titus Cảm ơn! Không chắc tại sao tôi không nghĩ về điều đó
ETHproductions 2/11/2016

n<<8|y.charCodeAt()nên lưu một byte. for(;n;)for(i=!alert(n);i<=n;i*=2)n^=isẽ lưu một byte khác, nhưng bạn sẽ không hiển thị 0, điều này có thể được yêu cầu.
Arnauld

@Arnauld Cảm ơn. Tôi đã nghĩ về việc thực hiện n<<8sớm hơn nhưng quyết định nó sẽ không hoạt động vì nó sẽ phá vỡ n với hơn 31 bit. Tôi cho rằng bây giờ tôi đã không phân chia nó giữa phiên bản 31 bit và phiên bản 53 bit ... Và thật đáng buồn, tôi không nghĩ mình có thể lưu bất cứ điều gì vào cảnh báo trong khi cảnh báo cả hai lặp đi lặp lại và cuối cùng
Sản phẩm ETH

7

Trên thực tế , 14 byte

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

Hãy thử trực tuyến!

Giải trình:

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 byte

Sử dụng mã hóa CP-1252 .

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

Hãy thử trực tuyến!

Giải trình

Ç                     # 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

MATL , 13 byte

8W:qZA`tB~XBt

Hãy thử trực tuyến!

Giải trình

8W:q            % Push array [0 1 ... 255]
    ZA          % Take input string and convert it from the base defined by the
                % alphabet [0 1 ... 255] to decimal
      `         % Do...while
       t        % Duplicate
        B       % Convert to binary
         ~      % Negate
          XB    % Convert to decimal
            t   % Duplicate. Used as loop condition: exit if zero

4

Toán học, 99 byte

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

Chức năng ẩn danh. Lấy một chuỗi làm đầu vào và trả về một danh sách các số làm đầu ra.


4

Haskell, 109 123 118 102 97 byte

Cảm ơn @nimi vì đã tiết kiệm 5 byte!

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

Sử dụng: (++[0]).fst.span(>0).iterate c.foldl((+).(256*))0.map fromEnum $ "Infinity"

Được đảm bảo để làm việc trên các số lên đến 29 bit theo ngôn ngữ, thường hoạt động lên đến số 63 bit trên hệ thống 64 bit. Sử dụng map(fromIntegral.fromEnum)thay thế (+14 byte) để hỗ trợ số lượng lớn tùy ý.

Hoạt động cho phạm vi unicode [0..255]. Đệ quy lật bit.


1
Bạn có thể thay thế takeWhile(>0)bằng fst.span(>0). Nếu bạn đi miễn phí, bạn có thể bỏ tên f, vì vậy chức năng chính của bạn là (++[0]) ... map fromEnum.
nimi

@nimi cảm ơn, bỏ tên giải quyết vấn đề suy luận kiểu tôi gặp phải f.
Angs

Tại sao fromIntegral? Từ thử thách: "phải hỗ trợ ... tối đa 63 bitcoin ... hoặc giới hạn ngôn ngữ của bạn", vì vậy Intsẽ ổn thôi. Nếu bạn muốn giữ nó, hãy chuyển nó sang map, tức là phiên bản cũ của bạn foldl1map(fromIntegral.fromEnum).
nimi

@nimi OP đã đăng một bình luận ở đây (kể từ khi xóa), hỏi xem điều này có hỗ trợ 63 bit không, vì vậy tôi cho rằng đó là ý định của anh ấy. Đánh bại tôi
Angs

4

PHP, 132 126 123 120 108 107 byte

foreach(unpack("C*",$argv[1])as$i)$n=$n*256+$i;for(print$n;$n;)echo _.$n=bindec(strtr(decbin($n),"01",10));
  • in 0 sau vòng lặp thay vì giá trị ban đầu trước vòng lặp tiết kiệm 6 byte.
  • unpackthay vì str_splitlàm cho ord()lỗi thời -> -3 byte
  • gạch dưới _làm dấu phân cách tiết kiệm 3.
  • bindecthay vì ltrimxóa các số 0 đứng đầu: -12
  • echotrong thân vòng lặp tiết kiệm 1 byte trên printđầu vòng lặp.

Không thể $n=$n*256+$i;for(print$n;$n;)được viết là for(print$n=$n*256+$i;$n;)? Vì phần gán sẽ thực thi một lần, nên phần này sẽ hoạt động. Và thay vì echo _.$n=[...], bạn nên sử dụng echo _,$n=[...]thay thế. Nó sẽ không lưu bất kỳ byte nào, nhưng sẽ tăng tốc mã thành một bit nhỏ xíu nhỏ xíu và sẽ tách các câu lệnh. Điều đó có nghĩa là, ví dụ, echo _,$a?5:6;có thể được viết thay vì echo _.($a?5:6);. Điều này có thể hữu ích trong tương lai.
Ismael Miguel

@IsmaelMiguel Phần bài tập là một vòng lặp. Tôi thực sự sử dụng dấu phẩy khi tôi không cần chấm; nó là tàn dư từ printtrong trường hợp này. Một mình không đáng để chỉnh sửa; nhưng cảm ơn.
Tít

Ồ, đúng rồi ... Nó ở bên trong foreach(unpack("C*",$argv[1])as$i)... Ngớ ngẩn với tôi ... Và vâng, thay đổi một khoảng thời gian để dấu phẩy có tác dụng tương tự không đáng để gặp rắc rối.
Ismael Miguel

4

Perl, 65 byte

Mã 53 byte + 12 cho -Mbigint -p.

Cảm ơn @ Dada đã tiết kiệm cho tôi 13 byte!

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

Cách tiếp cận khá đơn giản, chỉ khác với hầu hết trong số này là số được lưu dưới dạng nhị phân và được in ra dưới dạng thập phân. Tôi chắc chắn rằng nó có thể được cải thiện, có lẽ với việc lưu trữ các chi tiết trong một mảng. -Mbigintlà một chút bất tiện nhưng cần thiết.

Sử dụng

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
Giải nén bạn của tôi, giải nén! perl -Mbigint -lpE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'(Tôi không có ý tưởng làm thế nào để sử dụng giải nén thông thường, tôi chỉ gặp may khi tìm cách chuyển chuỗi thành nhị phân ;-))
Dada

Ahhh, tôi luôn quên về unpackcú pháp luôn thổi vào tâm trí của tôi! Tôi sẽ cập nhật, cảm ơn bạn!
Dom Hastings

perlpacktut sẽ giúp ... Tôi đã đọc 10 dòng đầu tiên hàng chục lần, nhưng tôi thực sự nên dành thời gian để đọc phần còn lại!
Dada

@Dada Tôi chắc chắn tôi đã đọc nó nhiều lần, nó chỉ không bao giờ ở lại ... Cảm ơn lần nữa -13 là một kỳ công không nhỏ! Tôi đã phải chuyển sang echo -nlà thay đổi duy nhất khác.
Dom Hastings

4

Bình thường, 12 byte

.usi!MjN2 2C

Một chương trình lấy đầu vào của một chuỗi được trích dẫn và in kết quả dưới dạng danh sách các số nguyên.

Xác nhận tất cả các trường hợp kiểm tra

Làm thế nào nó hoạt động

.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 byte

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

Ý tưởng chính là chuyển đổi chuỗi thành byte thành số. Mỗi lần lặp lại in đầu ra và XOR với tất cả 1 giây để tiến về 0.


Bạn không cần dấu ngoặc đơn xung quanh 2**x.bit_length()-1. Thứ tự các phép toán cho công suất và phép trừ cao hơn xor. Ngoài ra, đó whilecó thể là trên một dòng duy nhất.
mbomb007

Viết vòng lặp while trên một dòng (xóa dòng mới và thụt lề)
FlipTack

Hãy thử bắt đầu chương trình với P=printvà sau đó sử dụng P()thay vìprint()
Cyoce

3

Python 2, 117 115 byte

Tiết kiệm 2 byte nhờ Cyoce.

Giả sử đầu vào kèm theo trong ngoặc kép, vd "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 đến chữ số cao nhất, m-1mặt nạ XOR để thực hiện thao tác mong muốn. Phần dài nhất là chuyển đổi đầu vào thành chuỗi bit ban đầu.

Thí dụ:

"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

Bạn có thể thay thế -i-1bằng~i
Cyoce

3

Ruby, 104 101 100 81 80 65 byte

19 byte được lưu nhờ vào @WayneConrad!
15 byte được lưu nhờ vào @philomory!
Lưu 1 byte nhờ @LeeW!

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

Đưa đầu vào thông qua các đối số dòng lệnh.

Lấy cảm hứng từ câu trả lời Python của @ JimmyJohnson


Bạn có thể lưu một vài ký tự bằng cách thay thế i.to_s(2).rjust 8,'0'bằng"%08b"%i
Wayne Conrad

Ngoài ra, tôi nghĩ inject(:+)có thể được thay thế bằngjoin
Wayne Conrad

@WayneConrad cảm ơn vì sự giúp đỡ! Không chắc là tôi đã quên những thứ đó như thế nào
Cyoce 2/11/2016

Mừng vì tôi có thể giúp! Cảm ơn bạn đã dạy tôi phương pháp #bit_length mà tôi không biết.
Wayne Conrad

1
Chuyển sang unpacktheo sau [0]thay vì gây rối gsubsẽ tiết kiệm 11 byte. Chuyển sang $*[0]thay vì gets.chop(sử dụng đối số dòng lệnh thay vì đầu vào bàn điều khiển) sẽ lưu thêm 9, dòng đầu tiên trở thành p n=$*[0].unpack('B*')[0].to_i(2).
triết học

3

Mê cung , 104 103 byte

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

Hãy thử trực tuyến!

Giải trình:

Hình ảnh được mã hóa màu của mã nguồn

Con trỏ lệnh bắt đầu ở phía trên bên trái hầu hết các ký tự không tường (tường bao gồm khoảng trắng và bất kỳ chữ nào ngoại trừ v).

Trái cam:

Vòng lặp này lấy một ký tự đầu vào tại một thời điểm dưới dạng mã ASCII, thêm nó vào giá trị hiện tại và nhân giá trị hiện tại với 256.

  • ' Không-op
  • ,Đẩy mã ascii của char đầu vào tiếp theo lên trên cùng của ngăn xếp hoặc -1 nếu EOF. Tại thời điểm này nếu đầu vào được nhận, mã sẽ rẽ phải (di chuyển xuống) vì đỉnh của ngăn xếp là tiềm năng. Nếu không, nó sẽ rẽ trái vì đỉnh của ngăn xếp là âm.
  • | Bật hai mục trên cùng từ ngăn xếp và đẩy kết quả của bit OR.
  • _ Đẩy số không
  • 256Mỗi chữ số nhìn thấy bật xvà đẩy x*10+digit. Vì vậy, điều này kết hợp với việc đẩy số 0 trước đó đẩy 256 lên đỉnh của ngăn xếp.
  • *Pop y, pop x, đẩy x*y. Tại thời điểm này vì đỉnh của ngăn xếp là dương, mã sẽ rẽ phải để tiếp tục vòng lặp.

Màu xanh da trời:

  • )Tăng đỉnh của ngăn xếp. Khi kết thúc đầu vào, mã sẽ rẽ trái để đến điểm này với -1 trên ngăn xếp sẽ được tăng lên 0.
  • 256 Có đỉnh của ngăn xếp 0 cho phép chúng ta đẩy 256 này.
  • /Pop y, pop xđẩy x/y(phân chia số nguyên). Vì chúng tôi đã nhân đầu vào với 256 mỗi vòng lặp, chúng tôi cần hoàn nguyên phép nhân cuối cùng.
  • : Sao chép đỉnh của ngăn xếp để chúng tôi có một bản sao của giá trị hiện tại cho lần sau.
  • ! Bật đầu ngăn xếp và in giá trị nguyên sang STDOUT.
  • \ In một dòng mới.
  • _2 Đẩy một hai đến đỉnh của ngăn xếp.
  • } Di chuyển đỉnh của ngăn xếp đến đỉnh của ngăn xếp phụ trợ.

Màu đỏ:

Vòng lặp này lật các bit của giá trị hiện tại bằng XOR với một giá trị cụ thể được tính trong vòng lặp bên trong (màu xanh lá cây). Sau đó nó xuất giá trị hiện tại và thoát khỏi chương trình nếu giá trị hiện tại bằng không.

  • _ Đẩy số không (điều khiển lưu lượng).
  • ; Hủy bỏ đỉnh của ngăn xếp (luồng điều khiển).
  • :Nhân đôi giá trị hiện tại. Bản sao sẽ được sử dụng để tính XOR.
  • _ Đẩy số không (điều khiển lưu lượng).
  • (Vòng xanh)
  • $Pop y, pop x, đẩy x XOR y.
  • :! Nhân đôi giá trị hiện tại và in biểu diễn số nguyên.
  • Nếu giá trị hiện tại là 0, chúng tôi tiếp tục đi thẳng vào @và chấm dứt.
  • \ In một dòng mới.
  • _2} Đẩy 2 và di chuyển đến ngăn xếp phụ trợ.
  • _1 Đẩy 1 (điều khiển lưu lượng).

Màu xanh lá:

Vòng lặp này tính toán giá trị mà theo đó chúng ta cần XOR giá trị hiện tại. Điều này được thực hiện bằng cách liên tục nhân đôi đỉnh của ngăn xếp phụ trong khi giảm một nửa bản sao của giá trị hiện tại trên điểm dừng của ngăn xếp chính cho đến khi đạt 0.

  • _ Đẩy số không (điều khiển lưu lượng).
  • ; Hủy giá trị hiện tại chỉ được sử dụng để thực thi luồng điều khiển.
  • _2 Đẩy 2 để giảm một nửa giá trị hiện tại.
  • / Phân phát
  • { Di chuyển đỉnh của ngăn xếp phụ lên đỉnh ngăn xếp chính.
  • _2* Nhân đôi đỉnh của ngăn xếp
  • } Di chuyển đỉnh của ngăn xếp chính trở lại ngăn xếp phụ.
  • _1 Đẩy một cái cho dòng điều khiển.
  • Sau khi thoát khỏi vòng lặp:
  • ; Hủy bỏ số 0 còn lại để tính XOR.
  • { Di chuyển XOR tính toán vào ngăn xếp chính.
  • ( Trừ một từ giá trị XOR.

2

PowerShell v2 +, 158 byte

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}

Vâng, vì vậy, chuyển đổi cơ sở trong PowerShell thực sự rất may mắn . Và chúng tôi có thể làm điều đó hai lần ở đây.

OK, vì vậy đây chỉ là một forvòng lặp trên $a- tức là, chúng ta lặp miễn là $atồn tại. Cuối cùng chúng ta sẽ đạt được một chuỗi trống (đó là falsey), vì vậy đó là cách chúng ta sẽ chấm dứt.

Việc thiết lập vòng lặp, $a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)})lấy đầu vào $args[0], biến nó thành một char-array và lặp qua từng ký tự. Chúng tôi sử dụng .NET [convert]::ToString(int,base)để chuyển đổi từng chuỗi thành chuỗi nhị phân. Tuy nhiên, điều đó không bao gồm các số 0 đứng đầu, vì vậy chúng ta cần truyền lại chuỗi đó thành một số [int]và gọi phương thức của nó .ToString() với các 8số không làm mặt nạ. Sau đó, các chuỗi được gói gọn trong parens và -joined với nhau, sau đó được lưu vào $a.

Trong vòng lặp, chúng tôi [convert]::ToInt64(string,base)chuyển đổi số nhị phân thành số thập phân. Điều đó được để lại trên đường ống và sau đó được tuôn ra khi vòng lặp đặt lại (và do đó được in ngầm). Phần tiếp theo thực hiện các phép tính - chúng ta .TrimStart()loại bỏ bất kỳ số 0 đứng đầu nào, -split0để phân chia các số không và lấy một biểu stringđồ của các số 1đó, -replacecác số có số không và cuối cùng -joinlà mảng trở lại với 1s. Sau đó, vòng lặp bắt đầu lại.

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 byte

q256b0{_p2b:!2bj}j

Hãy thử trực tuyến!

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

LƯU Ý: Phiên bản 16 byte cũ không hoạt động chính xác với các chuỗi trống:

q256b{_p2b:!2b}h

Ngoài ra, cảm ơn Dennis vì đã gợi ý pgiúp tiết kiệm 1 byte so với N\việc đưa dòng mới vào ngăn xếp.


_p2b:!2btiết kiệm một byte. Ngoài ra, bạn nên sử dụng l; rsẽ thất bại nếu đầu vào chứa khoảng trắng.
Dennis

@Dennis Cảm ơn, mặc dù điều này bây giờ làm tôi lo lắng nếu một chuỗi trống là một vấn đề.
Linus

Đúng. qsẽ hoạt động chính xác với các chuỗi trống.
Dennis


1

Võng mạc, 116 byte

Số lượng byte giả định mã hóa ISO 8859-1. Dòng 5 chứa các byte không in được. Đó là 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ùng thử trực tuyến

Đừng thử điều này với đầu vào dài hơn hai ký tự. (Đã hết thời gian sử dụng trình thông dịch trực tuyến.) Chúng ta phải chuyển đổi nhị phân thành đơn vị trước số thập phân. :CƯỜI MỞ MIỆNG

Thật không may, có một số 0 và linefeed kéo dài, nhưng tôi quyết định cho rằng điều đó là ổn vì đầu ra vẫn đúng.

Giải trình

-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 byte

λ 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>'

Chương trình thoát với một ngoại lệ sau khi hoàn thành, nhưng sự hiểu biết của tôi là nó vẫn ổn miễn là đầu ra lỗi chuyển sang STDERR chứ không phải STDOUT (mà nó làm).


1

C, 147 135 133 125 122 121 117 115 103 byte

Đã lưu 5 byte nhờ @Cyoce!

Đã lưu 2 byte nhờ @Cyoce và @cleblanc!

Đã lưu 12 byte nhờ @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;}

Ung dung:

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 */
    }
}

Tôi nghĩ bạn có thể bỏ qua các inttuyên bố
Cyoce

Bạn cũng có thể lưu một byte bằng cách chuyển đổi whilevòng lặp cuối cùng thành một forvòng lặp
Cyoce

Và bạn có thể đổi while(1)thànhfor(;;)
Cyoce

@Cyoce Tôi đã thử xóa inttờ khai ở mọi nơi và gặp gcc -std=89lỗi. Nhưng cảm ơn vì tiền for(;;)boa. Tôi sẽ tiếp tục cố gắng xóa các intkhai báo :)))
Noodle9

xin lỗi, tôi đã không kiểm tra nó Tôi nghĩ rằng nó sẽ hoạt động nếu bạn di chuyển chúng lên đầu ( i;main(c,v)char**v;{...}). Trên thiết bị di động ngay bây giờ vì vậy tôi không thể chắc chắn
Cyoce

0

C, 129 120 117 110 107 105 byte

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);}

Đã thử nghiệm với

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

đầu ra

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,

Tôi nghĩ bạn có thể chuyển i=0sang khai báo ivà để fortrống phần khởi tạo của vòng lặp
Cyoce

@Cyoce Hàm cần hoạt động mỗi lần nó được gọi và vì inó là ẩn toàn cầu int nên nó cần được khởi tạo mỗi khi f (...) được gọi.
cleblanc

@Cyoce Bạn đã đúng sau tất cả. Hàm không thoát cho đến khi ibằng 0 một lần nữa vì vậy nó vẫn có thể sử dụng lại được.
cleblanc


0

C #, 360 359 byte

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());}};

Chương trình đầy đủ:

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
    }
}

Tôi không làm C #, nhưng có var t="";var f="";thể var t="",f=""thay thế? Tiết kiệm 5 byte.
corsiKa

@corsiKa Vâng, tôi đã thử nhưng nó đã báo lỗi, tôi đoán nguyên nhân là do var chứ không phải chuỗi.
Yodle

Trên thực tế, chuỗi không lưu một byte, vì vậy tôi đoán tôi sẽ làm theo cách đó.
Yodle

Ngoài ra, bạn có thể thực hiện biến az cho số không để lưu những trích dẫn khó chịu đó không?
corsiKa

Chỉ cần thử, nó thực sự làm tăng giá trị bởi vì tôi không thể thay thế cả chuỗi "0" và char '0' :(
Yodle
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.