Question

Le puzzle

Un peu casse-tête que j'ai entendu alors que j'étais à l'école secondaire est allé quelque chose comme ça...

  • L'interlocuteur me demandait de lui donner un numéro;
  • Lors de l'audition sur le nombre, la question serait de faire une sorte de transformation sur lui à plusieurs reprises (par exemple, il pourrait dire dix est de trois) jusqu'à ce que finalement arriver au nombre de 4 (à quel point il serait d'en finir avec quatre est magique).
  • N'importe quel nombre semble être transformable en quatre, finalement, n'importe quoi.

L'objectif était d'essayer de comprendre la transformation de la fonction et ensuite être en mesure de manière fiable proctor ce puzzle vous-même.

La solution

La transformation de la fonction à n'importe quelle étape était pour

  • Prendre le numéro en question,
  • Compter le nombre de lettres dans son mot anglais représentation, en ignorant un trait d'union ou des espaces ou des "et" (par exemple, "dix" est composé de 3 lettres, "trente-quatre" a 10 lettres, "les cent quarante-trois" a 20 lettres).
  • Retour que le nombre de lettres.

Pour tous les numéros que j'ai jamais pris la peine de tester, cela converge vers 4.Depuis "quatre" dispose également de quatre lettres, il y aurait une boucle infinie ici;au lieu de cela, il est simplement appelé la magie par convention à la fin de la séquence.

Le défi

Votre défi est de créer un morceau de code qui va lire un certain nombre de l'utilisateur et ensuite imprimer les lignes montrant la transformation de la fonction en cours de manière répétitive jusqu'à ce que "quatre est magique" est atteint.

Plus précisément:

  1. Les Solutions doivent être de terminer les programmes en eux-mêmes.Ils ne peuvent pas être purement et simplement les fonctions qui prennent en un nombre-- facteur dans l'entrée.
  2. D'entrée doit être lues sur l'entrée standard.(Tuyauterie de "echo" ou à l'aide de la redirection d'entrée est correct, car ce qui va aussi à partir de stdin)
  3. L'entrée doit être sous forme numérique.
  4. Pour chaque application de la transformation de la fonction, une ligne doit être imprimé: a is b., où a et b sont des formes de la les chiffres dans la transformation.
  5. Les points (périodes) SONT nécessaires!
  6. La dernière ligne devrait naturellement dire, 4 is magic..
  7. Le code doit produire de sortie correcte pour tous les nombres à partir de De 0 à 99.

Exemples:

> 4
4 is magic.

> 12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.

> 42
42 is 8.
8 is 5.
5 is 4.
4 is magic.

> 0
0 is 4.
4 is magic.

> 99
99 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.

Le gagnant est le la plus courte présentation par le code source de nombre de caractères ce qui est également correct.

BONUS

Vous pouvez également essayer d'écrire une version du code qui affiche les NOMS en ANGLAIS pour les numéros à chaque application de la transformation de la fonction.L'entrée d'origine est toujours en numérique, mais les lignes de sortie doit avoir la forme de mot de le nombre.

(Double bonus pour dessiner des formes avec votre code)

(EDIT) Quelques précisions:

  1. Je ne veux pas la parole à apparaître sur les deux côtés dans tous les cas, par exemple, Nine is four. Four is magic.
  2. Je ne m'inquiète pas à propos de la capitalisation, de la bien que.Et je n'aime pas la façon dont vous avez séparé le mot de jetons, mais ils doivent être séparés: ninety-nine c'est bien, ninety nine c'est bien, ninetynine n'est pas correct.

Je suis en train d'étudier ces une catégorie distincte pour les bonus de concurrence en ce qui concerne le défi, donc, si vous allez pour cela, ne vous inquiétez pas au sujet de votre code étant plus longue que la version numérique.

N'hésitez pas à soumettre une solution pour chaque version.

Était-ce utile?

La solution

GolfScript - 101 96 93 92 91 90 94 86 octets

90 → 94:De sortie fixe pour les multiples de 10.
94 → 86:Restructuré code.À l'aide de la base de 100 pour supprimer les caractères non-imprimables.
86 → 85:Plus courte de fonte à la chaîne.

{n+~."+#,#6$DWOXB79Bd")base`1/10/~{~2${~1$+}%(;+~}%++=" is "\".
"1$4$4-}do;;;"magic."

Autres conseils

Perl, environ 147 char

Vaguement basé sur la Platine Azure solution:

               chop
              ($_.=
              <>);@
             u="433
            5443554
           366  887
          798   866
         555    766
        "=~     /\d
       /gx      ;#4
      sub       r{4
     -$_        ?$_
    <20         ?$u
   [$_          ]:(
  $'?           $u[
 $']            :0)
+$u[18+$&]:magic}print"
$_ is ",$_=r(),'.'while
                /\d
                /x;
                444

Common Lisp 157 Caractères

Nouvelle plus conforme version, maintenant la lecture de la forme de l'entrée standard et ignorant des espaces et des tirets:

(labels((g (x)(if(= x 4)(princ"4 is magic.")(let((n(length(remove-if(lambda(x)(find x" -"))(format nil"~r"x)))))(format t"~a is ~a.~%"x n)(g n)))))(g(read)))

Dans une forme lisible:

 (labels ((g (x)
           (if (= x 4)
            (princ "4 is magic.")
            (let ((n (length (remove-if (lambda(x) (find x " -"))
                                        (format nil "~r" x)))))
               (format t"~a is ~a.~%" x n)
               (g n)))))
    (g (read)))

Et quelques essais:

>24
24 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.

>23152436
23152436 is 64.
64 is 9.
9 is 4.
4 is magic.

Et le bonus de la version, à 165 caractères:

 (labels((g(x)(if(= x 4)(princ"four is magic.")(let*((f(format nil"~r"x))(n(length(remove-if(lambda(x)(find x" -"))f))))(format t"~a is ~r.~%"f n)(g n)))))(g(read)))

Donner

>24
twenty-four is ten.
ten is three.
three is five.
five is four.
four is magic.

>234235
two hundred thirty-four thousand two hundred thirty-five is forty-eight.
forty-eight is ten.
ten is three.
three is five.
five is four.
four is magic.

Python 2.x, 144 150 154 166 caractères

C'est ce qui sépare le nombre en dizaines et les uns et les résumer.La propriété indésirable de la pseudo-opérateur ternaire a and b or c que c est renvoyée si b est 0 est maltraité ici.

n=input()
x=0x4d2d0f47815890bd2
while n-4:p=n<20and x/10**n%10or 44378/4**(n/10-2)%4+x/10**(n%10)%10+4;print n,"is %d."%p;n=p
print"4 is magic."

La précédente version naïve (150 caractères maximum).Juste coder toutes les longueurs comme un entier.

n=input()
while n-4:p=3+int('1yrof7i9b1lsi207bozyzg2m7sclycst0zsczde5oks6zt8pedmnup5omwfx56b29',36)/10**n%10;print n,"is %d."%p;n=p
print"4 is magic."

C - avec le nombre de mots

445 431 427 421 399 386 371 359* 356 354 348 347 caractères

C'est tout.Je ne pense pas que je peux faire de cette plus courte.

Tous les retours à la ligne sont pour des raisons de lisibilité et peut être retiré:

i;P(x){char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,
fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,
4RmagicS,zero,";while(x--)if(*++p-44&&!x++)*p>95|*p<48?putchar(*p),++i:P(*p-48);
}main(c){for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))P(c?c>19?P(c/10+18),
(c%=10)&&putchar(45):0,c:37);P(36);}

Ci-dessous, c'est un peu unminified, mais encore assez difficile à lire.Voir ci-dessous pour une version plus lisible.

i;
P(x){
    char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";
    while(x--)
        if(*++p-44&&!x++)
            *p>95|*p<48?putchar(*p),++i:P(*p-48);
}
main(c){
    for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))
        P(c?
            c>19?
                P(c/10+18),
                (c%=10)&&
                    putchar(45)
            :0,
            c
        :37);
    P(36);
}

Élargi et commenté:

int count; /* type int is assumed in the minified version */

void print(int index){ /* the minified version assumes a return type of int, but it's ignored */
    /* see explanation of this string after code */
    char *word =
        /* 1 - 9 */
        ",one,two,three,four,five,six,sM,eight,nine,"
        /* 10 - 19 */
        "tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,"
        /* 20 - 90, by tens */
        "twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,"
        /* lookup table */
        "en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";

    while(index >= 0){
        if(*word == ',')
            index--;
        else if(index == 0) /* we found the right word */
            if(*word >= '0' && *word < 'a') /* a compression marker */
                print(*word - '0'/*convert to a number*/);
            else{
                putchar(*word); /* write the letter to the output */
                ++count;
            }
        ++word;
    }
}
int main(int argc, char **argv){ /* see note about this after code */
    scanf("%d", &argc); /* parse user input to an integer */

    while(argc != 4){
        count = 0;
        if(argc == 0)
            print(37/*index of "zero"*/);
        else{
            if(argc > 19){
                print(argc / 10/*high digit*/ + 20/*offset of "twenty"*/ - 2/*20 / 10*/);
                argc %= 10; /* get low digit */

                if(argc != 0) /* we need a hyphen before the low digit */
                    putchar('-');
            }
            print(argc/* if 0, then nothing is printed or counted */);
        }
        argc = count;
        print(34/*" is "*/);
        print(argc); /* print count as word */
        print(35/*".\n"*/);
    }
    print(36/*"four is magic.\n"*/);
}

Sur la chaîne encodée à proximité du début

Les noms de nombres sont compressés à l'aide d'une très simple schéma.Fréquemment utilisé des sous-chaînes sont remplacés par un caractère indices dans le nom du tableau.Une "table de correspondance" de nom supplémentaire des entrées est ajouté à la fin pour les sous-chaînes non utilisés dans leur intégralité dans le premier set.Les recherches sont récursives:les inscriptions peuvent se rapporter à d'autres entrées.

Par exemple, le nom compressé pour 11 est elM.L' print() fonction des sorties des personnages e et l (bas-de-casse "L", pas le nombre de '1') mot à mot, mais il trouve ensuite le M, donc il appelle lui-même avec l'index de la 29e entrée ASCII ('M' ASCII '0') dans la table de recherche.Cette chaîne est evL, donc c'sorties e et v, puis appelle lui-même à nouveau avec l'index de la 28e entrée dans la table de recherche, qui est en, et est sortie de verbatim.Ceci est utile parce que en est également utilisé dans eL pour een (utilisé après eight dans eighteen), qui est utilisé dans tO pour teen (utilisé pour tous les autres -teen nom).

Ce schéma des résultats d'une manière très significative la compression du nombre des noms, tout en ne nécessitant qu'une petite quantité de code à décompresser.

Les virgules au début et à la fin de la chaîne compte de la manière simpliste que les sous-chaînes sont dans cette chaîne.L'ajout de deux personnages ici permet d'économiser plus de personnages plus tard.

Au sujet de l'abus de main()

argv est ignoré (et donc pas déclaré dans la version compressée), argc la valeur est ignorée, mais l'espace de stockage est réutilisé pour contenir le nombre actuel.Cette juste m'évite d'avoir à déclarer une variable supplémentaire.

Au sujet de l'absence de #include

Certains se plaignent que l'omission #include <stdio.h> est de la triche.Il n'est pas du tout.La donnée est tout à fait légal programme C qui compile correctement sur n'importe quel compilateur C je connais (mais avec des mises en garde).Manque de protoypes pour les fonctions de stdio, le compilateur suppose qu'ils sont cdecl fonctions de renvoi int, et la confiance que vous savez quels sont les arguments à passer.Les valeurs de retour sont ignorés dans ce programme, de toute façon, et ils sont tous cdecl ("C" convention d'appel) fonctions, et nous ne sommes en effet de savoir quels sont les arguments à passer.

Sortie

La sortie est prévu:

0
zero is four.
four is magic.
1
one is three.
three is five.
five is four.
four is magic.
4
four is magic.
20
twenty is six.
six is three.
three is five.
five is four.
four is magic.
21
twenty-one is nine.
nine is four.
four is magic.

* La version précédente à côté de la plaque sur les deux parties de la spécification:il n'a pas de poignée de zéro, et il a pris d'entrée sur la ligne de commande au lieu de l'entrée standard.La manipulation ajouter des zéros de caractères, mais à l'aide de stdin au lieu de ligne de commande args, ainsi que quelques autres optimzations enregistré le même nombre de caractères, résultant en un lavage.

Les exigences ont été modifiées afin de préciser que le nombre de mots doit être imprimé sur les deux côtés de " est ".Cette nouvelle version répond à cette condition, et met en œuvre un couple plus d'optimisations de (plus de) la prise en compte de la taille supplémentaire nécessaire.

J, 107 112 caractères

'4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.
(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊꥘誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:

(Retour à la ligne pour des raisons de lisibilité uniquement)

D'utilisation et de sortie:

    '4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊꥘誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:12
12 is 6.    
6 is 3.     
3 is 5.     
5 is 4.     
4 is magic. 

T-SQL, 413 451 499 caractères

CREATE FUNCTION d(@N int) RETURNS int AS BEGIN
Declare @l char(50), @s char(50)
Select @l='0066555766',@s='03354435543668877987'
if @N<20 return 0+substring(@s,@N+1,1) return 0+substring(@l,(@N/10)+1,1) + 0+(substring(@s,@N%10+1,1))END
GO
CREATE proc M(@x int) as BEGIN
WITH r(p,n)AS(SELECT p=@x,n=dbo.d(@x) UNION ALL SELECT p=n,n=dbo.d(n) FROM r where n<>4)Select p,'is',n,'.' from r print '4 is magic.'END

(Pas que je suggère sérieusement que vous le ferais...vraiment, je voulais juste écrire un CTE)

Pour l'utiliser:

M 95

Retourne

p                n
----------- ---- -----------
95          is   10.
10          is   3.
3           is   5.
5           is   4.
4 is magic.

Java (avec passe-partout), 308 290 286 282 280 caractères

class A{public static void main(String[]a){int i=4,j=0;for(;;)System.out.printf("%d is %s.%n",i=i==4?new java.util.Scanner(System.in).nextInt():j,i!=4?j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:"magic");}}

Je suis sûr que Groovy serait de se débarrasser de beaucoup de que.

Explication et mise en forme (tous les commentaires, les retours à la ligne et leader/suiveur espaces supprimés en compte):

Raisonnablement simple, mais

//boilerplate
class A{
   public static void main(String[]a){
      //i is current/left number, j right/next number.  i=4 signals to start
      //by reading input
      int i=4,j=0;
      for(;;)
         //print in the form "<left> is <right>."
         System.out.printf(
            "%d is %s.%n",
            i=i==4?
               //<left>: if i is 4 <left> will be a new starting number
               new java.util.Scanner(System.in).nextInt():
               //otherwise it's the next val
               j,
            i!=4?
               //use string to map number to its length (:;< come after 9 in ASCII)
               //48 is value of '0'.  store in j for next iteration
               j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:
               //i==4 is special case for right; print "magic"
               "magic");
   }
}

Edit:Ne plus utiliser l'hexagone, c'est moins de touches

Windows PowerShell:152 153 184 octets

basé sur la solution précédente, avec plus de l'influence d'autres solutions

$o="03354435543668877988"
for($input|sv b;($a=$b)-4){if(!($b=$o[$a])){$b=$o[$a%10]-48+"66555766"[($a-$a%10)/10-2]}$b-=48-4*!$a
"$a is $b."}'4 is magic.'

C, 158 caractères

main(n,c){char*d="03354435543668877988";for(scanf("%d",&n);n-4;n=c)printf("%d is %d.\n",n,c=n?n<19?d[n]-48:d[n%10]-"_,**+++)**"[n/10]:4);puts("4 is magic.");}

(à l'origine basée sur Vlad code Python, emprunté un truc de Tom Sirgedas' C++ solution pour prendre un peu plus de caractères)

version étendue:

main(n, c) {
    char *d = "03354435543668877988";
    for (scanf("%d",&n); n-4; n = c)
        printf("%d is %d.\n", n, c = n ? n<19 ? d[n]-48 : d[n%10] - "_,**+++)**"[n/10]  : 4);
    puts("4 is magic.");
}

Python, 129 133 137 148 caractères

Comme un warm-up, voici ma première version (améliore le couple de caractères sur le meilleur Python).

PS.Après quelques rédactions maintenant, il est d'une vingtaine de char, qui est plus court:

n=input()
while n-4:p=(922148248>>n/10*3&7)+(632179416>>n%10*3&7)+(737280>>n&1)+4*(n<1);print n,'is %d.'%p;n=p
print'4 is magic.'

C#:210 Caractères.

Écrasé:

using C=System.Console;class B{static void Main(){int
x=0,y=int.Parse(C.ReadLine());while(x!=4)C.Write((x=y)+" is {0}.\n",x==4?"magic":""+(y=x==0?4:"03354435543668877988"[x<20?x:x%10]+"0066555766"[x/10]-96));}}

Élargi:

using C=System.Console;
class B
{
    static void Main()
    {
        int x=0,y=int.Parse(C.ReadLine());
        while(x!=4)
            C.Write((x=y)+" is {0}.\n",
                x==4?
                     "magic":
                     ""+(y= x==0?
                                4:
                                "03354435543668877988"[x<20?x:x%10]+
                                "0066555766"[x/10]-96)
                   );
    }
}

Astuces cette approche utilise:

  • Créer une table de recherche pour le numéro de la longueur des noms basés sur les chiffres qui apparaissent dans le nombre.
  • L'utilisation du tableau des caractères de recherche sur une chaîne, et un char de l'arithmétique au lieu d'un tableau numérique.
  • Utilisation de la classe nom de l'aliasing à court Console. pour C.
  • Utiliser le conditionnel (ternaire) opérateur (?:) au lieu de if/else.
  • L'utilisation de la \n avec Write code d'échappement au lieu de WriteLine
  • Utiliser le fait que le C# est un ordre défini d'évaluation pour permettre à des affectations à l'intérieur de la Write appel de fonction
  • Utiliser l'assignation des expressions pour éliminer les états, et donc extra accolades

Perl:148 caractères

(Perl: 233 181 212 206 200 199 198 185 179 149 148 caractères)

  • Déplacé exceptions hachage dans l'unité de tableau.Il en est résulté dans mon être en mesure de coupe d'un grand nombre de personnages :-)
  • mobrule a souligné un méchant bug.Quick fix ajoute à 31 caractères, ouch!
  • Refait de zéro cas particulier, une légère golf aussi bien fait.
  • Liste directe d'accès à usage unique plutôt que de stocker à la matrice?L'enfer oui!
  • DONC, BEAUCOUP de REFACTORING pour juste UN maudit personnage.Cela, vraiment, est la vie d'un golfeur.:-(
  • Oups, facile d'espaces correctif.198 maintenant.
  • Refait quelques code redondant.
  • Dernier retour en mot clé r est inutile, rasée peu plus large.
  • Massive refactoring par des commentaires;malheureusement je n'ai pu l'obtenir à 149 parce que j'ai eu à corriger un bug qui était présent dans mon code précédent et les commentateurs " versions.
  • En essayant de mot nu "magie".

Let's get ce bal avec une modeste tentative en Perl.

@u=split'','4335443554366887798866555766';$_=<>;chop;print"$_ is ".($_=$_==4?0:$_<20?$u[$_]:($u[$_/10+18]+($_%10&&$u[$_%10]))or magic).".
"while$_

Astuces:

De trop!

JavaScript 1.8 (SpiderMonkey) - 153 Caractères

l='4335443554366887798866555766'.split('')
for(b=readline();(a=+b)-4;print(a,'is '+b+'.'))b=a<20?l[a]:+l[18+a/10|0]+(a%10&&+l[a%10])
print('4 is magic.')

Utilisation: echo 42 | js golf.js

Sortie:

42 is 8.
8 is 5.
5 is 4.
4 is magic.

Avec bonus - 364 caractères

l='zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty thirty fourty fifty sixty seventy eighty ninety'.split(' ')
z=function(a)a<20?l[a]:l[18+a/10|0]+(a%10?' '+l[a%10]:'')
for(b=+readline();(a=b)-4;print(z(a),'is '+z(b)+'.'))b=z(a).replace(' ','').length
print('four is magic.')

Sortie:

ninety nine is ten.
ten is three.
three is five.
five is four.
four is magic.

Haskell, 224 270 caractères

o="43354435543668877988"
x!i=read[x!!i]
n x|x<20=o!x|0<1="0066555766"!div x 10+o!mod x 10
f x=zipWith(\a b->a++" is "++b++".")l(tail l)where l=map show(takeWhile(/=4)$iterate n x)++["4","magic"]
main=readLn>>=mapM putStrLn.f

Et un peu plus lisible

ones = [4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8]
tens = [0,0,6,6,5,5,5,7,6,6]

n x = if x < 20 then ones !! x else (tens !! div x 10) + (ones !! mod x 10)

f x = zipWith (\a b -> a ++ " is " ++ b ++ ".") l (tail l)
    where l = map show (takeWhile (/=4) (iterate n x)) ++ ["4", "magic"]
    
main = readLn >>= mapM putStrLn . f

C++ Stdio version minifiée:196 caractères

#include <cstdio>
#define P;printf(
char*o="43354435543668877988";main(int p){scanf("%d",&p)P"%d",p);while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]P" is %d.\n%d",p,p);}P" is magic.\n");}

C++ Iostreams version minifiée:195 caractères

#include <iostream>
#define O;std::cout<<
char*o="43354435543668877988";main(int p){std::cin>>p;O p;while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]O" is "<<p<<".\n"<<p;}O" is magic.\n";}

D'origine, de l'onu-compacte:344 caractères

#include <cstdio>

int ones[] = { 4, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8 };
int tens[] = { 0, 3, 6, 6, 5, 5, 5, 9, 6, 6 };

int n(int n) {
    return n<20 ? ones[n] : tens[n/10] + ones[n%10];
}

int main(int p) {
    scanf("%d", &p);
    while(p!=4) {
        int q = n(p);
        printf("%i is %i\n", p, q);
        p = q;
    }
    printf("%i is magic\n", p);
}

Delphi:329 caractères

Ligne Unique Version:

program P;{$APPTYPE CONSOLE}uses SysUtils;const S=65;A='EDDFEEDFFEDGGIIHHJII';B='DGGFFFJGG';function Z(X:Byte):Byte;begin if X<20 then Z:=Ord(A[X+1])-S else Z:=(Ord(B[X DIV 10])-S)+Z(X MOD 10)end;var X,Y:Byte;begin Write('> ');ReadLn(X);repeat Y:=Z(X);WriteLn(Format('%d is %d.',[X,Y]));X:=Y;until X=4;WriteLn('4 is magic.');end.

Formaté:

program P;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const
  S = 65;
  A = 'EDDFEEDFFEDGGIIHHJII';
  B = 'DGGFFFJGG';

function Z(X:Byte):Byte;
begin
  if X<20
  then Z := Ord(A[X+1])-S
  else Z := (Ord(B[X DIV 10])-S) + Z(X MOD 10);
end;

var
  X,Y: Byte;

begin
  Write('> ');
  ReadLn(X);

  repeat
    Y:=Z(X);
    WriteLn(Format('%d is %d.' , [X,Y]));
    X:=Y;
  until X=4;

  WriteLn('4 is magic.');
end.

Probablement de la place pour un peu plus pressant...:-P

C# 314 286 283 274 289 273 252 caractères.

Écrasé:

252 

Normal:

using C = System.Console;
class P
{
    static void Main()
    {
        var x = "4335443554366877798866555766";
        int m, o, v = int.Parse(C.ReadLine());
        do {
            C.Write("{0} is {1}.\n", o = v, v == 4 ? (object)"magic" : v = v < 20 ? x[v] - 48 : x[17 + v / 10] - 96 + ((m = v % 10) > 0 ? x[m] : 48));
        } while (o != 4);
        C.ReadLine();
    }
}

Edit Dykam:Fait assez attention les insertions et modifications:

  • Changé l'l.ToString() dans un plâtre à object de la string "magic".
  • Créé une variable temporaire o, afin que je puisse déplacer le break en dehors de la for boucle, qui est, résultant en une do-while.
  • Inline l' o cession, ainsi que le v cession, continueing en insérant le calcul de l dans les arguments de la fonction tout à fait, en supprimant la nécessité pour les l.Aussi inline à la cession de m.
  • Retiré de l'espace dans les int[] x, int[]x est légitime aussi.
  • Essayé de transformer le tableau en une chaîne de transformation, mais la using System.Linq a trop pour que cela soit une amélioration.

Edit 2 Dykam Changé le tableau int d'un char array/string, ajoutée bon arithmics pour corriger cela.

Lua, 176 Caractères

o={[0]=4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8}t={3,6,6,5,5,5,7,6,6}n=0+io.read()while n~=4 do a=o[n]or o[n%10]+t[(n-n%10)/10]print(n.." is "..a..".")n=a end print"4 is magic."

ou

  o={[0]=4,3,3,5,4,4
  ,3,5,5,4,3,6,6,8,8
  ,7,7,9,8,8}t={3,6,
   6,5,5,5,7,6,6}n=
   0+io.read()while
   n ~= 4 do a= o[n
   ]or o[n%10]+t[(n
   -n%10)/10]print(
n.." is "..a.."." )n=a
end print"4 is magic."

C - sans numéro de mots

180 175* 172 167 caractères

Tous les retours à la ligne sont pour des raisons de lisibilité et peut être retiré:

i;V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}main(c){for(scanf("%d",&c);
c-4;)i=c,printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);puts(
"4 is magic.");}

Légèrement unminified:

i;
V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}
main(c){
    for(scanf("%d",&c);c-4;)
        i=c,
        printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);
    puts("4 is magic.");
}

* La version précédente à côté de la plaque sur les deux parties de la spécification:il n'a pas de poignée de zéro, et il a pris d'entrée sur la ligne de commande au lieu de l'entrée standard.La manipulation de zéro caractères ajoutés, mais en utilisant stdin au lieu de ligne de commande args sauvé, même plus, pour un montant net d'épargne.

perl, 123 122 caractères

Viens de réaliser qu'il n'y a pas d'obligation de sortie sur la sortie standard, de sorte que la sortie vers STDERR et tomber d'un autre personnage.

@u='0335443554366887798866555766'=~/./g;$_+=<>;warn"$_ is ",$_=$_-4?$_<20?$u[$_]||4:$u[chop]+$u[$_+18]:magic,".\n"until/g/

Et, une version qui renvoie énoncé les numéros:

279 278 276 280 caractères

@p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2] $n[$n%10]":Zero}$p+=<>;warnt$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/

Tout qui répond à la spécification, il n'est pas à 100% bien formaté.Il renvoie à un espace en trop après les numéros se terminant par un zéro.La spec dit:

"Je n'aime pas la façon dont vous avez séparé le mot de jetons, mais ils doivent être séparés"

C'est le genre de weaselly bien.Plus version correcte à

282 281 279 283 caractères

@p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("\x8",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2]-$n[$n%10]":Zero}$p+=<>;warn$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/

Python:

#!/usr/bin/env python

# Number of letters in each part, we don't count spaces
Decades = ( 0, 3, 6, 6, 6, 5, 5, 7, 6, 6, 0 )
Smalls  = ( 0, 3, 3, 5, 4, 4, 3, 5, 5, 4 )
Teens  =  ( 6, 6, 8, 8, 7, 7, 9, 8, 8 )

def Count(n):
    if n > 10 and n < 20: return Teens[n-11]
    return   Smalls[n % 10 ] + Decades [ n / 10 ]

N = input()

while N-4:
    Cnt = Count(N)
    print "%d is %d" % ( N, Cnt)
    N = Cnt

print "4 is magic"

C++, 171 caractères (#inclure omis)

void main(){char x,y,*a="03354435543668877988";scanf("%d",&x);for(;x-4;x=y)y=x?x<19?a[x]-48:"_466555766"[x/10]+a[x%10]-96:4,printf("%d is %d.\n",x,y);puts("4 is magic.");}

Ruby, 164 caractères

n=gets.to_i;s="03354435543668877987";if n==0;puts"0 is 4.";else;puts"#{n} is #{n=(n<20)?s[n]-48:"0066555766"[n/10]-48+s[n%10]-48}." until n==4;end;puts"4 is magic."

décodé:

n = gets.to_i
s = "03354435543668877987"
if n == 0
  puts "0 is 4."
else
  puts "#{n} is #{n = (n < 20) ? s[n] - 48 : "0066555766"[n / 10] - 48 + s[n % 10] - 48}." until n == 4
end

puts "4 is magic."

Lua 185 190 199

ajouté périodes, a ajouté io.lire, retiré ()'s sur la dernière impression

 n=io.read();while(n~=4)do m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;print(n,' is ',m,'.')n=m;end print'4 is magic.'

avec des sauts de ligne

 n=io.read()
 while (n~=4) do
    m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;
    print(n,' is ',m,'.')
    n=m;
 end 
 print'4 is magic.'

Le Code PhP

function get_num_name($num){  
    switch($num){  
        case 1:return 'one';  
    case 2:return 'two';  
    case 3:return 'three';  
    case 4:return 'four';  
    case 5:return 'five';  
    case 6:return 'six';  
    case 7:return 'seven';  
    case 8:return 'eight';  
    case 9:return 'nine';  
    }  
}  

function num_to_words($number, $real_name, $decimal_digit, $decimal_name){  
    $res = '';  
    $real = 0;  
    $decimal = 0;  

    if($number == 0)  
        return 'Zero'.(($real_name == '')?'':' '.$real_name);  
    if($number >= 0){  
        $real = floor($number);  
        $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
    }else{  
        $real = ceil($number) * (-1);  
        $number = abs($number);  
        $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
    }  
    $decimal = substr($decimal, strpos($decimal, '.') +1);  

    $unit_name[1] = 'thousand';  
    $unit_name[2] = 'million';  
    $unit_name[3] = 'billion';  
    $unit_name[4] = 'trillion';  

    $packet = array();    

    $number = strrev($real);  
    $packet = str_split($number,3);  

    for($i=0;$i<count($packet);$i++){  
        $tmp = strrev($packet[$i]);  
        $unit = $unit_name[$i];  
        if((int)$tmp == 0)  
            continue;  
        $tmp_res = '';  
        if(strlen($tmp) >= 2){  
            $tmp_proc = substr($tmp,-2);  
            switch($tmp_proc){  
                case '10':  
                    $tmp_res = 'ten';  
                    break;  
                case '11':  
                    $tmp_res = 'eleven';  
                    break;  
                case '12':  
                    $tmp_res = 'twelve';  
                    break;  
                case '13':  
                    $tmp_res = 'thirteen';  
                    break;  
                case '15':  
                    $tmp_res = 'fifteen';  
                    break;  
                case '20':  
                    $tmp_res = 'twenty';  
                    break;  
                case '30':  
                    $tmp_res = 'thirty';  
                    break;  
                case '40':  
                    $tmp_res = 'forty';  
                    break;  
                case '50':  
                    $tmp_res = 'fifty';  
                    break;  
                case '70':  
                    $tmp_res = 'seventy';  
                    break;  
                case '80':  
                    $tmp_res = 'eighty';  
                    break;  
                default:  
                    $tmp_begin = substr($tmp_proc,0,1);  
                    $tmp_end = substr($tmp_proc,1,1);  

                    if($tmp_begin == '1')  
                        $tmp_res = get_num_name($tmp_end).'teen';  
                    elseif($tmp_begin == '0')  
                        $tmp_res = get_num_name($tmp_end);  
                    elseif($tmp_end == '0')  
                        $tmp_res = get_num_name($tmp_begin).'ty';  
                    else{  
                        if($tmp_begin == '2')  
                            $tmp_res = 'twenty';  
                        elseif($tmp_begin == '3')  
                            $tmp_res = 'thirty';  
                        elseif($tmp_begin == '4')  
                            $tmp_res = 'forty';  
                        elseif($tmp_begin == '5')  
                            $tmp_res = 'fifty';  
                        elseif($tmp_begin == '6')  
                            $tmp_res = 'sixty';  
                        elseif($tmp_begin == '7')  
                            $tmp_res = 'seventy';  
                        elseif($tmp_begin == '8')  
                            $tmp_res = 'eighty';  
                        elseif($tmp_begin == '9')  
                            $tmp_res = 'ninety';  

                        $tmp_res = $tmp_res.' '.get_num_name($tmp_end);  
                    }  
                    break;  
            }  

            if(strlen($tmp) == 3){  
                $tmp_begin = substr($tmp,0,1);  

                $space = '';  
                if(substr($tmp_res,0,1) != ' ' && $tmp_res != '')  
                    $space = ' ';  

                if($tmp_begin != 0){  
                    if($tmp_begin != '0'){  
                        if($tmp_res != '')  
                            $tmp_res = 'and'.$space.$tmp_res;  
                    }  
                    $tmp_res = get_num_name($tmp_begin).' hundred'.$space.$tmp_res;  
                }  
            }  
        }else  
            $tmp_res = get_num_name($tmp);  
        $space = '';  
        if(substr($res,0,1) != ' ' && $res != '')  
            $space = ' ';  
        $res = $tmp_res.' '.$unit.$space.$res;  
    }  

    $space = '';  
    if(substr($res,-1) != ' ' && $res != '')  
        $space = ' ';  

    if($res)  
        $res .= $space.$real_name.(($real > 1 && $real_name != '')?'s':'');  

    if($decimal > 0)  
        $res .= ' '.num_to_words($decimal, '', 0, '').' '.$decimal_name.(($decimal > 1 && $decimal_name != '')?'s':'');  
    return ucfirst($res);  
}  

//////////// les tests ////////////////

 $str2num = 12;
    while($str2num!=4){
        $str = num_to_words($str2num, '', 0, '');  
        $str2num = strlen($str)-1;
        echo $str . '=' . $str2num .'<br/>';
        if ($str2num == 4)
            echo 'four is magic';
    }

////// Les résultats /////////

Twelve =6
Six =3
Three =5
Five =4
four is magic

Perl - 130 caractères


5.12.1 (130 caractères) 121 123 132 136 140

#        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123

@u='4335443554366887798866555766'=~/./g;$_=pop;say"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,"."until/\D/


5.10.1 (134 caractères) 125 127 136 140 144

#        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234

@u='4335443554366887798866555766'=~/./g;$_=pop;print"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,".\n"until/\D/


Historique Des Modifications:

20100714:2223 - revenue de changement à l'attention de mobrule, mais ($_%10&&$u[$_%10])(($_%=10)&&$u[$_]), qui est le même nombre de caractères, mais je l'ai fait dans le cas où quelqu'un pourrait voir un moyen de l'améliorer

20100714:0041 - split//,'...''...'=~/./g
20100714:0025 - ($_%10&&$u[$_%10])$u[$_%10]
20100713:2340 - while$_until/\D/ + retiré parenthèses inutiles
20100713:xxxx - $=<>;chop;$_=pop; - avec l'aimable autorisation de mobrule


Note: J'étais fatigué d'améliorer les réponses des autres dans les commentaires, alors maintenant, je suis gourmande et peut juste ajouter mes changements ici :) C'est une scission de Platine D'Azur's réponse - crédit dans le cadre de Hobbs, mobrule, et Platine D'Azur.

Sans vergogne Perl avec le Nombre de Mots (329 caractères)

Adapté assez directement à partir de P de Papa le code en C, avec quelques ajustements pour p() pour lui faire faire la même chose à l'aide de Perl primitives au lieu de C, et surtout réécrit mainloop.Voir sa pour une explication.Les retours à la ligne sont tous facultatifs.

@t=(qw(zero one two three four five six sM eight nine
tL elM twelve NP 4P fifP 6P 7P 8O 9P twLQ NQ forQ fifQ
6Q 7Q 8y 9Q en evL thir eL tO ty 4SmagicT)," is ",".\n");
sub p{local$_=$t[pop];1while s/[0-Z]/$t[-48+ord$&]/e;
print;length}$_=<>;chop;while($_-4){
$_=($_>19?(p($_/10+18),$_&&print("-"),$_%=10)[0]:0)+p$_;
p 35;p$_;p 36}p 34

Note de côté:c'est dommage que perl print retourne true/false;si elle revenait un compte il me sauver de 7 coups.

Ruby, 141 caractères:

n=gets.to_i;m="4335443554366887798866555766";loop{s=n;n=n>20?m[18+n/10]+m[n%10]-96: m[n]-48;puts"#{s} is #{n==s ? 'magic': n}.";n==s &&break}
while(true)
{
    string a;
    ReadLine(a)
    WriteLine(4);

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top