Odliczanie od „Infinity”


47

Wydaje się, że to niemożliwe zadanie, prawda? Cóż, to wcale nie jest takie trudne. Jeśli napiszemy to słowo Infinityjako 8-bitowy binarny kod ASCII, otrzymamy:

01001001 01101110 01100110 01101001 01101110 01101001 01110100 01111001

Można to połączyć i przekonwertować na wartość dziesiętną 5291279215216915577. To liczba, z którą możemy pracować ...

Sposób, w jaki odliczasz to:

  1. Wyprowadza oryginalny ciąg jako liczbę dziesiętną (jak pokazano powyżej)
  2. Usuń wiodące zera z reprezentacji binarnej (jeśli istnieje)
  3. Przełącz bity w reprezentacji binarnej (1-> 0, 0-> 1)
  4. Podaj liczbę dziesiętną
  5. Powtarzaj kroki 2–4, dopóki nie osiągniesz 0.

Wyzwanie:

Utwórz program lub funkcję, która pobiera ciąg znaków jako dane wejściowe i wyświetla (w dowolnym odpowiednim formacie) liczby, które otrzymasz podczas wykonywania powyższej procedury.

Przypadek testowy:

Myślę, że wyzwanie będzie dość łatwe do zrozumienia, nawet jeśli jest to tylko jeden przypadek testowy. Użyję Infzamiast tego, Infinityaby to dość krótko.

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

Twój kod musi obsługiwać ciągi znaków, które mogą być reprezentowane jako liczba binarna do limitu Twojego języka. Wszystkie ciągi będą zawierać tylko drukowalne znaki ASCII od 32-126 (spacja do tyldy).


Tabela liderów


31
Chuck Norris , 8 bajtów:Inf:-1:0
Luis Mendo

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

5
@LuisMendo Czy na pewno nie masz na myśli Jona Skeeta ?
mbomb007

Odpowiedzi:


12

Galaretka , 15 10 bajtów

-5 bajtów dzięki @Dennis (konwersja bezpośrednio z bazy 256 po rzucie porządkowym)

Oḅ⁹µBCḄµÐĿ

TryItOnline!

W jaki sposób?

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
Pierwsza część jest po prostu Oḅ⁹.
Dennis

O rany, jak mi tego brakowało ?!
Jonathan Allan

11

Python 2, 89 82 77 76 75 bajtów

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

Przetestuj na Ideone .

Jak to działa

Po zainicjowaniu n na 0 , drugi wiersz wykonuje konwersję ciągu na liczbę całkowitą określoną w wyzwaniach w następujący sposób.

W każdym kroku n przesuwa się o 8 jednostek w lewo, a następnie bitowo LUB - z kodem następnego znaku c . W przypadku wejścia Inf wygląda to następująco.

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

Teraz jesteśmy gotowi do wygenerowania wyniku. Aby odwrócić bity n , postępujemy w następujący sposób.

Najpierw obliczamy bity w reprezentacji binarnej n bez zer wiodących. Nazwijmy wynik k . Następnie obliczamy moc k k 2 , która ma k + 1 cyfr binarnych: pojedynczą 1 , po której następuje k 0 . Odejmujemy 1 od wyniku, otrzymując liczbę złożoną z k jedynek, którą następnie XOR z n, aby odwrócić jego bity. Dla wejścia inf wygląda to następująco.

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

Dodatkową przeszkodą we wdrożeniu jest to, że musimy wydrukować n przed pierwszym krokiem, po ostatnim kroku i we wszystkich krokach pomiędzy. Python nie ma pętli „do while”, a pojedyncza instrukcja drukowania kosztuje 8 bajtów, dlatego zamiast tego wykonujemy następujące czynności.

W prostej realizacji kroku aktualizacji, tj.

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

zamieniamy pętlę na nieskończoną ( while 1) i obliczamy 1w pętli jako n/n. Jest to równoważne, gdy n> 0 .

Gdy n = 0 , pozostajemy w pętli, drukujemy stan jeszcze raz, a następnie próbujemy go zaktualizować. Jednakże 0/0wyzwala ZeroDivisionError , zrywając z pętli oraz wychodzenia z błędem. Zauważ, że powoduje to rozproszenie danych wyjściowych do STDERR, co jest domyślnie dozwolone .


2
Uwielbiam tę -n/nsztuczkę :-)
ETHproductions

Czy potrafisz wyjaśnić niż n/npodstęp? Prawdopodobnie zostało to wyjaśnione gdzieś w innej odpowiedzi, ale jej nie znalazłem. Co on tu robi?
Stewie Griffin

@StewieGriffin n / n ma wartość 1, dopóki n nie wynosi 0, a następnie zgłasza błąd i powoduje zatrzymanie programu.
jazzpi

Z komunikatem o błędzie (mam nadzieję)?
Stewie Griffin

1
@StewieGriffin Rzeczywiście. Python jest boleśnie gadatliwy, jeśli chodzi o raportowanie błędów. Zredagowałem swoją odpowiedź, aby dołączyć wyjaśnienie.
Dennis

8

JavaScript, 82 bajty

Zapisano bajt dzięki @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

Jeden z niewielu razy, kiedy pełny program przewyższa funkcję (a ES6 nie przewyższa ES5) ...


Powyższe obsługuje do 4 liter. Dodaj 4 bajty, aby obsługiwać do 6 liter:

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)
Tytus

@Titus Thanks! Nie jestem pewien, dlaczego o tym nie pomyślałem
ETHproductions

n<<8|y.charCodeAt()powinien zapisać bajt. for(;n;)for(i=!alert(n);i<=n;i*=2)n^=iuratuje kolejny bajt, ale nie wyświetlisz 0, co prawdopodobnie jest wymagane.
Arnauld

@Arnauld Thanks. Myślałem o zrobieniu tego n<<8wcześniej, ale zdecydowałem, że to nie zadziała, ponieważ złamie się dla n z więcej niż 31 bitami. Wydaje mi się, że teraz nie ma znaczenia, że ​​podzieliłem go już na wersję 31-bitową i 53-bitową ... I niestety, nie sądzę, żebym mógł zapisać cokolwiek na ostrzeżeniu, alarmując jednocześnie pierwszą iteracja i ostatnia.
ETHprodukcje

7

Właściwie 14 bajtów

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

Wypróbuj online!

Wyjaśnienie:

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 bajtów

Wykorzystuje kodowanie CP-1252 .

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

Wypróbuj online!

Wyjaśnienie

Ç                     # 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 bajtów

8W:qZA`tB~XBt

Wypróbuj online!

Wyjaśnienie

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 bajtów

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

Funkcja anonimowa. Pobiera ciąg znaków jako dane wejściowe i zwraca listę liczb jako dane wyjściowe.


4

Haskell, 109 123 118 102 97 bajtów

Dzięki @nimi za uratowanie 5 bajtów!

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

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

Gwarantowane działanie na liczbach do 29 bitów według języka, zwykle działa na liczbach 63-bitowych w systemach 64-bitowych. map(fromIntegral.fromEnum)Zamiast tego użyj (+14 bajtów) do obsługi dowolnie dużych liczb.

Działa dla zakresu Unicode [0..255]. Rekurencyjnie odwraca bity.


1
Można wymienić takeWhile(>0)z fst.span(>0). Jeśli przejdziesz bez celu, możesz usunąć nazwę f, więc twoją główną funkcją jest (++[0]) ... map fromEnum.
nimi

@nimi dzięki, upuszczenie nazwy rozwiązuje problem wnioskowania typu, z którym miałem f.
Angs

Dlaczego fromIntegral? Z wyzwania: „musi obsługiwać ... do 63 bitów ... lub limit twojego języka”, więc Intpowinno być w porządku. Jeśli chcesz go zachować, przenieś go do map, tj. Do starej wersji foldl1i map(fromIntegral.fromEnum).
nimi

@nimi OP opublikował tutaj komentarz (ponieważ usunięty), pytając, czy to obsługuje 63 bity, więc założyłem, że taki był jego zamiar. Bije mnie
Angs

4

PHP, 132 126 123 120 108 107 bajtów

foreach(unpack("C*",$argv[1])as$i)$n=$n*256+$i;for(print$n;$n;)echo _.$n=bindec(strtr(decbin($n),"01",10));
  • wypisywanie 0 po pętli zamiast wartości początkowej, zanim pętla zapisuje 6 bajtów.
  • unpackzamiast str_splitrenderuje ord()przestarzałe -> -3 bajty
  • podkreślenie, _gdy separator zapisuje 3.
  • bindeczamiast ltrimusunąć wiodące zera: -12
  • echow korpusie pętli oszczędza 1 bajt printw głowicy pętli.

Nie $n=$n*256+$i;for(print$n;$n;)można zapisać jako for(print$n=$n*256+$i;$n;)? Ponieważ część przypisania zostanie wykonana raz, powinno to działać. I zamiast tego echo _.$n=[...]powinieneś użyć echo _,$n=[...]zamiast tego. Nie uratuje żadnego bajtu, ale przyspieszy kod malutki malutki drobiazg i rozdzieli instrukcje. Oznacza to, że można na przykład echo _,$a?5:6;napisać zamiast echo _.($a?5:6);. Może to być pomocne w przyszłości.
Ismael Miguel

@IsmaelMiguel Część przypisania jest pętlą. Używam przecinka, gdy nie potrzebuję kropki; printw tym przypadku jest to pozostałość . Sam nie wart edycji; ale dzięki.
Tytus

Och, racja ... To jest wewnątrz foreach(unpack("C*",$argv[1])as$i)... Głupia ja ... I tak, zmiana okresu, aby przecinek miał taki sam efekt, nie jest warta kłopotów.
Ismael Miguel

4

Perl, 65 bajtów

Kod 53 bajty + 12 dla -Mbigint -p.

Dzięki @ Dada za uratowanie mnie 13 bajtów!

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

Dość proste podejście, różniące się tylko od większości z nich, jest to, że liczba jest przechowywana jako binarna i drukowana w systemie dziesiętnym. Jestem pewien, że można to poprawić, być może dzięki przechowywaniu szczegółów w tablicy. -Mbigintjest nieco niewygodny, ale konieczny.

Stosowanie

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
Rozpakuj mojego przyjaciela, rozpakuj! perl -Mbigint -lpE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'(Nie mam pojęcia, jak zwykle korzystać z rozpakowywania , po prostu miałem szczęście, kiedy googlowałem, jak przekonwertować ciąg na binarny ;-))
Dada,

Ahhh, zawsze zapominam o unpackskładni, zawsze miażdżę umysł! Zaktualizuję, dziękuję!
Dom Hastings,

Jest perlpacktut, który powinien pomóc ... Przeczytałem pierwsze 10 wierszy dziesiątki razy, ale naprawdę powinienem poświęcić trochę czasu na przeczytanie reszty!
Dada,

@Dada Jestem pewien, że przeczytałem to wiele razy, to po prostu nigdy nie zostaje ... Dzięki jeszcze raz -13 to niemały wyczyn! Musiałem przełączyć się na echo -nto jedyna inna zmiana.
Dom Hastings,

4

Pyth, 12 bajtów

.usi!MjN2 2C

Program, który pobiera ciąg cytowanego ciągu i wypisuje wynik jako listę liczb całkowitych.

Sprawdź wszystkie przypadki testowe

Jak to działa

.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 bajtów

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

Główną ideą jest konwersja ciągu znaków na bajty na liczbę. Każda iteracja wypisuje wynik i XOR ze wszystkimi 1, aby przejść do zera.


Nie potrzebujesz nawiasów 2**x.bit_length()-1. Kolejność operacji dla mocy i odejmowania jest wyższa niż xor. whileMoże to również znajdować się w jednej linii.
mbomb007

Napisz pętlę while w jednym wierszu (usuń
znak

Spróbuj uruchomić program za pomocą, P=printa następnie użyj P()zamiastprint()
Cyoce

3

Python 2, 117 115 bajtów

Oszczędność 2 bajtów dzięki Cyoce.

Zakłada dane wejściowe ujęte w cudzysłów, np "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

mliczy się do najwyższej cyfry, podobnie m-1jak maska ​​XOR do wykonania żądanej operacji. Najdłuższą częścią jest konwersja danych wejściowych na początkową sekwencję bitów.

Przykład:

"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

Można wymienić -i-1z~i
Cyoce

3

Rubinowy, 104 101 100 81 80 65 bajtów

19 bajtów zapisanych dzięki @WayneConrad!
15 bajtów zapisanych dzięki @philomory!
1 bajt zapisany dzięki @LeeW!

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

Pobiera dane wejściowe za pomocą argumentów wiersza poleceń.

Zainspirowany odpowiedzią Pythona na JimmyJohnson


Być może uda ci się uratować kilka postaci, zastępując i.to_s(2).rjust 8,'0'je"%08b"%i
Wayne Conrad

Myślę też, że inject(:+)można go zastąpićjoin
Wayne Conrad

@WayneConrad dzięki za pomoc! Nie jestem pewien, jak o nich zapomniałem
Cyoce

Cieszę się, że mogłem pomóc! Dziękujemy za nauczenie mnie metody #bit_length, o której nie wiedziałem.
Wayne Conrad

1
Przejście na unpackopcję „ [0]zamiast, a nie na bałagan” gsubpozwoli zaoszczędzić 11 bajtów. Przełączenie na $*[0]zamiast gets.chop(użycie argumentu wiersza poleceń zamiast danych wejściowych konsoli) spowoduje zapisanie kolejnych 9, pierwszy wiersz staje się p n=$*[0].unpack('B*')[0].to_i(2).
philomory

3

Labirynt , 104 103 bajty

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

Wypróbuj online!

Wyjaśnienie:

Obraz kodu źródłowego oznaczony kolorami

Wskaźnik instrukcji zaczyna się od lewego górnego znaku, który nie jest ścianą (ściany zawierają spacje i dowolną literę z wyjątkiem v).

Pomarańczowy:

Ta pętla pobiera jeden znak na raz jako kod ASCII, dodając go do bieżącej wartości i mnożąc bieżącą wartość przez 256.

  • ' Brak operacji
  • ,Wciśnij kod ascii następnego znaku wejściowego na górę stosu lub -1, jeśli EOF. W tym momencie, jeśli otrzymano dane wejściowe, kod skręci w prawo (przesuwa się w dół), ponieważ górna część stosu jest potencjalna. W przeciwnym razie skręci w lewo, ponieważ górna część stosu jest ujemna.
  • | Zdejmij dwa górne przedmioty ze stosu i wciśnij wynik bitowego LUB.
  • _ Naciśnij zero
  • 256Każda cyfra wyskakuje xi popycha x*10+digit. Tak więc w połączeniu z poprzednim zepchnięciem zerowym push 256 na szczyt stosu.
  • *Pop y, pop x, push x*y. W tym momencie, ponieważ górna część stosu jest dodatnia, kod skręci w prawo, aby kontynuować wokół pętli.

Niebieski:

  • )Zwiększ górną część stosu. Po osiągnięciu końca wejścia kod skręci w lewo, aby dostać się do tego punktu z -1 na stosie, który zostanie zwiększony do zera.
  • 256 Posiadanie góry stosu 0 pozwala nam przesunąć tę 256.
  • /Pop y, pop xpush x/y(podział na liczby całkowite). Ponieważ mnożymy dane wejściowe przez 256 w każdej pętli, musimy cofnąć ostatnie mnożenie.
  • : Zduplikuj górę stosu, abyśmy mieli kopię bieżącej wartości na później.
  • ! Pop u góry stosu i wydrukuj wartość całkowitą na STDOUT.
  • \ Wydrukuj nową linię.
  • _2 Wciśnij dwa na wierzch stosu.
  • } Przenieś górę stosu na górę stosu pomocniczego.

Czerwony:

Ta pętla odwraca bity bieżącej wartości o XOR o określoną wartość obliczoną w wewnętrznej (zielonej) pętli. Następnie wysyła aktualną wartość i wychodzi z programu, jeśli bieżąca wartość wynosi zero.

  • _ Naciśnij zero (przepływ kontrolny).
  • ; Odrzuć górę stosu (przepływ kontrolny).
  • :Zduplikuj bieżącą wartość. Kopia zostanie wykorzystana do obliczenia XOR.
  • _ Naciśnij zero (przepływ kontrolny).
  • (Zielona pętla)
  • $Pop y, pop x, push x XOR y.
  • :! Zduplikuj bieżącą wartość i wydrukuj reprezentację liczb całkowitych.
  • Jeśli bieżąca wartość wynosi 0, kontynuujemy prosto do @i kończymy .
  • \ Wydrukuj nową linię.
  • _2} Naciśnij 2 i przejdź do stosu Aux.
  • _1 Naciśnij 1 (kontrola przepływu).

Zielony:

Ta pętla oblicza wartość, o którą potrzebujemy XOR bieżącej wartości. Odbywa się to poprzez wielokrotne podwojenie górnej części stosu pomocniczego przy jednoczesnym zmniejszeniu o połowę kopii bieżącej wartości na końcu głównego stosu aż do osiągnięcia wartości 0.

  • _ Naciśnij zero (przepływ kontrolny).
  • ; Odrzuć bieżącą wartość, która jest używana tylko do wymuszenia przepływu kontroli.
  • _2 Naciśnij 2, aby zmniejszyć o połowę bieżącą wartość.
  • / Podzielić
  • { Przenieś górę stosu Aux na górę głównego stosu.
  • _2* Podwój górną część stosu
  • } Przenieś górę głównego stosu z powrotem na stos pomocniczy.
  • _1 Naciśnij jeden, aby uzyskać kontrolę przepływu.
  • Po wyjściu z pętli:
  • ; Odrzuć lewą ponad zero od obliczenia XOR.
  • { Przenieś obliczony XOR na główny stos.
  • ( Odejmij jeden od wartości XOR.

2

PowerShell v2 +, 158 bajtów

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}

Tak, więc konwersja baz w PowerShell jest naprawdę cholerna . I zrobimy to tutaj dwa razy.

OK, więc jest to tylko forpętla włączona $a- tzn. Pętla trwa tak długo, jak $aistnieje. W końcu dojdziemy do pustej struny (która jest falsey), więc w ten sposób zakończymy.

Konfiguracja pętli, $a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)})pobiera dane wejściowe $args[0], charrzutuje je na- tablicę i zapętla każdą postać. Używamy .NET [convert]::ToString(int,base)do konwersji każdego z nich na ciąg binarny. Nie obejmuje to jednak zer wiodących, dlatego musimy ponownie rzucić ten ciąg jako [int]i wywołać jego .ToString() metodę z 8zerami jako maską. Następnie te ciągi znaków są zamykane w pareny i edytowane -joinrazem, a następnie zapisywane w $a.

Wewnątrz pętli [convert]::ToInt64(string,base)przekształcamy liczbę binarną na liczbę dziesiętną. Pozostaje on w potoku, a następnie jest przepłukiwany, gdy pętla resetuje się (a zatem niejawnie drukuje). Następna sekcja wykonuje obliczenia - my .TrimStart()usuwamy wszystkie wiodące zera, dzielimy -split0na zera i otrzymujemy stringtablicę 1s, -replacete z zerami, a na końcu -jointablicę z powrotem razem z 1s. Następnie pętla zaczyna się od nowa.

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 bajtów

q256b0{_p2b:!2bj}j

Wypróbuj 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

UWAGA: Stara 16-bajtowa wersja nie działała poprawnie z pustymi ciągami:

q256b{_p2b:!2b}h

Ponadto, dzięki Dennisowi za sugestię, pktóra pozwala zaoszczędzić 1 bajt przed N\wstawieniem nowych linii do stosu.


_p2b:!2bzapisuje bajt. Powinieneś także użyć l; rzakończy się niepowodzeniem, jeśli dane wejściowe zawierają spacje.
Dennis

@Dennis Dzięki, chociaż to mnie teraz martwi, jeśli problem stanowi pusty ciąg.
Linus

Dobrze. qbędzie działać poprawnie z pustymi ciągami.
Dennis


1

Siatkówka, 116 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1. Wiersz 5 zawiera bajty niedrukowalne. Jest 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

Wypróbuj online

Nie próbuj tego przy wprowadzaniu dłuższych niż dwa znaki. (Upływa limit czasu przy użyciu interpretera internetowego.) Musimy przekonwertować plik binarny na jednoargumentowy przed przecinkiem. :RE

Niestety jest końcowe zero i podawanie wiersza, ale postanowiłem założyć, że było w porządku, ponieważ dane wyjściowe są nadal poprawne.

Wyjaśnienie

-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

Rubinowy - 70 bajtów

λ 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 kończy działanie z wyjątkiem po zakończeniu, ale rozumiem, że jest w porządku, dopóki wyjście błędu przechodzi do STDERR, a nie STDOUT (co robi).


1

C, 147 135 133 125 122 121 117 115 103 bajtów

Zaoszczędź 5 bajtów dzięki @Cyoce!

Zaoszczędź 2 bajty dzięki @Cyoce i @cleblanc!

Zaoszczędzono 12 bajtów dzięki @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;}

Nie golfowany:

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

Myślę, że można pominąć intdeklaracje
Cyoce,

Możesz także zapisać bajt, przekształcając ostatnią whilepętlę w forpętlę
Cyoce,

I możesz zmienić while(1)nafor(;;)
Cyoce

@Cyoce Próbowałem usunąć intdeklaracje wszędzie i dostałem gcc -std=89błędy. Ale dziękuję za for(;;)wskazówkę. Będę próbował usunąć intdeklaracje :)))
Noodle9

przepraszam, nie testowałem tego. Myślę, że to zadziała, jeśli przeniesiesz je na górę ( i;main(c,v)char**v;{...}). Na telefonie komórkowym, więc nie mogę być pewien
Cyoce

0

C, 129 120 117 110 107 105 bajtów

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

Testowane z

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

wynik

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,

Myślę, że możesz przejść i=0do deklaracji ii pozostawić sekcję inicjalizacji forpętli pustą
Cyoce,

@Cyoce Funkcja musi działać za każdym razem, gdy jest wywoływana, a ponieważ ijest domyślną int globalną, należy ją inicjować za każdym razem, gdy wywoływane jest f (...).
cleblanc

@Cyoce W końcu miałeś rację. Funkcja nie kończy działania, dopóki iponownie nie wyzeruje, więc można ją ponownie wykorzystać.
cleblanc


0

C #, 360 359 bajtów

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

Pełny 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
    }
}

Nie robię C #, ale może var t="";var f="";być var t="",f=""zamiast? Oszczędza 5 bajtów.
corsiKa

@ corsiKa Tak, próbowałem, ale dało mi to błąd, bo to jest var, a nie string.
Yodle

W rzeczywistości łańcuch zapisuje jeden bajt, więc myślę, że zrobię to w ten sposób.
Yodle

Czy możesz również ustawić zmienną az na zero, aby zapisać te nieprzyjemne cytaty?
corsiKa

Właśnie wypróbowałem, w rzeczywistości podnosi liczbę bajtów, ponieważ nie mogę zastąpić zarówno ciągu „0”, jak i znaku „0” :(
Yodle
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.