Countdown von "Unendlichkeit"

47

Scheint eine unmögliche Aufgabe zu sein, oder? Nun, es ist eigentlich nicht so schwer. Wenn wir das Wort Infinityals 8-Bit-Binär-ASCII-Code schreiben , erhalten wir:

01001001 01101110 01100110 01101001 01101110 01101001 01110100 01111001

Dies kann verkettet und in den Dezimalwert konvertiert werden 5291279215216915577. Das ist eine Nummer, mit der wir arbeiten können ...

Der Countdown läuft folgendermaßen ab:

  1. Die ursprüngliche Zeichenfolge als Dezimalzahl ausgeben (wie oben gezeigt)
  2. Entfernen Sie führende Nullen in der Binärdarstellung (falls vorhanden)
  3. Umschalten der Bits in der Binärdarstellung (1-> 0, 0-> 1)
  4. Geben Sie die Zahl dezimal aus
  5. Wiederholen Sie die Schritte 2 bis 4, bis Sie 0 erreichen.

Herausforderung:

Erstellen Sie ein Programm oder eine Funktion, die eine Zeichenfolge als Eingabe verwendet und (in einem geeigneten Format) die Zahlen ausgibt, die Sie beim Ausführen des obigen Verfahrens erhalten.

Testfall:

Ich denke, die Herausforderung wird ziemlich einfach zu verstehen sein, auch wenn es nur ein Testfall ist. Ich werde verwenden, Infanstatt Infinitydies ziemlich kurz zu halten.

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

Ihr Code muss Zeichenfolgen unterstützen, die bis zur Grenze Ihrer Sprache als Binärzahl dargestellt werden können. Alle Zeichenketten enthalten nur druckbare ASCII-Zeichen von 32-126 (Leerzeichen bis Tilde).


Bestenliste

Stewie Griffin
quelle
31
Chuck Norris , 8 Bytes:Inf:-1:0
Luis Mendo
2
@ LuisMendo Chuck Norris 'NARS-APL:∞..0
Adám
5
@ LuisMendo Sind Sie sicher, dass Sie nicht Jon Skeet meinen ?
mbomb007

Antworten:

12

Jelly , 15 10 Bytes

-5 Bytes dank @Dennis (konvertiere direkt von der Basis 256 nach der ordinalen Umwandlung)

Oḅ⁹µBCḄµÐĿ

TryItOnline!

Wie?

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
quelle
1
Der erste Teil ist einfach Oḅ⁹.
Dennis
Oh mein Gott, wie habe ich das vermisst ?!
Jonathan Allan
11

Python 2, 89 82 77 76 75 Bytes

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

Teste es auf Ideone .

Wie es funktioniert

Nach der Initialisierung von n auf 0 führt die zweite Zeile die in den Abfragen angegebene Umwandlung von Zeichenfolge in Ganzzahl wie folgt aus.

In jedem Schritt wird n um 8 Einheiten nach links verschoben und dann mit dem Codepunkt des nächsten Zeichens c bitweise ODER- verknüpft . Für den Eingang Inf ist dies wie folgt.

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

Jetzt können wir die Ausgabe generieren. Um die Bits von n zu invertieren , gehen wir wie folgt vor.

Zuerst berechnen wir die Bits in der Binärdarstellung von n ohne führende Nullen. Nennen wir das Ergebnis k . Dann berechnen wir die k k Potenz von 2 , die k + 1 Binärziffern hat: eine einzelne 1 , gefolgt von k 0 . Wir subtrahieren 1 vom Ergebnis und erhalten eine aus k Einsen zusammengesetzte Zahl , die wir dann mit n XOR- verknüpft, um ihre Bits zu invertieren. Für die Eingabe von inf ist dies wie folgt.

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

Eine zusätzliche Hürde bei der Implementierung ist, dass wir n vor dem ersten Schritt, nach dem letzten Schritt und in allen dazwischen liegenden Schritten drucken müssen . Python hat keine do-while-Schleifen und eine einzelne print- Anweisung kostet 8 Bytes. Deshalb gehen wir stattdessen wie folgt vor.

Bei der unkomplizierten Durchführung des Update-Schritts, dh

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

wir ersetzen die Schleife durch eine unendliche ( while 1) und berechnen die 1in der Schleife als n/n. Dies ist äquivalent, wenn n> 0 ist .

Sobald n = 0 ist , bleiben wir in der Schleife, drucken den Status erneut und versuchen ihn zu aktualisieren. Löst jedoch 0/0einen ZeroDivisionError aus , bricht die Schleife ab und wird mit einem Fehler beendet. Beachten Sie, dass dies zu einer Streuausgabe an STDERR führt, die standardmäßig zulässig ist .

Dennis
quelle
2
Ich liebe diesen -n/nTrick :-)
ETHproductions
Können Sie als n/nTrick erklären ? Es ist wahrscheinlich in einer anderen Antwort erklärt worden, aber ich habe es nicht gefunden. Was macht es hier?
Stewie Griffin
@StewieGriffin n / n ist 1 bis n ist 0, dann wird ein Fehler ausgegeben und das Programm beendet.
Jazzpi
Mit einer Fehlermeldung (hoffe ich)?
Stewie Griffin
1
@ StewieGriffin In der Tat. Python ist schmerzhaft ausführlich, wenn es um Fehlerberichte geht. Ich habe meine Antwort bearbeitet, um eine Erklärung aufzunehmen.
Dennis
8

JavaScript, 82 Byte

Ein Byte dank @Arnuald gespeichert

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

Eines der wenigen Male, wenn ein vollständiges Programm eine Funktion übertrifft (und ES6 ES5 nicht übertrifft) ...


Das Obige unterstützt Wörter mit bis zu 4 Buchstaben. Fügen Sie 4 Bytes hinzu, um Wörter mit bis zu 6 Buchstaben zu unterstützen:

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

ETHproductions
quelle
g=a=>a[0]?a.pop().charCodeAt()+g(a)*256:0(-1)
Titus
@ Titus Danke! Ich bin mir nicht sicher, warum ich nicht daran gedacht habe
ETHproductions
n<<8|y.charCodeAt()sollte ein Byte speichern. for(;n;)for(i=!alert(n);i<=n;i*=2)n^=iwürde ein weiteres Byte speichern, aber Sie werden nicht angezeigt 0, was wahrscheinlich erforderlich ist.
Arnauld
@ Arnauld Danke. Ich dachte darüber nach n<<8, entschied aber, dass es nicht funktionieren würde, weil es für n mit mehr als 31 Bits kaputt gehen würde. Ich nehme an, es ist jetzt egal, dass ich es bereits in eine 31-Bit-Version und eine 53-Bit-Version aufgeteilt habe Iteration und die letzte.
ETHproductions
7

Eigentlich 14 Bytes

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

Probieren Sie es online!

Erläuterung:

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
quelle
6

05AB1E , 18 Bytes

Verwendet CP-1252- Codierung.

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

Probieren Sie es online!

Erläuterung

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

MATL , 13 Bytes

8W:qZA`tB~XBt

Probieren Sie es online!

Erläuterung

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
quelle
4

Mathematica, 99 Bytes

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

Anonyme Funktion. Nimmt eine Zeichenfolge als Eingabe und gibt eine Liste von Zahlen als Ausgabe zurück.

LegionMammal978
quelle
4

Haskell, 109 123 118 102 97 Bytes

Vielen Dank an @nimi für das Speichern von 5 Bytes!

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

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

Garantiert für die Bearbeitung von Zahlen mit bis zu 29 Bit in der Sprache. Bei 64-Bit-Systemen werden normalerweise bis zu 63-Bit-Zahlen verarbeitet. Verwenden Sie map(fromIntegral.fromEnum)stattdessen (+14 Byte), um beliebig große Zahlen zu unterstützen.

Funktioniert für Unicode-Bereich [0..255]. Kehrt Bits rekursiv um.

Angs
quelle
1
Sie können ersetzen takeWhile(>0)mit fst.span(>0). Wenn Sie frei gehen, können Sie den Namen fallen lassen f, also ist Ihre Hauptfunktion (++[0]) ... map fromEnum.
nimi
@nimi danke, das Löschen des Namens löst das Typinferenzproblem, mit dem ich hatte f.
Angs
Warum fromIntegral? Aus der Herausforderung: "Muss unterstützen ... bis zu 63bit ... oder die Grenze Ihrer Sprache", Intsollte also in Ordnung sein. Wenn Sie es behalten möchten, verschieben Sie es in mapIhre alte Version von foldl1und map(fromIntegral.fromEnum).
nimi
@nimi OP hat hier einen Kommentar gepostet (seitdem gelöscht) und gefragt, ob dies 63 Bits unterstützt. Ich nahm an, dass dies seine Absicht war. Schlägt mich.
Angs
4

PHP, 132 126 123 120 108 107 Bytes

foreach(unpack("C*",$argv[1])as$i)$n=$n*256+$i;for(print$n;$n;)echo _.$n=bindec(strtr(decbin($n),"01",10));
  • Drucken von 0 nach der Schleife anstelle des Anfangswerts, bevor die Schleife 6 Bytes speichert.
  • unpackstatt str_splitmacht ord()obsolet -> -3 Bytes
  • Unterstrich _als Trennzeichen speichert 3.
  • bindecanstatt ltrimführende Nullen zu entfernen: -12
  • echoIm Schleifenkörper wird 1 Byte printim Schleifenkopf gespeichert.
Titus
quelle
Kann nicht $n=$n*256+$i;for(print$n;$n;)als geschrieben werden for(print$n=$n*256+$i;$n;)? Da der Zuweisungsteil einmal ausgeführt wird, sollte dies funktionieren. Und stattdessen echo _.$n=[...]sollten Sie echo _,$n=[...]stattdessen verwenden. Es speichert kein Byte, beschleunigt aber den Code um ein winziges kleines bisschen und trennt Anweisungen. Das heißt, dass beispielsweise echo _,$a?5:6;statt geschrieben werden kann echo _.($a?5:6);. Dies kann in Zukunft hilfreich sein.
Ismael Miguel
@IsmaelMiguel Der Zuweisungsteil ist eine Schleife. Ich benutze eigentlich das Komma, wenn ich den Punkt nicht brauche; es ist ein Überbleibsel der printin diesem Fall. Alleine keine Bearbeitung wert; aber danke.
Titus
Oh, richtig ... Es liegt im foreach(unpack("C*",$argv[1])as$i)... Dummen Ich ... Und ja, einen Punkt für ein Komma zu ändern, um den gleichen Effekt zu erzielen, ist die Mühe nicht wert.
Ismael Miguel
4

Perl, 65 Bytes

53 Byte Code + 12 für -Mbigint -p.

Vielen Dank an @ Dada für die Rettung von 13 Bytes!

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

Ein relativ einfacher Ansatz, der sich von den meisten unterscheidet, besteht darin, dass die Zahl als Binärzahl gespeichert und dezimal ausgedruckt wird. Ich bin mir sicher, dass es verbessert werden kann, wenn Details in einem Array gespeichert werden. -Mbigintist etwas umständlich aber notwendig.

Verwendungszweck

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
quelle
1
Packe meinen Freund aus, packe aus! perl -Mbigint -lpE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'(Ich habe keine Ahnung, wie man normalerweise entpackt , ich habe gerade Glück gehabt, als ich gegoogelt habe, wie man einen String in Binär umwandelt ;-))
Dada
Ahhh, ich vergesse immer unpackdie Syntax , die mich immer in den Bann zieht ! Ich werde aktualisieren, danke!
Dom Hastings
Es gibt Perlpacktut , das helfen sollte ... Ich habe die ersten 10 Zeilen Dutzende Male gelesen, aber ich sollte mir wirklich die Zeit nehmen, den Rest zu lesen!
Dada
@Dada Ich bin sicher, ich habe es oft gelesen, es bleibt einfach nie drin ... Nochmals vielen Dank -13 ist keine Kleinigkeit! Ich musste echo -numsteigen , ist die einzige andere Änderung.
Dom Hastings
4

Pyth, 12 Bytes

.usi!MjN2 2C

Ein Programm, das eine Zeichenfolge in Anführungszeichen eingibt und das Ergebnis als Liste von Ganzzahlen ausgibt.

Überprüfen Sie alle Testfälle

Wie es funktioniert

.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
quelle
3

Python 3, 99 95 Bytes

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

Die Hauptidee ist, eine Zeichenkette in Bytes in Zahlen umzuwandeln. Bei jeder Iteration werden die Ausgabe und das XOR mit allen Einsen gedruckt, um in Richtung Null voranzukommen.

Jimmy Johnson
quelle
Sie brauchen keine runden Klammern 2**x.bit_length()-1. Die Reihenfolge der Operationen für Leistung und Subtraktion ist höher als xor. Dies whilekann auch in einer einzelnen Zeile erfolgen.
mbomb007
Schreiben Sie die while-Schleife in eine Zeile (entfernen Sie die neue Zeile und den Einzug)
FlipTack
Versuchen Sie das Programm mit Start P=printund dann unter Verwendung P()anstelle vonprint()
Cyoce
3

Python 2, 117 115 Bytes

2 Bytes sparen dank Cyoce.

Nimmt an, dass die Eingabe in Anführungszeichen eingeschlossen ist, z "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

mzählt bis zur höchsten Ziffer, so m-1ist eine XOR-Maske zur Durchführung der gewünschten Operation. Der längste Teil konvertiert die Eingabe in die anfängliche Bitsequenz.

Beispiel:

"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
quelle
Sie können -i-1mit~i
Cyoce
3

Ruby, 104 101 100 81 80 65 Bytes

19 Bytes gespart dank @WayneConrad!
15 Bytes gespart dank @philomory!
1 Byte gespart dank @LeeW!

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

Übernimmt die Eingabe über Befehlszeilenargumente.

Inspiriert von @ JimmyJohnsons Python-Antwort

Cyoce
quelle
Sie können durch das Ersetzen ein paar Zeichen speichern können , i.to_s(2).rjust 8,'0'mit"%08b"%i
Wayne Conrad
Auch ich denke, inject(:+)kann mitjoin
Wayne Conrad
@WayneConrad danke für die Hilfe! Nicht sicher, wie ich das vergessen habe
Cyoce
Froh, dass ich helfen konnte! Vielen Dank, dass Sie mir die Methode #bit_length beigebracht haben, von der ich nichts wusste.
Wayne Conrad
1
Das Umschalten auf unpackgefolgt von, [0]anstatt mit zu experimentieren gsub, spart 11 Bytes. Wenn Sie zu $*[0]anstatt gets.chop(mit einem Befehlszeilenargument anstelle einer Konsoleneingabe) wechseln, werden weitere 9 gespeichert, die erste Zeile wird p n=$*[0].unpack('B*')[0].to_i(2).
Philomory
3

Labyrinth , 104 103 Bytes

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

Probieren Sie es online!

Erläuterung:

Farbcodiertes Bild des Quellcodes

Der Anweisungszeiger beginnt am obersten linken Rand des Nicht-Wand-Zeichens (Wände enthalten Leerzeichen und alle Buchstaben außer v).

Orange:

Diese Schleife erhält die Eingabe zeichenweise als ASCII-Code, addiert sie zum aktuellen Wert und multipliziert den aktuellen Wert mit 256.

  • ' Nein-Op
  • ,Schieben Sie den ASCII-Code des nächsten Eingabezeichens an den Anfang des Stapels oder -1, wenn EOF. Wenn zu diesem Zeitpunkt eine Eingabe empfangen wurde, dreht sich der Code nach rechts (nach unten), da die Oberseite des Stapels potenziell ist. Andernfalls wird es nach links gedreht, da die Oberseite des Stapels negativ ist.
  • | Pop die beiden obersten Elemente aus dem Stapel und drücken Sie das Ergebnis eines bitweisen ODER.
  • _ Null drücken
  • 256Jede Ziffer erscheint xund drückt x*10+digit. Dies kombiniert mit dem Push-Null-Vorgänger-Push 256 an die Spitze des Stapels.
  • *Pop y, Pop x, Push x*y. Zu diesem Zeitpunkt dreht sich der Code nach rechts, um die Schleife zu durchlaufen, da die Oberseite des Stapels positiv ist.

Blau:

  • )Erhöhen Sie die Oberseite des Stapels. Wenn das Ende der Eingabe erreicht ist, dreht sich der Code nach links, um mit -1 auf dem Stapel zu diesem Punkt zu gelangen, der auf Null erhöht wird.
  • 256 Wenn wir die Spitze des Stapels 0 haben, können wir diese 256 verschieben.
  • /Pop y, Pop xPush x/y(ganzzahlige Division). Da wir die Eingabe mit 256 pro Schleife multipliziert haben, müssen wir die letzte Multiplikation zurücksetzen.
  • : Duplizieren Sie den oberen Bereich des Stapels, damit wir eine Kopie des aktuellen Werts für später haben.
  • ! Öffnen Sie den oberen Bereich des Stapels und geben Sie den ganzzahligen Wert in STDOUT aus.
  • \ Drucken Sie eine neue Zeile.
  • _2 Schieben Sie eine Zwei nach oben auf den Stapel.
  • } Bewegen Sie die Oberseite des Stapels an die Oberseite des Hilfsstapels.

Rot:

Diese Schleife kippt die Bits des aktuellen Werts durch XOR mit einem bestimmten Wert, der in der inneren (grünen) Schleife berechnet wurde. Es gibt dann den aktuellen Wert aus und beendet das Programm, wenn der aktuelle Wert Null ist.

  • _ Null drücken (Kontrollfluss).
  • ; Verwerfen Sie die Oberseite des Stapels (Kontrollfluss).
  • :Duplizieren Sie den aktuellen Wert. Die Kopie wird zur Berechnung des XOR verwendet.
  • _ Null drücken (Kontrollfluss).
  • (Grüne Schleife)
  • $Pop y, Pop x, Push x XOR y.
  • :! Duplizieren Sie den aktuellen Wert und drucken Sie die Ganzzahldarstellung.
  • Wenn der aktuelle Wert 0 ist, fahren wir direkt mit dem fort @und enden.
  • \ Drucken Sie eine neue Zeile.
  • _2} Drücken Sie 2 und gehen Sie zum Aux-Stack.
  • _1 Drücken Sie 1 (Kontrollfluss).

Grün:

Diese Schleife berechnet den Wert, um den wir den aktuellen Wert XOR benötigen. Dies erfolgt durch wiederholtes Verdoppeln der Oberseite des Zusatzstapels, während eine Kopie des aktuellen Werts auf dem Stopp des Hauptstapels halbiert wird, bis 0 erreicht ist.

  • _ Null drücken (Kontrollfluss).
  • ; Verwerfen Sie den aktuellen Wert, der nur zum Erzwingen des Kontrollflusses verwendet wird.
  • _2 Drücken Sie 2, um den aktuellen Wert zu halbieren.
  • / Teilen
  • { Bewegen Sie die Oberseite des Aux-Stapels an die Oberseite des Hauptstapels.
  • _2* Verdoppeln Sie die Oberseite des Stapels
  • } Bewegen Sie die Oberseite des Hauptstapels zurück zum Aux-Stapel.
  • _1 Drücken Sie eine für den Kontrollfluss.
  • Nach dem Verlassen der Schleife:
  • ; Verwerfen Sie die verbleibende Null bei der Berechnung des XOR.
  • { Verschieben Sie das berechnete XOR in den Hauptstapel.
  • ( Subtrahiere eins vom XOR-Wert.
Robert Hickman
quelle
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}

Ja, das Konvertieren von Basen in PowerShell ist wirklich bescheuert . Und wir können es hier zweimal machen.

OK, das ist also nur eine forSchleife, $adh wir schleifen, solange es $aexistiert. Wir werden irgendwann eine leere Zeichenfolge erreichen (was falsch ist), also werden wir so enden.

Der Aufbau der Schleife $a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)})übernimmt die Eingabe $args[0], charwandelt sie als -array um und durchläuft jedes Zeichen in einer Schleife. Wir verwenden .NET [convert]::ToString(int,base), um jeden in einen Binärstring umzuwandeln. Das schließt jedoch führende Nullen nicht ein, daher müssen wir diese Zeichenfolge als eine [int]umwandeln und ihre .ToString() Methode mit 8Nullen als Maske aufrufen . Dann werden diese Zeichenfolgen in Parens eingekapselt und -joinzusammengefügt und dann in gespeichert $a.

Innerhalb der Schleife [convert]::ToInt64(string,base)konvertieren wir die Binärzahl in eine Dezimalzahl. Dieser wird in der Pipeline belassen und anschließend gelöscht, wenn die Schleife zurückgesetzt wird (und daher implizit gedruckt wird). Der nächste Abschnitt führt die Berechnungen durch - wir .TrimStart()entfernen alle führenden Nullen, -split0teilen die Nullen auf und erhalten ein string-array von 1s, -replacedie Einsen mit Nullen und schließlich -joindas Array wieder zusammen mit 1s. Dann beginnt die Schleife erneut.

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
quelle
2

CJam , 17 16 18 Bytes

q256b0{_p2b:!2bj}j

Probieren Sie es 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

HINWEIS: Die alte 16-Byte-Version hat sich bei leeren Zeichenfolgen nicht richtig verhalten:

q256b{_p2b:!2b}h

Vielen Dank auch an Dennis , pder vorgeschlagen hat, 1 Byte zu sparen N\, wenn Zeilenumbrüche in den Stapel geschrieben werden.

Linus
quelle
_p2b:!2bSpeichert ein Byte. Auch sollten Sie verwenden l; rschlägt fehl, wenn die Eingabe Leerzeichen enthält.
Dennis
@Dennis Danke, aber das macht mir jetzt Sorgen, ob eine leere Zeichenfolge ein Problem ist.
Linus
Richtig. qwird mit leeren Zeichenfolgen korrekt funktionieren.
Dennis
2

J, 24 Bytes

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

Erklärung kommt später!

Olius
quelle
2
Willkommen bei PPCG! Permalink für Interessierte: Online ausprobieren!
Dennis
1

Netzhaut, 116 Bytes

Die Bytezahl setzt die ISO 8859-1-Codierung voraus. Zeile 5 enthält nicht druckbare Bytes. Es ist 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

Probieren Sie es online aus

Versuchen Sie dies nicht, wenn Sie mehr als zwei Zeichen eingeben. (Bei Verwendung des Online-Interpreters tritt eine Zeitüberschreitung auf.) Wir müssen die Binärzahl vor der Dezimalstelle in die Unärzahl umwandeln. : D

Leider gibt es eine nachgestellte Null und einen Zeilenvorschub, aber ich habe angenommen, dass dies in Ordnung ist, da die Ausgabe immer noch korrekt ist.

Erläuterung

-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
quelle
1

Ruby - 70 Bytes

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

Das Programm wird mit einer Ausnahme nach Abschluss beendet, aber meines Wissens ist dies in Ordnung, solange die Fehlerausgabe an STDERR und nicht an STDOUT (was es tut) geht.

Philomory
quelle
1

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

5 Bytes gespart dank @Cyoce!

2 Bytes gespart dank @Cyoce und @cleblanc!

12 Bytes dank @ceilingcat gespart

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 */
    }
}
Noodle9
quelle
Ich denke, Sie können die intErklärungen
auslassen
Sie können auch ein Byte speichern, indem Sie die letzte whileSchleife in eine forSchleife
umwandeln
Und Sie können while(1)zufor(;;)
Cyoce
@Cyoce Ich habe versucht, intDeklarationen überall zu entfernen und habe gcc -std=89Fehler bekommen. Aber danke für den for(;;)Tipp. Ich werde weiterhin versuchen, die intErklärungen zu entfernen :)))
Noodle9
Entschuldigung, ich habe es nicht getestet. Ich denke, es wird funktionieren, wenn Sie sie nach oben verschieben ( i;main(c,v)char**v;{...}). Ich bin gerade auf dem Handy, kann mir also nicht sicher sein
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);}

Getestet mit

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

Ausgabe

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
quelle
Ich denke, Sie können i=0zur Deklaration von wechseln iund den Initialisierungsabschnitt der forSchleife leer lassen
Cyoce
@Cyoce Die Funktion muss bei jedem Aufruf funktionieren und da sie iimplizit global int ist, muss sie bei jedem Aufruf von f (...) initialisiert werden.
Cleblanc
@Cyoce Du hattest doch recht. Die Funktion wird erst wieder beendet, wenn sie iwieder Null ist. Sie kann also weiter verwendet werden.
Cleblanc
102 Bytes
Ceilingcat
0

C #, 360 359 Bytes

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

Volles Programm:

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
    }
}
Jodler
quelle
Ich mache kein C #, kann es var t="";var f="";aber var t="",f=""stattdessen sein? Spart 5 Bytes.
corsiKa
@corsiKa Ja, ich habe das versucht, aber es hat mir einen Fehler beschert, ich denke, es ist var und kein String.
Yodle
Tatsächlich speichert ein String ein Byte, also werde ich es wohl so machen.
Jodler
Können Sie auch eine Variable für Null festlegen, um diese fiesen Anführungszeichen zu speichern?
corsiKa
Nur ausprobiert, es erhöht tatsächlich den bytecount, weil ich nicht sowohl die Zeichenfolge "0" als auch das Zeichen "0" ersetzen kann :(
Yodle