Hitung mundur dari "Infinity"

47

Sepertinya tugas yang mustahil kan? Sebenarnya tidak terlalu sulit. Jika kita menulis kata itu Infinitysebagai kode ASCII biner 8-bit, kita akan mendapatkan:

01001001 01101110 01100110 01101001 01101110 01101001 01110100 01111001

Ini dapat digabungkan, dan dikonversi ke nilai desimal 5291279215216915577. Nah, itu angka yang bisa kita kerjakan ...

Cara Anda menghitung mundur adalah:

  1. Keluarkan string asli sebagai angka desimal (seperti yang ditunjukkan di atas)
  2. Hapus awalan 0s dalam representasi binernya (jika ada)
  3. Beralih bit dalam representasi biner (1-> 0, 0-> 1)
  4. Keluarkan angka dalam desimal
  5. Ulangi langkah 2-4 hingga Anda mencapai 0.

Tantangan:

Buat program atau fungsi yang mengambil string sebagai input, dan output (pada format apa pun yang sesuai) angka yang akan Anda dapatkan ketika melakukan prosedur di atas.

Kasus cobaan:

Saya pikir tantangannya akan cukup mudah untuk dipahami, meskipun hanya satu test case. Saya akan menggunakan Infalih-alih Infinitymenjaga ini cukup singkat.

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

Kode Anda harus mendukung string yang dapat direpresentasikan sebagai angka biner hingga batas bahasa Anda. Semua string hanya akan berisi karakter ASCII yang dapat dicetak dari 32-126 (spasi hingga tilde).


Papan peringkat

Stewie Griffin
sumber
31
Chuck Norris , 8 byte:Inf:-1:0
Luis Mendo
2
@LuisMendo Chuck Norris 'NARS-APL:∞..0
Adám
5
@LuisMendo Apakah Anda yakin maksud Anda Jon Skeet ?
mbomb007

Jawaban:

12

Jelly , 15 10 byte

-5 bytes terima kasih kepada @Dennis (konversikan langsung dari basis 256 setelah pemain ordinal)

Oḅ⁹µBCḄµÐĿ

TryItOnline!

Bagaimana?

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 
Jonathan Allan
sumber
1
Bagian pertama adalah adil Oḅ⁹.
Dennis
Ya ampun, bagaimana saya bisa melewatkan itu ?!
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

Uji di Ideone .

Bagaimana itu bekerja

Setelah menginisialisasi n ke 0 , baris kedua melakukan konversi string-ke-integer yang ditentukan dalam tantangan sebagai berikut.

Di setiap langkah, n digeser 8 unit ke kiri, lalu bitwise ATAU -ed dengan titik kode karakter berikutnya c . Untuk input Inf , ini sebagai berikut.

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

Sekarang kita siap untuk menghasilkan output. Untuk membalikkan bit n , kami melanjutkan sebagai berikut.

Pertama, kita menghitung bit dalam representasi biner n tanpa memimpin nol. Mari kita sebut hasilnya k . Kemudian, kita menghitung kekuatan k k dari 2 , yang memiliki k + 1 digit biner: 1 tunggal , diikuti oleh k 0 's. Kita kurangi 1 dari hasilnya, menghasilkan angka yang terdiri dari k , yang kemudian kita XOR dengan n untuk membalikkan bitnya. Untuk input inf ini berlaku sebagai berikut.

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

Pada rintangan tambahan dalam implementasi adalah bahwa kita harus mencetak n sebelum langkah pertama, setelah langkah terakhir, dan di semua langkah di antaranya. Python tidak memiliki loop do-while dan satu pernyataan cetak berharga 8 byte, jadi kami melakukan yang berikut.

Dalam implementasi langsung dari langkah pembaruan, yaitu,

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

kami mengganti loop dengan yang tak terbatas ( while 1) dan menghitung 1dalam loop sebagai n/n. Ini sama dengan n> 0 .

Sekali n = 0 , kita tetap di loop, mencetak status sekali lagi, lalu mencoba memperbaruinya. Namun, 0/0memicu ZeroDivisionError , keluar dari loop dan keluar dengan kesalahan. Perhatikan bahwa ini menyebabkan output liar ke STDERR, yang diizinkan secara default .

Dennis
sumber
2
Saya suka -n/ntrik itu :-)
ETHproduk
Bisakah Anda menjelaskan daripada n/ntrik? Mungkin dijelaskan di jawaban lain di suatu tempat tetapi saya belum menemukannya. Apa fungsinya di sini?
Stewie Griffin
@StewieGriffin n / n adalah 1 hingga n adalah 0, lalu melempar kesalahan dan menyebabkan program berhenti.
jazzpi
Dengan pesan kesalahan (saya harap)?
Stewie Griffin
1
@StewieGriffin Memang. Python adalah verbose menyakitkan ketika datang ke pelaporan kesalahan. Saya telah mengedit jawaban saya untuk memasukkan penjelasan.
Dennis
8

JavaScript, 82 byte

Menyimpan satu byte berkat @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

Salah satu dari beberapa kali ketika program penuh mengungguli fungsi (dan ES6 tidak mengungguli ES5) ...


Kata-kata di atas mendukung hingga 4 huruf. Tambahkan 4 byte untuk mendukung kata hingga 6 huruf:

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

Produksi ETH
sumber
g=a=>a[0]?a.pop().charCodeAt()+g(a)*256:0(-1)
Titus
@Titus, Terima kasih! Tidak yakin mengapa saya tidak memikirkan hal itu
ETHproduk
n<<8|y.charCodeAt()harus menyimpan byte. for(;n;)for(i=!alert(n);i<=n;i*=2)n^=iakan menyimpan byte lain, tetapi Anda tidak akan menampilkan 0, yang mungkin diperlukan.
Arnauld
@Arnauld Terima kasih. Saya berpikir tentang melakukan n<<8lebih awal tetapi memutuskan itu tidak akan berhasil karena akan rusak untuk n dengan lebih dari 31 bit. Saya kira itu tidak masalah sekarang karena saya sudah membaginya antara versi 31-bit dan versi 53-bit ... Dan sayangnya, saya tidak berpikir saya bisa menyimpan apa pun pada peringatan sementara mengingatkan kedua yang pertama iterasi dan yang terakhir.
ETHproduk
7

Sebenarnya , 14 byte

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

Cobalah online!

Penjelasan:

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
Mego
sumber
6

05AB1E , 18 byte

Menggunakan pengodean CP-1252 .

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

Cobalah online!

Penjelasan

Ç                     # 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
Emigna
sumber
4

MATL , 13 byte

8W:qZA`tB~XBt

Cobalah online!

Penjelasan

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
Luis Mendo
sumber
4

Mathematica, 99 byte

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

Fungsi anonim. Mengambil string sebagai input, dan mengembalikan daftar angka sebagai output.

LegionMammal978
sumber
4

Haskell, 109 123 118 102 102 97 byte

Terima kasih kepada @nimi karena telah menghemat 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

Pemakaian: (++[0]).fst.span(>0).iterate c.foldl((+).(256*))0.map fromEnum $ "Infinity"

Dijamin untuk bekerja pada angka hingga 29 bit oleh bahasa, biasanya bekerja hingga angka 63-bit pada sistem 64-bit. Gunakan map(fromIntegral.fromEnum)sebagai gantinya (+14 byte) untuk mendukung jumlah besar yang sewenang-wenang.

Bekerja untuk rentang unicode [0..255]. Membalik bit secara rekursif.

Angs
sumber
1
Anda bisa menggantinya takeWhile(>0)dengan fst.span(>0). Jika Anda menggunakan pointfree, Anda dapat menjatuhkan nama f, jadi fungsi utama Anda adalah (++[0]) ... map fromEnum.
nimi
@nimi terima kasih, menjatuhkan nama memecahkan masalah inferensi tipe yang saya alami f.
Angs
Mengapa fromIntegral? Dari tantangan: "harus mendukung ... hingga 63 bit ... atau batas bahasa Anda", jadi Intharus baik-baik saja. Jika Anda ingin menyimpannya, pindahkan ke map, yaitu versi lama foldl1dan map(fromIntegral.fromEnum).
nimi
@nimi OP memposting komentar di sini (sejak dihapus), menanyakan apakah ini mendukung 63 bit, jadi saya berasumsi bahwa itu adalah tujuannya. Mengalahkan saya.
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));
  • mencetak 0 setelah loop alih-alih nilai awal sebelum loop menyimpan 6 byte.
  • unpackbukannya str_splitmerender ord()usang -> -3 byte
  • garis bawah _saat pemisah menyelamatkan 3.
  • bindecalih-alih ltrimmenghapus nol terkemuka: -12
  • echodi loop body menghemat 1 byte printdi loop head.
Titus
sumber
Tidak $n=$n*256+$i;for(print$n;$n;)dapat ditulis sebagai for(print$n=$n*256+$i;$n;)? Karena bagian penugasan akan dieksekusi sekali, ini harusnya berhasil. Dan alih-alih echo _.$n=[...], Anda harus menggunakannya echo _,$n=[...]. Itu tidak akan menyimpan byte apa pun, tetapi akan mempercepat kode sedikit sangat kecil dan akan memisahkan pernyataan. Itu berarti bahwa, misalnya, echo _,$a?5:6;dapat ditulis alih-alih echo _.($a?5:6);. Ini mungkin membantu di masa depan.
Ismael Miguel
@IsmaelMiguel Bagian penugasan adalah sebuah loop. Saya benar-benar menggunakan koma ketika saya tidak membutuhkan titik; itu adalah sisa dari printdalam kasus ini. Sendiri tidak layak diedit; tapi terima kasih
Titus
Oh, benar ... Itu ada di dalam foreach(unpack("C*",$argv[1])as$i)... Konyol saya ... Dan ya, mengubah periode untuk koma untuk memiliki efek yang sama tidak sepadan dengan masalahnya.
Ismael Miguel
4

Perl, 65 byte

53 byte kode + 12 untuk -Mbigint -p.

Terima kasih kepada @ Dada karena telah menyelamatkan saya 13 byte!

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

Pendekatan yang cukup mudah, hanya berbeda dengan sebagian besar dari ini adalah bahwa angka disimpan sebagai biner dan dicetak dalam desimal. Saya yakin ini bisa diperbaiki, mungkin dengan menyimpan detail dalam sebuah array. -Mbigintagak tidak nyaman tetapi perlu.

Pemakaian

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
Dom Hastings
sumber
1
Bongkar teman saya, bongkar! perl -Mbigint -lpE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'(Saya tidak tahu cara menggunakan unpack biasanya, saya hanya beruntung ketika googling cara mengkonversi string ke biner ;-))
Dada
Ahhh, aku selalu lupa tentang unpacksintaks yang selalu meledakkan pikiranku! Saya akan memperbarui, terima kasih!
Dom Hastings
Ada perlpacktut yang seharusnya membantu ... Saya sudah membaca 10 baris pertama, tapi saya harus meluangkan waktu untuk membaca sisanya!
Dada
@Dada saya yakin saya telah membacanya berkali-kali, hanya saja tidak pernah tinggal di ... Terima kasih lagi -13 bukan prestasi kecil! Saya harus beralih ke echo -nsatu-satunya perubahan lain.
Dom Hastings
4

Pyth, 12 byte

.usi!MjN2 2C

Program yang mengambil input dari string yang dikutip dan mencetak hasilnya sebagai daftar bilangan bulat.

Verifikasi semua kasus uji

Bagaimana itu bekerja

.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
TheBikingViking
sumber
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)

Gagasan utamanya adalah mengubah string menjadi byte ke angka. Setiap iterasi mencetak output dan XOR dengan semua 1s untuk maju ke nol.

Jimmy Johnson
sumber
Anda tidak perlu ada tanda kurung 2**x.bit_length()-1. Urutan operasi untuk daya dan pengurangan lebih tinggi dari xor. Juga, itu whilebisa dalam satu baris.
mbomb007
Tulis loop sementara pada satu baris (hapus baris baru dan
lekukan
Cobalah memulai program dengan P=printdan kemudian gunakan P()sebagai gantinyaprint()
Cyoce
3

Python 2, 117 115 byte

Menyimpan 2 byte berkat Cyoce.

Asumsikan input terlampir dalam tanda kutip, mis "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

mmenghitung hingga digit tertinggi, demikian m-1juga topeng XOR untuk melakukan operasi yang diinginkan. Bagian terpanjang adalah mengubah input menjadi urutan bit awal.

Contoh:

"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
Karl Napf
sumber
Anda dapat mengganti -i-1dengan~i
Cyoce
3

Ruby, 104 101 100 81 80 65 byte

19 byte disimpan berkat @WayneConrad!
15 Bytes disimpan berkat @philomory!
1 byte disimpan berkat @LeeW!

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

Mengambil input melalui argumen baris perintah.

Terinspirasi oleh jawaban Python @ Jimmy Johnson

Cyoce
sumber
Anda mungkin dapat menyimpan beberapa karakter dengan menggantinya i.to_s(2).rjust 8,'0'dengan"%08b"%i
Wayne Conrad
Juga, saya pikir inject(:+)dapat digantikan denganjoin
Wayne Conrad
@WayneConrad terima kasih atas bantuannya! Tidak yakin bagaimana saya lupa tentang itu
Cyoce
Senang bisa membantu! Terima kasih telah mengajari saya metode #bit_length, yang tidak saya ketahui.
Wayne Conrad
1
Beralih ke unpackdiikuti oleh [0]daripada mengacaukan gsubakan menghemat 11 byte. Beralih ke $*[0]alih-alih gets.chop(menggunakan argumen baris perintah alih-alih input konsol) akan menyimpan 9 lainnya, baris pertama menjadi p n=$*[0].unpack('B*')[0].to_i(2).
philomory
3

Labirin , 104 103 byte

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

Cobalah secara Online!

Penjelasan:

Gambar kode warna dari kode sumber

Instruksi penunjuk dimulai pada karakter paling non-dinding paling kiri atas (dinding menyertakan spasi dan huruf apa pun kecuali v).

Jeruk:

Loop ini mendapatkan input satu karakter sekaligus sebagai kode ASCII, menambahkannya ke nilai saat ini dan mengalikan nilai saat ini dengan 256.

  • ' Tanpa op
  • ,Dorong kode ascii dari input char berikutnya ke atas stack atau -1 jika EOF. Pada titik ini jika input diterima, kode akan berbelok ke kanan (bergerak ke bawah) karena bagian atas tumpukan adalah potive. Kalau tidak, ia akan berbelok ke kiri karena bagian atas tumpukan negatif.
  • | Keluarkan dua item teratas dari tumpukan dan dorong hasil bitwise OR.
  • _ Tekan nol
  • 256Setiap digit terlihat muncul xdan didorong x*10+digit. Jadi ini dikombinasikan dengan push nol sebelumnya push 256 ke atas tumpukan.
  • *Pop y, pop x, push x*y. Pada titik ini karena bagian atas tumpukan positif, kode akan berbelok ke kanan untuk melanjutkan di sekitar loop.

Biru:

  • )Tambahkan bagian atas tumpukan. Ketika akhir input tercapai, kode akan berbelok ke kiri untuk sampai ke titik ini dengan -1 pada stack yang akan bertambah menjadi nol.
  • 256 Memiliki bagian atas tumpukan 0 memungkinkan kita untuk mendorong 256 ini.
  • /Pop y, pop xpush x/y(pembagian integer). Karena kita mengalikan input dengan 256 setiap loop, kita perlu mengembalikan perkalian terakhir.
  • : Gandakan bagian atas tumpukan sehingga kami memiliki salinan nilai saat ini untuk nanti.
  • ! Pop bagian atas tumpukan dan cetak nilai integer ke STDOUT.
  • \ Cetak baris baru.
  • _2 Dorong dua ke atas tumpukan.
  • } Pindahkan bagian atas tumpukan ke bagian atas tumpukan tambahan.

Merah:

Loop ini membalik bit dari nilai saat ini dengan XOR dengan nilai tertentu yang dihitung dalam loop (hijau). Kemudian output nilai saat ini dan keluar dari program jika nilai saat ini adalah nol.

  • _ Tekan nol (aliran kontrol).
  • ; Buang bagian atas tumpukan (aliran kontrol).
  • :Gandakan nilai saat ini. Salinan akan digunakan untuk menghitung XOR.
  • _ Tekan nol (aliran kontrol).
  • (Lingkaran hijau)
  • $Pop y, pop x, Push x XOR y.
  • :! Gandakan nilai saat ini dan cetak representasi integer.
  • Jika nilai saat ini adalah 0, kami melanjutkan langsung ke @dan berakhir.
  • \ Cetak baris baru.
  • _2} Tekan 2 dan pindah ke tumpukan aux.
  • _1 Tekan 1 (aliran kontrol).

Hijau:

Loop ini menghitung nilai yang kita perlukan untuk XOR nilai saat ini. Hal ini dilakukan dengan berulang kali menggandakan bagian atas tumpukan pembantu sambil membagi dua salinan nilai saat ini pada pemberhentian tumpukan utama hingga mencapai 0.

  • _ Tekan nol (aliran kontrol).
  • ; Buang nilai saat ini yang hanya digunakan untuk menegakkan aliran kontrol.
  • _2 Tekan 2 untuk membagi dua nilai saat ini.
  • / Membagi
  • { Pindahkan bagian atas tumpukan aux ke bagian atas tumpukan utama.
  • _2* Gandakan bagian atas tumpukan
  • } Pindahkan bagian atas tumpukan utama kembali ke tumpukan aux.
  • _1 Dorong satu untuk aliran kontrol.
  • Setelah keluar dari loop:
  • ; Buang yang tersisa dari nol dari menghitung XOR.
  • { Pindahkan XOR yang dihitung ke tumpukan utama.
  • ( Kurangi satu dari nilai XOR.
Robert Hickman
sumber
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}

Ya, jadi, mengonversi pangkalan di PowerShell benar-benar sial . Dan kita bisa melakukannya dua kali di sini.

OK, jadi ini hanya forloop on $a- yaitu, kita loop selama $aada. Kami akhirnya akan mencapai string kosong (yang merupakan falsey), jadi itulah cara kami akan mengakhiri.

Pengaturan loop,, $a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)})mengambil input $args[0], melemparkannya sebagai char-array, dan loop melalui masing-masing karakter. Kami menggunakan .NET [convert]::ToString(int,base)untuk mengonversi masing-masing menjadi string biner. Namun, itu tidak termasuk angka nol terkemuka, jadi kita perlu re-cast string sebagai [int]dan memanggil nya .ToString() metode dengan 8nol sebagai masker. Kemudian string tersebut dienkapsulasi dalam parens dan diedit -joinbersama, lalu disimpan ke dalam $a.

Di dalam loop, kita [convert]::ToInt64(string,base)mengkonversi angka biner ke angka desimal. Yang tersisa di pipa dan kemudian memerah ketika loop ulang (dan karena itu dicetak secara implisit). Bagian selanjutnya melakukan perhitungan - kita .TrimStart()menghapus nol di depan, -split0untuk membagi nol dan mendapatkan string-array 1s, -replaceyang dengan nol, dan akhirnya -joinarray kembali bersama dengan 1s. Kemudian, loop dimulai lagi.

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
AdmBorkBork
sumber
2

CJam , 17 16 18 byte

q256b0{_p2b:!2bj}j

Cobalah online!

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

CATATAN: Versi 16 byte yang lama tidak berperilaku benar dengan string kosong:

q256b{_p2b:!2b}h

Juga, terima kasih kepada Dennis untuk menyarankan pyang menghemat 1 byte dari N\menempatkan baris baru ke dalam tumpukan.

Linus
sumber
_p2b:!2bmenghemat satu byte. Anda juga harus menggunakan l; rakan gagal jika input berisi spasi.
Dennis
@ Dennis Terima kasih, meskipun ini sekarang membuat saya khawatir jika string kosong adalah masalah.
Linus
Baik. qakan bekerja dengan benar dengan string kosong.
Dennis
2

J, 24 byte

256-.&.#:^:*^:a:@#.a.&i.

Penjelasan akan datang nanti!

Olius
sumber
2
Selamat datang di PPCG! Permalink untuk yang tertarik: Coba online!
Dennis
1

Retina, 116 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1. Baris 5 berisi byte yang tidak dapat dicetak. Ini 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

Cobalah online

Jangan coba ini dengan input lebih dari dua karakter. (Ini habis menggunakan penerjemah online.) Kita harus mengonversi biner menjadi unary sebelum desimal. : D

Sayangnya, ada nol di belakang dan linefeed, tapi saya memutuskan untuk menganggap itu baik-baik saja karena output masih benar.

Penjelasan

-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)
mbomb007
sumber
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>'

Program keluar dengan pengecualian setelah selesai, tetapi pemahaman saya adalah bahwa itu baik-baik saja selama output kesalahan pergi ke STDERR daripada STDOUT (yang memang).

philomory
sumber
1

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

Disimpan 5 byte berkat @Cyoce!

Disimpan 2 byte berkat @Cyoce dan @cleblanc!

Disimpan 12 byte berkat @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;}

Tidak Disatukan:

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 */
    }
}
Mie9
sumber
Saya pikir Anda dapat meninggalkan intdeklarasi
Cyoce
Anda juga dapat menyimpan byte dengan mengubah whileloop terakhir menjadi forloop
Cyoce
Dan Anda dapat mengubah while(1)kefor(;;)
Cyoce
@Cyoce Saya mencoba menghapus intdeklarasi di mana-mana dan mendapat gcc -std=89kesalahan. Tapi terima kasih atas for(;;)tipnya. Saya akan terus berusaha menghapus intdeklarasi :)))
Noodle9
maaf, saya tidak mengujinya. Saya pikir ini akan berhasil jika Anda memindahkannya ke atas ( i;main(c,v)char**v;{...}). Di ponsel sekarang juga, jadi saya tidak yakin
Cyoce
0

C, 129 120 117 110 107 105 Bytes

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

Diuji dengan

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

keluaran

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,
Cleblanc
sumber
Saya pikir Anda dapat pindah i=0ke deklarasi idan biarkan bagian inisialisasi forloop kosong
Cyoce
@Cyoce Fungsi perlu bekerja setiap kali dipanggil dan karena iglobal int implisit, ia perlu diinisialisasi setiap kali f (...) dipanggil.
Cleblanc
@Cyoce Anda benar setelah semua. Fungsi tidak keluar sampai inol lagi sehingga masih dapat digunakan kembali.
cleblanc
102 byte
ceilingcat
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());}};

Program lengkap:

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
    }
}
Yodle
sumber
Saya tidak melakukan C #, tapi bisa var t="";var f="";menjadi var t="",f=""sebaliknya? Menghemat 5 byte.
corsiKa
@corsiKa Ya saya mencobanya tetapi itu memberi saya kesalahan, saya kira karena itu var dan bukan string.
Yodle
Sebenarnya, string memang menghemat satu byte, jadi saya kira saya akan melakukannya dengan cara itu.
Yodle
Dapatkah Anda membuat variabel az menjadi nol untuk menyimpan kutipan-kutipan jahat itu?
corsiKa
Baru saja mencoba, ini benar-benar meningkatkan bytecount karena saya tidak dapat mengganti kedua string "0" dan char '0' :(
Yodle