Distance à quatre

13

Ce défi est basé sur cette vidéo . Je vous recommande de le regarder avant d'essayer ce défi.

Nous définissons d'abord une fonction. Cette fonction ( OEIS ) prend un entier n en entrée et génère le nombre de lettres dans la représentation anglaise de n (sans espaces ni tirets). Par exemple, "trois" a 5 lettres, donc 3 correspond à 5.

Comme démontré dans la vidéo en commençant par un nombre répétitif, ce processus aboutira finalement à un quatre, qui se mappera pour lui-même pour toujours.

Voici un graphique orienté brut montrant les orbites des nombres inférieurs à 16:

  12 11
    \|      
15 2 6 1 10 14 13
  \ \|/ /  /  /
   7 3-/  8--/
    \|   /
 9 0 5--/
  \ \|
   \-4

Votre défi est de déterminer le nombre d'étapes qu'un nombre prendra (ou le nombre de fois que cette fonction doit être appliquée à un nombre) avant d'atteindre quatre (c'est-à-dire le niveau sur le graphique dirigé illustré).

Former des nombres anglais

Voici une brève explication sur la façon de former des mots anglais pour ce défi:

Les nombres de un à dix-neuf sont:

un, deux, trois, quatre, cinq, six, sept, huit, neuf, dix, onze, douze, treize, quatorze, quinze, seize, dix-sept, dix-huit, dix-neuf

Pour les nombres supérieurs à dix-neuf, le processus est le suivant:

Si le nombre contient des centaines, commencez par le nom du chiffre à la place des centaines et «cent».

par exemple

100 -> "onehundred"

Si le reste est inférieur à vingt, ajoutez la représentation anglaise du reste.

par exemple

714 -> "sevenhundredfourteen"

Sinon, si le chiffre des dizaines n'est pas nul, ajoutez la représentation appropriée:

2-> twenty
3-> thirty
4-> forty
5-> fifty
6-> sixty
7-> seventy
8-> eighty
9-> ninety

par exemple

470 -> "fourhundredseventy"

Enfin, s'il y a un chiffre, ajoutez sa représentation

par exemple

681 -> "sixhundredeightyone"

Autres stipulations

  • Pour les nombres supérieurs à cent, vous devez omettre le "et" lors du comptage du nombre de lettres. Par exemple, 577 est "fivehundredseventyseven" qui contient 23 lettres.

  • Votre programme doit accepter tous les entiers supérieurs à 0 et inférieurs à 1 000 en entrée via des méthodes standard.

  • Votre programme doit générer le nombre d'étapes requises pour les méthodes de sortie standard.

  • Il s'agit de codegolf, donc la solution avec le moins d'octets est gagnante.

Cas de test

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 
Post Rock Garf Hunter
la source
1
Associé, je pensais que c'était un dupe, mais je ne le trouve pas.
James
Qu'est-il arrivé à "et"? Ou plutôt, pourquoi laisser de côté et?!
Jonathan Allan
@JonathanAllan cuz 'Murica
LegionMammal978

Réponses:

5

JavaScript (ES6), 106 octets

f=(n,a="03354435543668877998")=>n-4&&1+f(7*(n>99)-(-a[n/100|0]-(a[n%=100]||a[n%10])-"0066555766"[n/10|0]))

Les chaînes semblent être le meilleur moyen d'encoder la longueur, malgré la surcharge de conversion numérique.

Neil
la source
Mon Dieu, c'est presque exactement à quoi ressemblait ma réponse (presque publiée), seulement 11 octets de moins.
ETHproductions
@ETHproductions Heureusement que j'ai joué au golf à 16 octets avant de le poster alors!
Neil
2

Python, avec num2words, 97113115 94 93 92 octets

+16 octets (oublié la césure que num2words applique qui ne change pas les résultats de l' un des cas de test, même si 23et 577ont chacun un trait d' union)
+2 octets (oublié d'inclure f=bien récursive)
-20 octets (utilisation re)
-8 octets grâce à @Wheat Wizard (utiliser ~, remplacer n!=4par n-4et ... importation d'une ligne> _ <)
-1 octet grâce à @Cyoce (espace depuis 4 and)

import re,num2words as w
f=lambda n:n-4and-~f(len(re.sub('\W|and','',w.num2words(n))))

Compte juste le nombre d'étapes; fonctionne aussi pour les entiers énormes et négatifs (\W trouve les espaces, les virgules et les tirets dans le résultat num2words):

>>> for test in (1,4,7,23,577,600,-1*2**96,3**96):
...     print('test: {0}  ->  {1}'.format(test, f(test)))
...
test: 1  ->  3
test: 4  ->  0
test: 7  ->  2
test: 23  ->  5
test: 577  ->  6
test: 600  ->  4
test: -79228162514264337593543950336  ->  4
test: 6362685441135942358474828762538534230890216321  ->  5

Voici ce dernier cas, étape par étape:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five
Jonathan Allan
la source
1
f=
N'avez-
1
Essayez import re,num2words as rau lieu des deux instructions différentes.
Post Rock Garf Hunter
1
n-4est la même chose quen!=4
Post Rock Garf Hunter
1
@WheatWizard num2wordsest w, reest toujours re- notez que le module et la fonction sont appelésnum2words
Jonathan Allan
1
Ok dernier, and 1+peut être remplacé par and-~pour économiser un octet
Post Rock Garf Hunter
1

Pyth - 54 octets

Va essayer de refactoriser.

KjC"Y©åláóê¤"Ttl.u?<NyT@KNs+V@LKJ_jNT[Z@jC"Ckg"ThtJ7

Suite de tests .

Maltysen
la source
1

Mathematica, 89 octets

Length@FixedPointList[StringLength@StringReplace[IntegerName@#,{" "->"","-"->""}]&,#]-2&

Mathematica typique: les fonctions intégrées sont bonnes, les noms de fonctions longs sont mauvais. FixedPointListapplique son premier argument (une fonction) au deuxième argument à plusieurs reprises jusqu'à ce que la réponse ne change pas, répertoriant tous les résultats; les résultats incluent l'entrée d'origine et deux copies de la sortie répétée, d'où la-2 la fin. Intégré de MathematicaIntegerName contient des espaces et des tirets, nous devons donc nous en débarrasser à la main.

De façon ennuyeuse, IntegerNamela sortie de contient le caractère "-" (Unicode # 8208) plutôt que des tirets normaux; c'est pourquoi cette soumission est de 89 octets au lieu de 88. (Et je ne pouvais pas faire précéder le code ci-dessus avec quatre espaces et lui faire accepter le caractère Unicode - toute aide? - donc le code ci-dessus ne fonctionnera pas exactement s'il est coupé et collé .)

Greg Martin
la source
1

Python 2.7, 344 216 208 octets:

x=`input()`;c=0;y=lambda v:dict(zip(range(0,10),[0]+v));l=[3,3,5,4,4,3,5,5,4];d=y(l);e=y([3,6,6,6,5,5,7,7,6]);f=y([i+7for i in l])
while x!='4':x=`sum([q[int(r)]for q,r in zip([d,e,f],x[::-1])])`;c+=1
print c

N'utilise pas de bibliothèques externes contrairement aux autres réponses Python. Prend l'entrée stdinet les sorties dansstdout .

Repl.it avec tous les cas de test!

Explication

Crée d'abord 3 dictionnaires, chacun associant la longueur des représentations de mots anglais de chaque nombre au nombre qu'il représente dans l'intervalle fermé [1,9], respectivement à la place des dizaines et des centaines. Par exemple, la première entrée du dictionnaire dest 1:3telle qu'elle 1est orthographiéeone en anglais et comporte des 3lettres.

Ensuite, chaque place de chiffres dans une certaine chaîne xest attribuée à son dictionnaire correspondant, après quoi chaque numéro de chaque place correspond à sa valeur dans le dictionnaire correspondant. Par exemple, supposons que le numéro d'entrée était 23. L' 20endroit dans les dizaines serait apparié avec le dictionnaire e, dans lequel il est apparié 6, et l' 3endroit dans les un serait apparié avec le dictionnaire d, dans lequel il est apparié 5. Ces chiffres appariés sont ensuite additionnés pour représenter la longueur de la représentation anglaise du numéro, qui est attribué à xune chaîne et, àx!='4' la boucle while continue, incrémentée cde1chaque fois pour représenter le nombre de mesures prises jusqu'à présent. Par conséquent, 23correspondrait à nombre total d'étapes.11, qui à son tour correspondrait à 6ce qui se tournerait vers 3, puis vers 5et enfin vers 4, résultant en5

Enfin, une fois la boucle terminée, cest émis pour stdoutreprésenter la "Distance à quatre", ce qui serait le cas dans ce cas 5.

R. Kap
la source
1

Java, 556 295 octets

Merci à @KevinCruijssen pour avoir économisé 261 octets

  void int(n) {int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;while(n>0){if(n/100>0)c+=(s[n/100]+7);else {if(n>0&n<25){c+=s[n];break;}else{c+=s[(n/10)+22];}}n=n%t;t=t/10;}while(c!=4){v++;c=s[c];}System.out.print(v);}


Non golfé:

  void int(n) {

    int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};
     int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;
         while(n>0){
            if(n/100>0)
                c+=(s[n/100]+7);
            else {if(n>0&n<25){
                c+=s[n];
            break;
            }
            else{
                c+=s[(n/10)+22];

            }
            }
            n=n%t;
            t=t/10;
        }

        while(c!=4)
        {
            v++;
        c=s[c];
        }
System.out.print(v);
}
Numberknot
la source
Je pense que vous avez une erreur dans votre code, car ce s++n'est pas possible sur un String-array ..: S
Kevin Cruijssen
@KevinCruijssen Je déclare S (compteur) comme INT et STRING aussi .... java décide automatiquement qu'il s'agit d'un INT.
Numberknot
Eh bien, si je lance votre code dans ideone ou mon Eclipse IDE , il échoue parce que vous avez deux s.. BTW, vous pouvez jouer au golf votre code par une grande quantité tout à fait comme ceci:int c(int n){int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8,6,9,9,11,10,6,5,5,5,7,6,6},c=0,t=(int)Math.pow(10,(int)Math.log10(n)),x=1;while(n>0)if(n/100>0)c+=s[n/100]+7;else{if(n>0&n<25){c+=s[n];break;}else c+=s[(n/10)+22];}n%=t;t/=10;}for(;c!=4;x++,c=s[c]);return x;}
Kevin Cruijssen
Je suis choqué ... ce qui arrive à mon code et merci @ KevinCruijssen..et je le corrige ... Merci encore.
Numberknot
Np :) Je pense qu'il pourrait être joué un peu plus en quelque sorte sans utiliser l'if-else et y pénétrer (mais je laisse cela à quelqu'un d'autre), mais votre code initial était une excellente base pour relever le défi, alors +1 de moi.
Kevin Cruijssen