“Sonsuzluk” dan sayın


47

İmkansız bir görev gibi görünüyor değil mi? Aslında o kadar da zor değil. Eğer kelimeyi Infinity8-bit ikili ASCII kodu olarak yazarsak, şunu alırız:

01001001 01101110 01100110 01101001 01101110 01101001 01110100 01111001

Bu birleştirilebilir ve ondalık değere dönüştürülebilir 5291279215216915577. İşte bu çalışabileceğimiz bir rakam.

Geri saymanın yolu:

  1. Orijinal dizgeyi ondalık sayı olarak çıkarın (yukarıda gösterildiği gibi)
  2. Önde gelen 0'ları ikili gösteriminde (varsa) kaldırın.
  3. İkili gösterimdeki bitleri değiştirin (1-> 0, 0-> 1)
  4. Sayıyı ondalık olarak yazdır
  5. 0'a ulaşana kadar 2-4. Adımları tekrarlayın.

Meydan okuma:

Girdi olarak bir dize alan bir program veya işlev oluşturun ve yukarıdaki prosedürü gerçekleştirirken elde edeceğiniz sayıları çıkarır (uygun herhangi bir formatta).

Test durumu:

Sadece bir test olayı olmasına rağmen mücadelenin anlaşılmasının oldukça kolay olacağını düşünüyorum. Ben kullanacağız Infyerine Infinitybu oldukça kısa tutmaya.

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

Kodunuz, dil sınırınıza kadar bir ikili sayı olarak temsil edilebilecek dizeleri desteklemelidir. Tüm dizeler yalnızca 32-126 (boşluktan tilde) kadar yazdırılabilir ASCII karakterleri içerecektir.


Liderler Sıralaması


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

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

5
@LuisMendo Jon Skeet'i kastetmediğinizden emin misiniz ?
mbomb007

Yanıtlar:


12

Jöle , 15 10 bayt

@Dennis sayesinde -5 bayt (sıralı dökümden sonra doğrudan 256 tabanından dönüştürün)

Oḅ⁹µBCḄµÐĿ

TryItOnline!

Nasıl?

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
İlk kısım sadece Oḅ⁹.
Dennis

Oh, bunu nasıl özledim?
Jonathan Allan

11

Python 2, 89 82 77 76 75 bayt

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

İdeone üzerinde test et .

Nasıl çalışır

Başlatılırken sonra , n için 0 , ikinci hat gerçekleştirir dize kadar-tamsayı dönüşüm aşağıdaki gibi zorlukları belirtilmiş.

Her aşamada, N kaydırılır 8 daha sonra bitsel sola birimleri VEYA sonraki karakter kodu noktası ile -ed c . Inf girişi için bu, aşağıdaki gibi gider.

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

Şimdi çıktıyı oluşturmaya hazırız. N bitlerini ters çevirmek için aşağıdaki şekilde ilerleriz.

İlk önce bitleri n 'nin ikili gösteriminde, baştaki sıfır olmadan hesaplarız . Sonuca k diyelim . Daha sonra, k + 1 ikili hanesine sahip olan 2 k k gücünü hesaplarız : tek bir 1 , ardından k 0 's. Bu çıkarma 1 oluşan bir dizi, sonuçta sonucundan k biz, daha sonra XOR olanlar, n kendi bit ters. İnf girişi için bu şu şekildedir.

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

Uygulanmasında ek engel biz yazdırmak zorunda olmasıdır n , ilk adımdan önce sonra son adım, ve aradaki tüm adımlarda. Python'da süre döngüleri yoktur ve tek bir baskı ifadesinin maliyeti 8 bayttır, bu nedenle aşağıdakileri yaparız.

Güncelleme adımının basit bir uygulamasında, yani,

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

Sonsuz bir bir (döngüyü yerine while 1) ve hesaplamak 1olarak döngüde n/n. Bu, n> 0 iken eşdeğerdir .

Bir kez n = 0 güncellemek için deneyin, biz çemberinde kalın bir kez daha devlet yazdırın. Ancak, 0/0bir ZeroDivisionError'ı tetikler , döngüden ayrılır ve bir hatayla çıkar. Bunun, varsayılan olarak izin verilen STDERR'de başıboş çıktılara neden olduğunu unutmayın .


2
Bu -n/nnumaraya bayılıyorum :-)
ETHproductions

n/nHile yapmaktan daha fazla açıklayabilir misin ? Muhtemelen başka bir yerde başka bir cevapta açıklanmıştı ama bulamadım. Burada ne işe yarıyor?
Stewie Griffin,

@StewieGriffin n / n, 0 olana kadar 1, sonra bir hata atar ve programın durmasına neden olur.
jazzpi,

Bir hata mesajı ile (umarım)?
Stewie Griffin,

1
@StewieGriffin Gerçekten. Python, hata raporlama konusunda acı verici bir şekilde ayrıntılıdır. Bir açıklama eklemek için cevabımı düzenledim.
Dennis

8

JavaScript, 82 bayt

@Arnuald sayesinde bir bayt kaydedildi

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

Tam bir program bir işlevi geride bıraktığında çok az zamandan biri (ve ES6 ES5'ten daha iyi bir performans göstermez) ...


Yukarıdakiler 4 harfe kadar kelimeyi destekler. 6 harfe kadar kelimeyi desteklemek için 4 bayt ekleyin:

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

@Titus Teşekkürler! Bunu neden düşünmedim bilmiyorum
ETHproductions

n<<8|y.charCodeAt()bir bayt kaydetmelisiniz. for(;n;)for(i=!alert(n);i<=n;i*=2)n^=ibaşka bir bayttan tasarruf edersiniz, ancak 0muhtemelen gerekli olan gösterilmez.
Arnauld

@Arnauld Teşekkürler. Daha n<<8önce yapmayı düşündüm ama işe yaramayacağına karar verdim, çünkü 31'den fazla bit ile n için ayrılacaktı. Sanırım şimdiden bunu 31-bit bir versiyonla 53-bit bir versiyona ayırmamın bir önemi yok ... Ve ne yazık ki, ikisini de ilk önce uyarırken alarmdaki hiçbir şeyi saklayabileceğimi sanmıyorum. yineleme ve son.
ETHProductions

7

Aslında , 14 bayt

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

Çevrimiçi deneyin!

Açıklama:

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 bayt

CP-1252 kodlamasını kullanır .

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

Çevrimiçi deneyin!

açıklama

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

8W:qZA`tB~XBt

Çevrimiçi deneyin!

açıklama

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

Mathematica, 99 bayt

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

Anonim işlev Bir dizeyi girdi olarak alır ve sayı olarak çıktı olarak döndürür.


4

Haskell, 109 123 118 102 97 bayt

5 bayt kaydettiğin için @nimi teşekkürler!

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

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

Dile göre 29 bite kadar sayılar üzerinde çalışma garantisi, 64-bit sistemlerde genellikle 63-bit sayılar için çalışır. Kullanım map(fromIntegral.fromEnum)keyfi çok sayıda destek yerine (14 bayt).

Unicode aralığı için çalışıyor [0..255]. Özyinelemeli bitleri çevirir.


1
Sen yerini alabilir takeWhile(>0)ile fst.span(>0). Noktasızca giderseniz, adı silebilirsiniz f, yani ana işleviniz budur (++[0]) ... map fromEnum.
nimi

@ nimi teşekkürler, adı bırakmak, sahip olduğum tip çıkarım sorununu çözdü f.
Angs

Neden fromIntegral? Zorluktan: "en fazla 63 bit ... veya dilinizin sınırını desteklemeli" olmalı, bu yüzden iyi Intolmalı. Bunu tutmak istiyorsanız, taşımak maparasında yani eski sürüm foldl1ve map(fromIntegral.fromEnum).
nimi

@nimi OP burada (silindiğinden beri) bir yorum yayınladı, 63 bit destekleyip desteklemediğini sordu, ben de onun niyetinin olduğunu varsaydım. Beni aşar.
Angs

4

PHP, 132 126 123 120 108 107 bayt

foreach(unpack("C*",$argv[1])as$i)$n=$n*256+$i;for(print$n;$n;)echo _.$n=bindec(strtr(decbin($n),"01",10));
  • Döngüden sonra 0 basıldığında, döngü 6 bayttan önce başlangıç ​​değeri yerine yazdırılır.
  • unpackstr_splitRender yerine ord()eski -> -3 bayt
  • _ayırıcı olarak alt çizgi 3 kaydeder.
  • bindecltrimBaştaki sıfırları kaldırmak yerine : -12
  • echodöngü gövdesinde printdöngü kafasında 1 byte tasarruf sağlar .

Can $n=$n*256+$i;for(print$n;$n;)olarak yazılabilir for(print$n=$n*256+$i;$n;)? Atama bölümü bir kez yürütüldüğünden, bu çalışması gerekir. Ve onun yerine echo _.$n=[...], onu kullanmalısın echo _,$n=[...]. Herhangi bir byte'ı kurtarmaz, ancak kodu küçük bir minik minik minik bit hızlandıracak ve ifadeleri ayıracaktır. Bu, örneğin, echo _,$a?5:6;yerine yazılabileceği anlamına gelir echo _.($a?5:6);. Bu gelecekte yardımcı olabilir.
Ismael Miguel

@ IsmaelMiguel Atama kısmı bir döngüdür. Noktaya ihtiyaç duymadığımda virgül kullanıyorum; printBu durumda gelen bir kalıntıdır . Yalnız bir düzenlemeye değmez; ama teşekkürler.
Titus

Ah, doğru ... İçinde foreach(unpack("C*",$argv[1])as$i)... Aptal ben ... Ve evet, virgül için aynı etkiye sahip bir dönem değiştirmek sorun değil.
Ismael Miguel

4

Perl, 65 bayt

İçin 53 bayt kodu + 12 -Mbigint -p.

Beni 13 bayttan kurtardığı için @ Dada'ya teşekkürler !

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

Oldukça basit bir yaklaşım, bunların çoğundan farklı olarak, sayının ikili olarak depolanması ve ondalık biçimde yazdırılmasıdır. Bir dizide ayrıntıları depolamakla belki de daha iyi olacağına eminim. -Mbigintbiraz uygunsuz ama gerekli.

kullanım

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
Arkadaşımı aç, aç! perl -Mbigint -lpE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'(Ben nasıl kullanılacağını bilmiyorum paketten ikili ;-) bir dize dönüştürmek için nasıl Googling zaman genellikle, sadece şanslıyım)
Dada

Ahhh, unpacksözdizimini hep unutuyorum hep aklımı başımdan alır! Güncelleyeceğim, teşekkür ederim!
Dom Hastings

Orada perlpacktut o yardımcı olmalıdır ... Ben zamanın ilk 10 satır onlarca okudum, ama gerçekten geri kalanını okumak için zaman almalıdır!
Dada

@Dada Bir çok kez okuduğuma eminim, asla içeri girmiyor ... Teşekkürler -13 küçük bir başarı değil! Geçmem gereken echo -ntek değişiklik oldu.
Dom Hastings,

4

Pyth, 12 bayt

.usi!MjN2 2C

Alıntı yapılan bir dizenin girişini alan ve sonucu bir tamsayı listesi olarak basan bir program.

Tüm test durumlarını doğrulayın

Nasıl çalışır

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

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

Ana fikir, dizgiyi bayttan sayıya dönüştürmektir. Her yineleme, sıfıra doğru ilerlemek için çıkışı ve XOR'yu tüm 1'lerle yazdırır.


Etrafında parantez gerekmez 2**x.bit_length()-1. Güç ve çıkarma işlemlerinin sırası, xor'dan yüksektir. Ayrıca, bu whiletek bir satırda olabilir.
mbomb007

While döngüsünü bir satıra yazın (yeni çizgiyi kaldırın ve girinti)
FlipTack

Programı başlatmayı P=printve sonra kullanmayı deneyinP()print()
Cyoce

3

Python 2, 117 115 bayt

Cyoce sayesinde 2 byte tasarrufu.

Örneğin tırnak içine alınmış girdiyi varsayar; "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

men yüksek haneye kadar sayar, bu nedenle m-1istenen işlemi gerçekleştirmek için bir XOR maskesidir. En uzun bölüm girişi ilk bit dizisine dönüştürmektir.

Örnek:

"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

Sen yerini alabilir -i-1ile~i
Cyoce

3

Ruby, 104 101 100 81 80 65 bayt

@WayneConrad sayesinde 19 bayt kaydedildi!
@Philomory sayesinde 15 bayt kurtarıldı!
@LeeW sayesinde 1 bayt kurtarıldı!

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

Komut satırı argümanları ile girdi alır.

@ JimmyJohnson'un Python yanıtından ilham alındı


Sen değiştirerek birkaç karakter kaydetmek mümkün olabilir i.to_s(2).rjust 8,'0'ile"%08b"%i
Wayne Conrad

Ayrıca, bence inject(:+)değiştirilebilirjoin
Wayne Conrad

@WayneConrad yardımın için teşekkürler! Bunları nasıl unuttuğumdan emin değilim
Cyoce

Yardımcı olduğuma sevindim! Bana bilmediğim # bit_length yöntemini öğrettiğiniz için teşekkür ederiz.
Wayne Conrad,

1
İle uğraşmak yerine unpackbunu takip etmek 11 bayt kazandırır. Bunun yerine geçmek (konsol girişi yerine bir komut satırı argümanı kullanarak) bir 9 daha kaydedecektir, ilk satır olur . [0]gsub$*[0]gets.chopp n=$*[0].unpack('B*')[0].to_i(2)
Philomory

3

Labirent , 104 103 bayt

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

Çevrimiçi Deneyin!

Açıklama:

Kaynak kodun renk kodlu görüntüsü

Komut göstericisi, duvarın en solundaki en üstte başlar (duvarlar boşluklar ve harf hariç v).

Portakal:

Bu döngü girişe ASCII kodu olarak her seferinde bir karakter alır, onu geçerli değere ekler ve mevcut değeri 256 ile çarpar.

  • ' Hayır-op
  • ,Bir sonraki giriş karakterinin ascii kodunu yığının en üstüne veya EOF ise -1'e basın. Girdi alınmışsa, bu noktada kod yığının tepesi diri olduğu için sağa döner (aşağıya doğru). Aksi halde, yığının üstü negatif olduğundan sola döner.
  • | En üstteki iki öğeyi yığından çıkarın ve bit yönünde bir OR sonucunu itin.
  • _ Sıfırla
  • 256Görülen her hane açılır xve iter x*10+digit. Böylece bu, önceki sıfırlama 256 ile istifin tepesine itme ile birleştirilir.
  • *Pop y, pop x, it x*y. Bu noktada, yığının tepesi pozitif olduğundan kod, döngünün etrafında devam etmek için sağa döner.

Mavi:

  • )Yığının tepesini arttırın. Girişin sonuna gelindiğinde kod bu noktaya ulaşmak için sola dönecek ve yığında -1 ile artacaktır.
  • 256 0 yığınının tepesine sahip olmak, bu 256'yı itmemize izin veriyor.
  • /Pop y, pop- xpush x/y(tamsayı bölümü). Girdiyi her döngü için 256 ile çarptığımızdan, son çarpımı geri almamız gerekiyor.
  • : Yığının tepesini çoğaltın, o zaman için geçerli değerin bir kopyasını alalım.
  • ! Yığının tepesini açın ve tamsayı değerini STDOUT'a yazdırın.
  • \ Yeni bir satır yazdır.
  • _2 Yığının üstüne iki tane itin.
  • } Yığının tepesini yardımcı yığının üstüne getirin.

Kırmızı:

Bu döngü, mevcut değerin bitlerini, iç (yeşil) döngüde hesaplanan belirli bir değerle XOR'a çevirir. Daha sonra akım değerini çıkarır ve mevcut değer sıfır ise programdan çıkar.

  • _ Sıfıra (kontrol akışı) basın.
  • ; Yığının üstünü atın (kontrol akışı).
  • :Geçerli değeri çoğalt. Kopya, XOR'u hesaplamak için kullanılacaktır.
  • _ Sıfıra (kontrol akışı) basın.
  • (Yeşil döngü)
  • $Pop y, pop x, it x XOR y.
  • :! Geçerli değeri çoğaltın ve tamsayı gösterimini yazdırın.
  • Mevcut değer 0 ise, doğrudan devam @edip sonlandırırız.
  • \ Yeni bir satır yazdır.
  • _2} 2'ye basın ve yardımcı yığına geçin.
  • _1 1 (kontrol akışı) düğmesine basın.

Yeşil:

Bu döngü, mevcut değeri XOR olarak koymamız gereken değeri hesaplar. Bu, yardımcı yığının tepesini iki katına çıkarırken, ana yığının durağındaki mevcut değerin bir kopyasını 0'a ulaşana kadar yarıya indirmek suretiyle yapılır.

  • _ Sıfıra (kontrol akışı) basın.
  • ; Yalnızca kontrol akışını zorlamak için kullanılan mevcut değeri atın.
  • _2 Mevcut değeri yarıya indirmek için 2 düğmesine basın.
  • / bölmek
  • { Yardımcı yığının tepesini ana yığının üstüne getirin.
  • _2* Yığının üstünü iki katına
  • } Ana yığının üstünü tekrar yardımcı yığına getirin.
  • _1 Kontrol akışı için bir tane basın.
  • Döngüden çıktıktan sonra:
  • ; XOR'u hesaplamak için soldan sıfırı atın.
  • { Hesaplanan XOR'ı ana yığına taşıyın.
  • ( XOR değerinden bir tane çıkarın.

2

PowerShell v2 +, 158 bayt

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}

Evet, bu yüzden PowerShell'deki üsleri dönüştürmek gerçekten çok berbat . Ve burada iki kez yapalım.

Tamam, yani bu sadece bir fordöngü $a- yani, $avar olduğu sürece döngü yapıyoruz . Sonunda boş bir dizgeye (falsey) ulaşacağız, bu yüzden sonlandırıyoruz.

Döngünün kurulumu $a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)})girdiyi alır, $args[0]onu bir chardizi olarak atar ve her karakter boyunca döner. [convert]::ToString(int,base)Her birini bir ikili dizeye dönüştürmek için .NET'i kullanırız. Ancak, baştaki sıfırları içermez, bu yüzden yeniden döküm bir şekilde bu dizeyi ihtiyaç [int]ve çağrı onun .ToString() yöntemi ile 8maske olarak sıfır. Sonra bu dizeler parantez içine alınır ve -joinbirlikte sıralanır , sonra kaydedilir $a.

Döngünün içinde, [convert]::ToInt64(string,base)ikili sayıyı ondalık sayıya dönüştürürüz. Bu boru hattında kalır ve daha sonra ilmek sıfırlandığında (ve dolayısıyla dolaylı olarak yazdırılır) temizlenir. Bir sonraki bölüm hesaplamaları yapar - .TrimStart()herhangi -split0bir stringbaştaki sıfırları çıkarırız , sıfırlara ayrılır ve bir- 1s dizisi alırız, -replacesıfır olanları ve son -joinolarak da 1s ile tekrar bir araya geliriz . Ardından, döngü tekrar başlar.

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 bayt

q256b0{_p2b:!2bj}j

Çevrimiçi deneyin!

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

Not: Eski 16 bayt sürümü boş dizelerle doğru şekilde davranmadı:

q256b{_p2b:!2b}h

Ayrıca Dennis'e , phangisinin N\yeni satırları yığına koyarken 1 bayt kazandırdığını önerdiği için teşekkür ederiz .


_p2b:!2bbir bayt kaydeder. Ayrıca, kullanmanız gerekir l; rgiriş boşluk içeriyorsa başarısız olur.
Dennis

@Dennis Teşekkürler, bu şimdi boş bir dize bir sorun ise beni endişelendiriyor.
Linus

Sağ. qboş dizelerle doğru çalışacaktır.
Dennis


1

Retina, 116 bayt

Bayt sayısı, ISO 8859-1 kodlamasını varsayar. 5. satırda yazdırılamayan bayt var. Bu 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

Çevrimiçi deneyin

Bunu iki karakterden uzun girişle denemeyin. (Çevrimiçi tercümanı kullanarak zaman aşımına uğradı.) Ondalıktan önce ikili dosyayı birliğe çevirmeliyiz. : D

Ne yazık ki, takip eden bir sıfır var ve satır besleme, ancak bunun doğru olduğunu kabul etmeye karar verdim çünkü çıktı hala doğru.

açıklama

-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

Yakut - 70 bayt

λ 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 tamamlandıktan sonra bir istisna ile çıkıyor, ancak benim anladığım kadarıyla, hata çıktısı STDOUT (ki yapıyor) yerine STDERR'e gittiği sürece sorun değil.


1

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

@Cyoce sayesinde 5 bayt kaydedildi!

@Cyoce ve @cleblanc sayesinde 2 bayt kaydedildi!

@Ceilingcat sayesinde 12 bayt kaydedildi

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

Bence intbildirimleri bırakabilirsin
Cyoce

Son whiledöngüyü bir fordöngüye dönüştürerek bir bayt da kaydedebilirsiniz
Cyoce

Ve değiştirebileceğiniz while(1)içinfor(;;)
Cyoce

@Cyoce Her intyerde bildirimleri kaldırmayı denedim ve gcc -std=89hatalar aldım . Ama for(;;)bahşiş için teşekkürler . intBildirimleri kaldırmak için çalışmaya devam edeceğim :)))
Noodle9

üzgünüm test etmedim. Onları en üste çıkarırsanız işe yarayacağını düşünüyorum ( i;main(c,v)char**v;{...}). Şu anda mobil cihazda bu yüzden emin
olamıyorum

0

C, 129 120 117 110 107 105 Bayt

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

İle test edildi

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

çıktı

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,

Sanırım döngünün başlatma bölümünü boş bırakıp i=0bildirimini ibırakabilirsinfor
Cyoce

@Cyoce İşleve her çağrıldığında çalışması gerekir ve idolaylı olarak genel olduğundan , f (...) çağrıldığında başlatılması gerekir.
cleblanc

@Cyoce Sonuçta haklıydın. İşlev itekrar sıfır olana kadar çıkmaz , bu yüzden yine kullanılabilir.
cleblanc


0

C #, 360 359 bayt

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

Tam program:

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 # yapmayın, ama var t="";var f="";olmak var t="",f=""yerine? 5 bayt kazandırır.
corsiKa

@corsiKa Evet Denedim ama bana bir hata verdi, sanırım var ve dize değil.
Yodle,

Aslında, dize bir bayt kurtarıyor, bu yüzden sanırım böyle yapacağım.
Yodle,

Ayrıca, bu kötü tırnakları kurtarmak için sıfır değişkeni için az değişken yapabilir misiniz?
corsiKa

Ben dize "0" ve karakter '0' :( hem yerini alamaz çünkü sadece denenmiş, aslında ByteCount yükseltir
Yodle
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.