Compte à rebours de “Infinity”


47

Cela semble être une tâche impossible, non? En fait, ce n'est pas si difficile. Si nous écrivons le mot Infinitysous forme de code ASCII binaire 8 bits, nous aurons:

01001001 01101110 01100110 01101001 01101110 01101001 01110100 01111001

Cela peut être concaténé et converti en valeur décimale 5291279215216915577. Voilà un nombre avec lequel nous pouvons travailler ...

Le compte à rebours est:

  1. Afficher la chaîne d'origine sous forme de nombre décimal (comme indiqué ci-dessus)
  2. Supprimer les 0 premiers dans sa représentation binaire (le cas échéant)
  3. Basculer les bits dans la représentation binaire (1-> 0, 0-> 1)
  4. Affiche le nombre en décimal
  5. Répétez les étapes 2 à 4 jusqu'à ce que vous atteigniez 0.

Défi:

Créez un programme ou une fonction qui prend une chaîne en tant qu'entrée et génère (sous n'importe quel format approprié) les nombres que vous obtiendrez en effectuant la procédure ci-dessus.

Cas de test:

Je pense que le défi sera assez facile à comprendre, même s'il ne s'agit que d'un cas test. Je vais utiliser Infau lieu de Infinitygarder cela assez court.

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

Votre code doit prendre en charge des chaînes pouvant être représentées sous la forme d'un nombre binaire dans la limite de votre langue. Toutes les chaînes ne contiendront que des caractères ASCII imprimables compris entre 32 et 126 (espace au tilde).


Classement


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

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

5
@LuisMendo Êtes-vous sûr de ne pas vouloir dire Jon Skeet ?
mbomb007

Réponses:


12

Gelée , 15 à 10 octets

-5 octets grâce à @Dennis (converti directement à partir de la base 256 après la conversion ordinale)

Oḅ⁹µBCḄµÐĿ

TryItOnline!

Comment?

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
La première partie est juste Oḅ⁹.
Dennis

Oh mon Dieu, comment est-ce que j'ai raté ça?!
Jonathan Allan

11

Python 2, 89 82 77 76 75 octets

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

Testez-le sur Ideone .

Comment ça fonctionne

Après l’initialisation de n à 0 , la deuxième ligne effectue la conversion de chaîne en entier spécifiée dans les défis comme suit.

À chaque étape, n est décalé de 8 unités vers la gauche, puis OR au bit près avec le point de code du caractère suivant c . Pour l'entrée Inf , ceci va comme suit.

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

Nous sommes maintenant prêts à générer la sortie. Pour inverser les bits de n , on procède comme suit.

Premièrement, nous calculons les bits dans la représentation binaire de n sans les zéros au début. Appelons le résultat k . Ensuite, nous calculons la k k puissance de 2 , qui a k + 1 chiffres binaires: un seul 1 , suivi de k 0 . Nous soustrayons 1 du résultat, ce qui donne un nombre composé de k unités, que nous avons ensuite XOR avec n pour inverser ses bits. Pour l'entrée inf, cela va comme suit.

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

Un obstacle supplémentaire à la mise en œuvre est que nous devons imprimer n avant la première étape, après la dernière étape et dans toutes les étapes intermédiaires. Python n'a pas de boucle do-while et une seule déclaration d' impression coûte 8 octets. Nous procédons donc comme suit.

Dans la simple mise en œuvre de l'étape de mise à jour, c'est-à-dire

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

nous remplaçons la boucle par un infini ( while 1) et calculons la 1dans la boucle comme n/n. Ceci est équivalent lorsque n> 0 .

Une fois que n = 0 , nous restons dans la boucle, imprimons l'état une fois de plus, puis essayons de le mettre à jour. Cependant, 0/0déclenche une erreur ZeroDivisionError , qui se détache de la boucle et se termine avec une erreur. Notez que cela entraîne une sortie parasite vers STDERR, autorisée par défaut .


2
J'adore cette -n/nastuce :-)
ETHproductions

Pouvez-vous expliquer que n/ntruc? Cela a probablement été expliqué dans une autre réponse quelque part mais je ne l'ai pas trouvée. Que fait-il ici?
Stewie Griffin

@StewieGriffin n / n est 1 jusqu'à ce que n soit 0, alors une erreur est générée et le programme s'arrête.
jazzpi

Avec un message d'erreur (j'espère)?
Stewie Griffin

1
@StewieGriffin En effet. Python est péniblement prolixe en ce qui concerne le signalement des erreurs. J'ai modifié ma réponse pour y inclure une explication.
Dennis

8

JavaScript, 82 octets

Enregistré un octet grâce à @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

Une des rares fois où un programme complet surpasse une fonction (et ES6 ne surpasse pas ES5) ...


Ce qui précède prend en charge les mots de 4 lettres maximum. Ajoutez 4 octets pour prendre en charge les mots de 6 lettres maximum:

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

@ Merci Merci! Je ne sais pas pourquoi je n'y ai pas pensé
ETHproductions

n<<8|y.charCodeAt()devrait sauver un octet. for(;n;)for(i=!alert(n);i<=n;i*=2)n^=iéconomiserait un autre octet, mais vous n’affichez pas 0, ce qui est probablement nécessaire.
Arnauld

@ Arnauld Merci. Je pensais le faire n<<8plus tôt, mais j'ai décidé que cela ne fonctionnerait pas, car cela cassait pour n avec plus de 31 bits. Je suppose que ça ne fait rien, maintenant que je l'ai déjà partagé entre une version 31 bits et une version 53 bits ... itération et le dernier.
ETHproductions

7

En fait , 14 octets

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

Essayez-le en ligne!

Explication:

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 octets

Utilise le codage CP-1252 .

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

Essayez-le en ligne!

Explication

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

8W:qZA`tB~XBt

Essayez-le en ligne!

Explication

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 octets

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

Fonction anonyme. Prend une chaîne en entrée et renvoie une liste de nombres en sortie.


4

Haskell, 109 123 118 102 97 octets

Merci à @nimi pour avoir économisé 5 octets!

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

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

Garanti de travailler sur des nombres allant jusqu'à 29 bits en fonction de la langue, fonctionne généralement jusqu'à des nombres de 63 bits sur des systèmes 64 bits. Utilisationmap(fromIntegral.fromEnum) plutôt (+14 octets) pour prendre en charge des nombres arbitrairement grands.

Fonctionne pour la plage unicode [0..255]. Retourne les bits récursivement.


1
Vous pouvez remplacer takeWhile(>0)avec fst.span(>0). Si vous choisissez Pointfree, vous pouvez supprimer le nom f. Votre fonction principale est alors (++[0]) ... map fromEnum.
nimi

@nimi merci, laisser tomber ce nom résout le problème d'inférence de type que j'ai rencontré f.
Angs

Pourquoi fromIntegral? D'après le défi: "doit supporter ... jusqu'à 63 bits ... ou la limite de votre langue", ça Intdevrait aller. Si vous souhaitez le conserver, déplacez-le vers map, c'est- à -dire votre ancienne version de foldl1et map(fromIntegral.fromEnum).
nimi

@nimi OP a posté un commentaire ici (depuis supprimé), demandant si cela supportait 63 bits, alors j'ai supposé que c'était son intention. Me bat.
Angs

4

PHP, 132 126 123 120 108 107 octets

foreach(unpack("C*",$argv[1])as$i)$n=$n*256+$i;for(print$n;$n;)echo _.$n=bindec(strtr(decbin($n),"01",10));
  • l'impression 0 après boucle au lieu de la valeur initiale avant boucle enregistre 6 octets.
  • unpackau lieu de str_splitrend ord()obsolète -> -3 octets
  • souligner _comme séparateur enregistre 3.
  • bindecau lieu de ltrimsupprimer les zéros de gauche: -12
  • echoin Loop corps économise 1 octet printdans la tête de boucle.

Ne peut pas $n=$n*256+$i;for(print$n;$n;)être écrit comme for(print$n=$n*256+$i;$n;)? Puisque la partie assignation sera exécutée une fois, cela devrait fonctionner. Et au lieu de echo _.$n=[...], vous devriez utiliser à la echo _,$n=[...]place. Cela ne sauvera aucun octet, mais accélérera le code un tout petit peu et séparera les déclarations. Cela signifie que, par exemple, echo _,$a?5:6;peut être écrit à la place de echo _.($a?5:6);. Cela peut être utile dans le futur.
Ismael Miguel

@IsmaelMiguel La partie affectation est une boucle. J'utilise réellement la virgule quand je n'ai pas besoin du point; c'est un vestige de la printdans ce cas. Seul ne vaut pas une édition; mais merci.
Titus

Oh, d'accord ... C'est à l'intérieur de foreach(unpack("C*",$argv[1])as$i)... stupide moi ... Et oui, changer le point pour qu'une virgule ait le même effet ne vaut pas la peine.
Ismael Miguel

4

Perl, 65 octets

Code 53 octets + 12 pour -Mbigint -p.

Merci à @ Dada de m'avoir sauvé 13 octets!

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

Une approche assez simple, mais différente de la plupart d'entre eux, est que le nombre est stocké sous forme binaire et imprimé en décimal. Je suis sûr que cela peut être amélioré, peut-être en stockant les détails dans un tableau. -Mbigintest un peu gênant mais nécessaire.

Usage

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
Déballez mon ami, décompressez! perl -Mbigint -lpE'$_=unpack"B*";say(0+"0b$_"),s/^0+//,y/10/01/while$_>0'(Je ne sais pas comment utiliser unpack habituellement, je viens d'avoir de la chance en recherchant comment convertir une chaîne en binaire ;-))
Dada

Ahhh, j'oublie toujours unpackla syntaxe qui m'échappe toujours! Je vais mettre à jour, merci!
Dom Hastings

Il y a peut-être quelque chose qui devrait aider ... J'ai lu les dix premières lignes des dizaines de fois, mais je devrais vraiment prendre le temps de lire le reste!
Dada

@Dada, je suis sûr que je l'ai lu plusieurs fois, il ne reste jamais dans ... Merci encore - 13 n'est pas un mince exploit! Je devais passer à echo -nest le seul autre changement.
Dom Hastings

4

Pyth, 12 octets

.usi!MjN2 2C

Un programme qui prend en entrée une chaîne entre guillemets et affiche le résultat sous forme de liste d'entiers.

Vérifier tous les cas de test

Comment ça fonctionne

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

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

L'idée principale est de convertir une chaîne d'octets en nombre. Chaque itération imprime la sortie et XOR avec tous les 1 pour progresser vers zéro.


Vous n'avez pas besoin de parenthèses 2**x.bit_length()-1. L'ordre des opérations pour la puissance et la soustraction est supérieur à xor. En outre, cela whilepeut être sur une seule ligne.
mbomb007

Écrivez la boucle while sur une ligne (supprimez la nouvelle ligne et l'
indent

Essayez de démarrer le programme avec P=print, puis d'utiliser à la P()place deprint()
Cyoce

3

Python 2, 117 115 octets

Enregistrement de 2 octets grâce à Cyoce.

Suppose que les entrées sont entre guillemets, par exemple "Inf"

s=input()
n=sum(ord(s[-i-1])<<i*8for i in range(len(s)))
while n:
 print n;k,m=n,1
 while k:k/=2;m*=2
 n^=m-1
print 0

m compte jusqu'au chiffre le plus élevé, donc m-1 qu'un masque XOR pour effectuer l'opération souhaitée. La partie la plus longue convertit l’entrée en séquence de bits initiale.

Exemple:

"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

Vous pouvez remplacer -i-1par~i
Cyoce

3

Ruby, 104 101 100 81 80 65 octets

19 octets sauvés grâce à @WayneConrad!
15 octets sauvés grâce à @philomory!
1 octet enregistré grâce à @LeeW!

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

Prend la saisie via des arguments en ligne de commande.

Inspiré par la réponse de JimmyJohnson en Python


Vous pourrez peut-être sauvegarder quelques caractères en les remplaçant i.to_s(2).rjust 8,'0'par"%08b"%i
Wayne Conrad

En outre, je pense inject(:+)peut être remplacé parjoin
Wayne Conrad

@WayneConrad merci pour l'aide! Je ne sais pas trop comment j'ai oublié
ça

Heureux d'avoir pu aider! Merci de m'avoir appris la méthode #bit_length, que je ne connaissais pas.
Wayne Conrad

1
Passer à unpacksuivi de [0]plutôt que de jouer avec gsubéconomisera 11 octets. Passer à la $*[0]place de gets.chop(en utilisant un argument de ligne de commande au lieu d'une entrée de console) économisera un autre 9, la première ligne devient p n=$*[0].unpack('B*')[0].to_i(2).
philomory

3

Labyrinth , 104 à 103 octets

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

Essayez-le en ligne!

Explication:

Image codée en couleur du code source

Le pointeur d'instruction commence au caractère non mur le plus en haut à gauche (les murs incluent des espaces et toute lettre sauf v).

Orange:

Cette boucle récupère l’entrée caractère par caractère sous forme de code ASCII, en l’ajoutant à la valeur actuelle et en la multipliant par 256.

  • ' No-op
  • ,Poussez le code ASCII du prochain caractère en entrée en haut de la pile ou -1 si EOF. À ce stade, si une entrée a été reçue, le code tournera à droite (en descendant) car le haut de la pile est actif. Sinon, il tournera à gauche car le sommet de la pile est négatif.
  • | Pop les deux premiers éléments de la pile et pousse le résultat d'un OU au niveau des bits.
  • _ Poussez zéro
  • 256Chaque chiffre vu apparaît xet pousse x*10+digit. Donc, ceci combiné avec la poussée zéro précédente pousse 256 au sommet de la pile.
  • *Pop y, pop x, pousse x*y. À ce stade, puisque le haut de la pile est positif, le code tourne à droite pour continuer le tour de la boucle.

Bleu:

  • )Incrémenter le haut de la pile. Lorsque la fin de la saisie est atteinte, le code tourne à gauche pour atteindre ce point avec un -1 sur la pile qui sera incrémenté à zéro.
  • 256 Avoir le haut de la pile 0 nous permet de pousser ce 256.
  • /Pop y, pop xpush x/y(division entière). Puisque nous multiplions l'entrée 256 par chaque boucle, nous devons inverser la dernière multiplication.
  • : Dupliquez le haut de la pile afin d'avoir une copie de la valeur actuelle pour plus tard.
  • ! Déposez le haut de la pile et imprimez la valeur entière sur STDOUT.
  • \ Imprimer une nouvelle ligne.
  • _2 Poussez un deux en haut de la pile.
  • } Déplacez le haut de la pile vers le haut de la pile auxiliaire.

Rouge:

Cette boucle retourne les bits de la valeur actuelle de XOR avec une valeur particulière calculée dans la boucle intérieure (verte). Il émet ensuite la valeur actuelle et quitte le programme si la valeur actuelle est zéro.

  • _ Appuyez sur zéro (flux de contrôle).
  • ; Jeter le haut de la pile (flux de contrôle).
  • :Dupliquez la valeur actuelle. La copie sera utilisée pour calculer le XOR.
  • _ Appuyez sur zéro (flux de contrôle).
  • (Boucle verte)
  • $Pop y, pop x, push x XOR y.
  • :! Dupliquez la valeur actuelle et imprimez la représentation entière.
  • Si la valeur actuelle est 0, nous continuons directement dans le @fichier et nous terminons.
  • \ Imprimer une nouvelle ligne.
  • _2} Appuyez sur 2 et passez à la pile auxiliaire.
  • _1 Appuyez sur 1 (flux de contrôle).

Vert:

Cette boucle calcule la valeur par laquelle nous devons XOR la ​​valeur actuelle. Pour ce faire, vous devez doubler de façon répétée le sommet de la pile auxiliaire tout en divisant par deux le nombre de copies de la valeur actuelle à l'arrêt de la pile principale jusqu'à atteindre 0.

  • _ Appuyez sur zéro (flux de contrôle).
  • ; Ignore la valeur actuelle utilisée uniquement pour appliquer le flux de contrôle.
  • _2 Appuyez sur 2 pour réduire de moitié la valeur actuelle.
  • / Diviser
  • { Déplacez le haut de la pile Aux vers le haut de la pile principale.
  • _2* Double le sommet de la pile
  • } Déplacez le haut de la pile principale vers la pile Aux.
  • _1 Appuyez sur l'un pour contrôler le flux.
  • Après avoir quitté la boucle:
  • ; Jeter la gauche au-dessus de zéro de calculer le XOR.
  • { Déplacez le XOR calculé vers la pile principale.
  • ( Soustrayez un de la valeur XOR.

2

PowerShell v2 +, 158 octets

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}

Ouais, donc, convertir des bases dans PowerShell est vraiment nul . Et nous avons le faire deux fois ici.

OK, il ne s’agit que d’une forboucle $a- c’est-à-dire que nous bouclons tant qu’il $aexiste. Nous finirons par atteindre une chaîne vide (qui est falsey), c'est ainsi que nous terminerons.

La configuration de la boucle, $a=-join([char[]]$args[0]|%{([int][convert]::ToString(+$_,2)).ToString('0'*8)})prend l’entrée $args[0], la charconvertit en une matrice et parcourt chaque caractère. Nous utilisons le .NET [convert]::ToString(int,base)pour convertir chacun en chaîne binaire. Cependant, cela n'inclut pas les zéros au début, nous devons donc la reformuler en tant que [int]et appeler sa .ToString() méthode avec les 8zéros comme masque. Ensuite, ces chaînes sont encapsulées dans des parens et éditées -joinensemble, puis sauvegardées dans $a.

Dans la boucle, nous [convert]::ToInt64(string,base)convertissons le nombre binaire en nombre décimal. Cela reste sur le pipeline et est ensuite vidé lorsque la boucle est réinitialisée (et donc implicitement imprimée). La section suivante effectue les calculs - nous devons .TrimStart()supprimer tous les zéros non significatifs , -split0les scinder en zéros et obtenir un stringtableau de 1s, -replaceceux contenant des zéros, et enfin -joinle tableau revenant avec 1s. Ensuite, la boucle recommence.

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 octets

q256b0{_p2b:!2bj}j

Essayez-le en ligne!

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

REMARQUE: l'ancienne version de 16 octets ne se comportait pas correctement avec des chaînes vides:

q256b{_p2b:!2b}h

Merci également à Dennis d’ avoir suggéré ce pqui économise 1 octet par rapport à l’ N\ajout de nouvelles lignes à la pile.


_p2b:!2benregistre un octet. En outre, vous devriez utiliser l; réchouera si l'entrée contient des espaces.
Dennis

@ Dennis Merci, bien que cela me rend maintenant inquiet si une chaîne vide est un problème.
Linus

Droite. qfonctionnera correctement avec des chaînes vides.
Dennis


1

Retina, 116 octets

Le nombre d'octets suppose un codage ISO 8859-1. La ligne 5 contient des octets non imprimables. C'est 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

Essayez-le en ligne

N'essayez pas cela avec une saisie de plus de deux caractères. (Il utilise plus tard l'interprète en ligne.) Il faut convertir le binaire en unaire avant la décimale. :RÉ

Malheureusement, il y a un zéro final et un saut de ligne, mais j'ai décidé de supposer que c'était correct parce que la sortie est toujours correcte.

Explication

-2`         # Convert ASCII to decimal (ord)
±
s{`±(.)
$&$1
}T`-`_o`±.
[^±]+
$.&
±

\d+         # Decimal to binary
$*
+`(1+)\1
${1}0
01
1


{*(`1       # Loop; Loop print and undo; Convert binary to unary
01
+`10
011
^0+

)M`1        # Unary to decimal; End print and undo
^0+         # Remove leading zeros

T`01`10     # Flip bits; (implicit loop end)

1

Ruby - 70 octets

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

Le programme se ferme avec une exception après avoir terminé, mais je crois comprendre que c'est correct tant que la sortie d'erreur est renvoyée à STDERR plutôt qu'à STDOUT (ce qui est le cas).


1

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

5 octets sauvés grâce à @Cyoce!

2 octets sauvés grâce à @Cyoce et @cleblanc!

Sauvegardé 12 octets grâce à @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;}

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

Je pense que vous pouvez int
omettre

Vous pouvez également enregistrer un octet en convertissant la dernière whileboucle en forboucle
Cyoce

Et vous pouvez changer while(1)àfor(;;)
Cyoce

@ Cyoce, j'ai essayé de supprimer des intdéclarations partout et j'ai eu des gcc -std=89erreurs. Mais merci pour le for(;;)tuyau. Je vais continuer d'essayer de supprimer les intdéclarations :)))
Noodle9

désolé, je ne l'ai pas testé. Je pense que cela fonctionnera si vous les déplacez vers le haut ( i;main(c,v)char**v;{...}). Je suis sur mobile maintenant, donc je ne peux pas en être sûr
Cyoce

0

C, 129 120 117 110 107 105 octets

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

Testé avec

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

sortie

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,

Je pense que vous pouvez passer i=0à la déclaration de iet laisser la section d'initialisation de la forboucle vide
Cyoce

@Cyoce La fonction doit fonctionner à chaque fois qu'elle est appelée et étant donné qu'elle iest implicite, elle doit être initialisée à chaque fois que f (...) est appelé.
Cleblanc

@ Cyoce Vous avez eu raison après tout. La fonction ne se termine que lorsque izéro est à nouveau, elle est donc toujours réutilisable.
Cleblanc


0

C #, 360 359 octets

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

Programme complet:

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

Je ne fais pas C #, mais peut var t="";var f="";être à la var t="",f=""place? Enregistre 5 octets.
CorsiKa

@corsiKa Ouais j'ai essayé ça mais ça m'a donné une erreur, je suppose parce que c'est var et pas string.
Yodle

En fait, string sauvegarde un octet, alors je suppose que je le ferai de cette façon.
Yodle

Aussi, pouvez-vous créer une variable z pour zéro afin d’enregistrer ces mauvaises citations?
CorsiKa

Je viens d’essayer, mais cela augmente le nombre de tours car je ne peux pas remplacer à la fois la chaîne "0" et le caractère '0' :(
Yodle
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.