Quatro é o número mágico

26

Não marquei a caixa de areia antes de postar esse desafio - parece que esse desafio foi proposto por Cᴏɴᴏʀ O'Bʀɪᴇɴ .

Dada uma entrada inteira, escreva um programa que imprima o enigma "quatro é um número mágico"

  • Quatro é o número mágico
  • Cinco é quatro e quatro é o número mágico
  • Seis é três e três é cinco e cinco é quatro e quatro é o número mágico
  • Onze é seis e seis é três e três é cinco e cinco é quatro e quatro é o número mágico
  • Quinhentos são onze e onze são seis e seis são três e três são cinco e cinco são quatro e quatro é o número mágico

Se você já conhece o enigma ou está com preguiça de resolvê-lo, ansioso para descobrir qual é o enigma, aqui está uma explicação

O próximo número é o número de letras no número anterior. Então, por exemplo, cinco tem quatro letras, então o próximo número é quatro .

seis tem três letras, então o próximo número é 3 , e três tem cinco letras, então o próximo número é 5 e cinco tem quatro letras, então o próximo número é 4

A razão pela qual o enigma termina às quatro é porque quatro tem quatro letras , e quatro é quatro e quatro é quatro e quatro é quatro ... (quatro é o número mágico)

Casos de teste

0 =>
  Zero is four and four is the magic number
1 =>
  One is three and three is five and five is four and four is the magic number
2 =>
  Two is three and three is five and five is four and four is the magic number
3 => 
  Three is five and five is four and four is the magic number
4 =>
  Four is the magic number
5 => 
  Five is four and four is the magic number
6 =>
  Six is three and three is five and five is four and four is the magic number
7 =>
  Seven is five and five is four and four is the magic number
8 =>
  Eight is five and five is four and four is the magic number
9 =>
  Nine is four and four is the magic number
10 =>
  Ten is three and three is five and five is four and four is the magic number
17 =>
  Seventeen is nine and nine is four and four is the magic number
100 =>
  One Hundred is ten and ten is three and three is five and five is four and four is the magic number
142 =>
  One Hundred Forty Two is eighteen and eighteen is eight and eight is five and five is four and four is the magic number
1,000 =>
  One Thousand is eleven and eleven is six and six is three and three is five and five is four and four is the magic number
1,642 =>
  One Thousand Six Hundred Forty Two is twenty nine and twenty nine is ten and ten is three and three is five and five is four and four is the magic number
70,000 =>
  Seventy Thousand is fifteen and fifteen is seven and seven is five and five is four and four is the magic number
131,072 =>
  One Hundred Thirty One Thousand Seventy Two is thirty seven and thirty seven is eleven and eleven is six and six is three and three is five and five is four and four is the magic number
999,999 =>
  Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine is fifty and fifty is five and five is four and four is the magic number

Regras

  • A entrada pode ser retirada de STDINou como argumento para uma função
  • A entrada será um número positivo entre 0 e 999.999
  • A entrada conterá apenas números (seguirá a regex ^[0-9]+$)
  • A entrada pode ser tomada como um número inteiro ou uma sequência
  • Quando convertidos em uma sequência de palavras, espaços e hífens não devem ser incluídos na contagem (100 [Cem] são 10 caracteres, não 11. 1.742 [Mil setecentos e quarenta e dois] possui 31 caracteres, não 36)
  • Quando convertidos em uma sequência, 100 deve ser Cem, não Cem ou Cem, 1000 deve ser Mil, não Mil ou Mil.
  • Quando convertido em uma sequência 142, deve ser cento e quarenta e dois, não cento e quarenta e dois
  • A saída não diferencia maiúsculas de minúsculas e deve seguir o formato " N é K e K é M e M é ... e quatro é o número mágico" (a menos que a entrada seja 4, nesse caso, a saída deve ser simplesmente "quatro é o número mágico ")
  • A saída pode usar números em vez de letras ("5 é 4 e 4 é o número mágico" em vez de "cinco é quatro e quatro é o número mágico"), desde que seu programa seja sempre consistente
  • A saída pode ser o valor de retorno de uma função ou impressa para STDOUT
  • Aplicam-se brechas padrão
  • Isso é , então o programa mais curto em bytes vence. Boa sorte!

Bônus

-30 bytes se o programa funcionar quando a entrada estiver entre -999.999 e 999.999.

Os números negativos, quando convertidos em palavras, têm apenas "negativo" na frente deles. Por exemplo, -4"Negativo Quatro", Negativo Quatro é doze e doze é seis e seis é três e três é cinco e cinco é quatro e quatro é o número mágico

-150 bytes se o programa não usar nenhuma função interna para gerar a representação de seqüência do número

Entre os melhores

Este é um snippet de pilha que gera um placar de líderes e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie sua resposta com um título, usando o seguinte modelo de remarcação

## Language Name, N bytes

Onde N é o tamanho, em bytes, do seu envio

Se você deseja incluir vários números em seu cabeçalho (por exemplo, localizar pontuações antigas ou incluir sinalizadores na contagem de bytes), verifique se a pontuação real é o último número em seu cabeçalho

## Language Name, <s>K</s> X + 2 = N bytes

Jojodmo
fonte
Existe uma entrada máxima possível?
quer
7
No futuro, verifique também a Sandbox para ver se alguém teve sua ideia .
El'endia Starman
@ El'endiaStarman Tudo bem, eu adicionei um texto no topo do desafio,
vinculado
Seu bônus de função embutido deve ser mais como -150 a -200 bytes.
TanMath
1
Eu só vou jogar isso lá fora - mesmo o número mais insanamente otimizado para nomear conversores mal custará menos de 150 bytes para a maioria dos idiomas, pois o -150 é mais uma armadilha do que um bônus.
Ricdesi

Respostas:

9

Bash + utilitários comuns (incluindo bsd-games), 123 - 30 = 93 bytes

for((n=$1;n-4;n=m)){
m=`number -l -- $n|sed 's/nus/&&/;s/\W//g'`
s+="$n is $[m=${#m}] and "
}
echo $s 4 is the magic number

Felizmente, a saída do utilitário bsd-gamesnumber é quase exatamente o que precisamos. Os números de saída são todos escritos numericamente e não em palavras, conforme o oitavo ponto:

$ ./4magic.sh 131072
131072 is 37 and 37 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
$ ./4magic.sh -4
-4 is 12 and 12 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
$ 
Trauma Digital
fonte
6

C, 263 261 bytes - 180 = 81

char*i="jmmonnmoonmpprrqqsrrjjddeeecdd",x;f(n,c){return!n?n:n<0?f(-n,8):n<100?c+i[n<20?n:n%10]-i[20+n/10]:f(n/1000,8)+f(n/100%10,7)+f(n/100%10,0)+c;}main(int c,char**v){for(c=atoi(*++v);c-4;c=x)printf("%d is %d and ",c,x=c?f(c,0)):4;puts("4 is the magic number");}

Inspirado pela resposta de Cole Cameron . Eu pensei que poderia ser melhor sem a definição de macro. Embora eu tenha conseguido, demorou um pouco para conseguir!

Requer um conjunto de caracteres do host com letras consecutivas (para que o ASCII esteja correto, mas o EBCDIC não funcione). Isso é para o par de tabelas de pesquisa. Eu escolhi jo caractere zero e aproveitei a necessidade de duas pesquisas, para poder subtrair uma da outra, em vez de ter que subtrair meu zero de ambas.

Versão comentada:

char*i=
    "jmmonnmoon"                /* 0 to 9 */
    "mpprrqqsrr"                /* 10 to 19 */
    "jjddeeecdd";               /* tens */
char x;                /* current letter count */

f(n,c){
return
    !n?n                        /* zero - return 0 (ignore c) */
    :n<0?f(-n,8)                /* negative n (only reached if c==0) */
    :n<100?c+i[n<20?n:n%10]-i[20+n/10] /* lookup tables */
    :
      f(n/1000,8)               /* thousand */
    + f(n/100%10,7)             /* hundred */
    + f(n%100,0)                /* rest */
    + c;                        /* carry-in */
}
main(int c, char**v)
{
    for(c=atoi(*++v);c-4;c=x)
        printf("%d is %d and ",c,x=c?f(c,0):4);
    puts("4 is the magic number");
}

Existe uma extensão óbvia para suportar milhões, substituindo f(n/1000,8)por f(n/1000000,7)+f(n/1000%1000,8).

Saída de teste

0 is 4 and 4 is the magic number
1 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
2 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
3 is 5 and 5 is 4 and 4 is the magic number
4 is the magic number
5 is 4 and 4 is the magic number
6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
7 is 5 and 5 is 4 and 4 is the magic number
8 is 5 and 5 is 4 and 4 is the magic number
9 is 4 and 4 is the magic number
10 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
17 is 9 and 9 is 4 and 4 is the magic number
100 is 10 and 10 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
142 is 18 and 18 is 8 and 8 is 5 and 5 is 4 and 4 is the magic number
1000 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
1642 is 29 and 29 is 10 and 10 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
70000 is 15 and 15 is 7 and 7 is 5 and 5 is 4 and 4 is the magic number
131072 is 37 and 37 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
999999 is 50 and 50 is 5 and 5 is 4 and 4 is the magic number
Toby Speight
fonte
4

Mathematica, 156 - 30 = 126 bytes

a=ToString;({a@#," is ",a@#2," and "}&@@@Partition[NestWhileList[#~IntegerName~"Words"~StringCount~LetterCharacter&,#,#!=4&],2,1])<>"4 is the magic number"&

Estou simplesmente surpreso que isso use strings e não seja ridiculamente longo.

LegionMammal978
fonte
4

Swift 2 , 408 419 - 30 = 389 bytes

Eu seria capaz de me livrar de 176 bytes se o Swift não fosse tão detalhado com expressões regulares (removendo hífens e espaços) * olha furioso para a Apple *

func c(var s:Int)->String{var r="";while(s != 4){r+="\(s)";let f=NSNumberFormatter();f.numberStyle=NSNumberFormatterStyle.SpellOutStyle;let v=f.stringFromNumber(s)!;s=v.stringByReplacingOccurrencesOfString("[- ]",withString:"",options:NSStringCompareOptions.RegularExpressionSearch,range:Range<String.Index>(start:v.startIndex,end:v.endIndex)).utf8.count+(s<0 ?3:0);r+=" is \(s) and "};return r+"4 is the magic number"}

Isso pode ser testado em swiftstub.com, aqui

Corri um pouco para o loop, e acontece que 100003é o número entre 0 e 999999 que tem o resultado mais longo da string, que tem 6 iterações e é

100003 é 23 e 23 é 11 e 11 é 6 e 6 é 3 e 3 é 5 e 5 é 4 e 4 é o número mágico

Ungolfed

func a(var s: Int) -> String{
    var r = ""
    while(s != 4){
        r+="\(s)"

        let f = NSNumberFormatter()
        f.numberStyle = NSNumberFormatterStyle.SpellOutStyle
        let v = f.stringFromNumber(s)!
        s = v.stringByReplacingOccurrencesOfString(
            "[- ]",
            withString: "",
            options: NSStringCompareOptions.RegularExpressionSearch,
            range: Range<String.Index>(start: v.startIndex, end: v.endIndex)
        ).utf8.count + (s < 0 ? 3 : 0)

        r+=" is \(s) and "
    }
    return r+"4 is the magic number"
}
Jojodmo
fonte
7
NSStringCompareOptions.RegularExpressionSearchE eu pensei que JS String.fromCharCodeera detalhado. : P
ETHproductions
4
Python e Ruby: string.replace. Swift:String.stringByReplacingOccurrencesOfString
cat
4

Haskell, 285 - 180 = 105 bytes

De fato, não há nenhum built-in para exibir o número. Eu ainda estou insatisfeito com o placar. Sinta-se livre para comentar. Vou experimentar ainda mais. Ainda assim, a pontuação é melhor que a pontuação de Swift

c n|n<0=8+c(-n)|n>999=r 1000+8|n>99=7+r 100|n>19=r 10+2-g[30..59]+g[20..29]|n>15=r 10-1|2>1=[0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7]!!n where{g=fromEnum.elem n;r k=c(mod n k)+c(div n k)}
m 4="4 is the magic number"
m 0="0 is 4 and "++m 4
m n=show n++" is "++show(c n)++" and "++m(c n)

uso

m 7
"7 is 5 and 5 is 4 and 4 is the magic number"
m 999999
"999999 is 50 and 50 is 5 and 5 is 4 and 4 is the magic number"

Explicação.

mé trivial o suficiente, no entanto, o cnão é. cé a função para contar o número de caracteres e o nome em inglês do número.

c n |n<0=8+c(-n) -- Add word "negative" in front of it, the length is 8
    |n>999=r 1000+8 -- the english name for number with form xxx,yyy is xxx thousand yyy
    |n>99=7+r 100 -- the english name for number with form xyy is x hundred yy
    |n>19=r 10+2-g[30..59]+g[20..29] -- the english name for number with form xy with x more
                                     -- than 1 is x-ty. However *twoty>twenty,
                                     -- *threety>thirty, *fourty>forty, *fivety>fifty.
    |n>10=r 10-1-g(15:18:[11..13]) -- the english name for number with form 1x is x-teen.
                                     -- However, *oneteen>eleven, *twoteen>twelve,
                                     -- *threeteen>thirteen, *fiveteen>fifteen,
                                     -- *eightteen>eighteen
    |2>1=[0,3,3,5,4,4,3,5,5,4,3]!!n -- for number 0-10, the length is memorized. 0 is 0
                                    -- because it is omitted. Input zero is handled
                                    -- separately. If we defined 0 to be 4, then
                                    -- 20 => twenty zero.
  where g   =fromEnum.elem n      -- Check if n is element of argument array, if true, 1 else 0
        r k=c(mod n k)+c(div n k) -- Obvious.
Akangka
fonte
1
Ah sim? Bem, Swift tem ... uhm ... uma pontuação mais alta ... (não sou muito bom em reviravoltas) #
487 Jojodmo
4

C, 268-180 = 88 bytes

#define t(x,o)n<x?o:f(n/x)+(n%x?f(n%x):0)
char*i="4335443554366887798866555766";f(n){return t(1000,t(100,n<20?n<0?8+f(-n):i[n]-48:i[n/10+18]-48+(n%10?f(n%10):0))+7)+8;}main(n){for(scanf("%d",&n);n^4;n=f(n))printf("%d is %d and ",n,f(n));puts("4 is the magic number");}

Experimente aqui .

Ungolfed

/* Encode number length in string (shorter representation than array) */
char*i="4335443554366887798866555766";

f(n)
{
    return n < 1000
        ? n < 100
            ? n < 20
                ? n < 0
                    ? 8 + f(-n) /* "Negative x" */
                    : i[n] - 48 /* "x" */
                : i[n/10+18] + (n%10 ? f(n%10) : 0) /* 20-99 */
            : f(n/100) + (n%100 ? f(n%100) : 0) + 7 /* x hundred y */
        : f(n/1000) + (n%1000 ? f(n%1000) : 0) + 8; /* x thousand y */
}

main(n)
{
    /* Keep printing until you get to the magic number */
    for(scanf("%d",&n);n^4;n=f(n))
        printf("%d is %d and ",n,f(n));
    puts("4 is the magic number");
}
Cole Cameron
fonte
3

Java, 800-150 = 650 bytes

class G{static String e="",i="teen",j="ty",k="eigh",y="thir",d="zero",l="one",n="two",m="three",h="four",s="five",c="six",t="seven",b=k+"t",g="nine",D="ten",L="eleven",N="twelve",M=y+i,H=h+i,S="fif"+i,C=c+i,T=t+i,B=k+i,G=g+i,o="twen"+j,p=y+j,q="for"+j,r="fif"+j,u=c+j,v=t+j,w=k+j,x=g+j,A=" ",O=" hundred ",z,E;public static void main(String a[]){z=e;int l=new Integer(a[0]);do{E=a(l,1,e);l=E.replace(A,e).length();z=z+E+" is "+a(l,1,e)+" and ";}while(l!=4);System.out.print(z+h+" is the magic number");}static String a(int P,int _,String Q){String[]f={e,l,n,m,h,s,c,t,b,g,D,L,N,M,H,S,C,T,B,G,e,D,o,p,q,r,u,v,w,x};int R=20,X=10,Y=100,Z=1000;return P==0?(_>0?d:e):(P<R?f[P]+Q:(P<Y?(f[R+(P/X)]+" "+a(P%X,0,e)).trim()+Q:(P<Z?a(P/Y,0,O)+a(P%Y,0,e)+Q:a(P/Z,0," thousand ")+a((P/Y)%X,0,O)+a(P%Y,0,e)+Q)));}}

De-golfe

class G {

   static String e="",i="teen",j="ty",k="eigh",y="thir",d="zero",l="one",n="two",m="three",h="four",s="five",c="six",t="seven",b=k+"t",g="nine",D="ten",L="eleven",N="twelve",M=y+i,H=h+i,S="fif"+i,C=c+i,T=t+i,B=k+i,G=g+i,o="twen"+j,p=y+j,q="for"+j,r="fif"+j,u=c+j,v=t+j,w=k+j,x=g+j,A=" ",O=" hundred ",z,E;

   public static void main(String a[]){
     z = e;
     int l = new Integer(a[0]);
     do {
             E = a(l,1,e);
             l = E.replace(A,e).length();  
             z = z+E+" is "+a(l,1,e)+" and ";
     } while(l!=4);
     System.out.println(z+h+" is the magic number");
   }

   static String a(int P,int _,String Q) {
     String[] f = {e,l,n,m,h,s,c,t,b,g,D,L,N,M,H,S,C,T,B,G,e,D,o,p,q,r,u,v,w,x};
     int R=20,X=10,Y=100,Z=1000;
     return P==0?(_>0?d:e):(P<R?f[P]+Q:(P<Y?(f[R+(P/X)]+" "+a(P%X,0,e)).trim()+Q:(P<Z?a(P/Y,0,O)+a(P%Y,0,e)+Q:a(P/Z,0," thousand ")+ a((P/Y)%X,0,O)+a(P%Y,0,e)+Q)));
   }
}
Mínimo
fonte
Sei que já faz mais de um ano, mas você pode remover alguns parênteses nessa tarefa ternária e mudar ==0para <1. Então: return P<1?_>0?d:e:P<R?f[P]+Q:P<Y?(f[R+(P/X)]+" "+a(P%X,0,e)).trim()+Q:P<Z?a(P/Y,0,O)+a(P%Y,0,e)+Q:a(P/Z,0," thousand ")+a((P/Y)%X,0,O)+a(P%Y,0,e)+Q;( - 10 bytes )
Kevin Cruijssen 22/02
3

QC, 265-30 - 150 = 85 bytes

(✵1:oaT%=ta100%=ha100/⌋T%=X[0 3 3 5 4 4 3 5 5 4 3 6 6 8 8 7 7 9 8 8]=Y[6 6 5 5 5 7 6 6]=a0≟4a20<Xt☌YtT/⌋2-☌Xo☌+▲▲hXh☌7+0▲+)(❆1:na0<8*=ba‖1000/⌋=ca1000%=nbb✵8+0▲a✵++){I4≠:EEI" is "++=II❆=EEI" and "++=E!}E"4 is the magic number"+

Suíte de teste

Ungolfed:

(✵1:
oaT%=                                        # ones
ta100%=                                      # tens
ha100/⌋T%=                                   # hundreds
X[0 3 3 5 4 4 3 5 5 4 3 6 6 8 8 7 7 9 8 8]=  # length of "zero", "one", "two", ..., "nineteen"
Y[6 6 5 5 5 7 6 6]=                          # length of "twenty", ..., "ninety"
a0≟
  4
  a20< 
    Xt☌ 
    YtT/⌋2-☌ Xo☌ +
  ▲ 
▲
hXh☌7+0▲+)

(❆1:
na0<8*=                 # if negative, add 8
ba‖1000/⌋=              # split aaaaaa into bbbccc
ca1000%=
n bb✵8+0▲ a✵ ++)

{I4≠:EEI" is "++=II❆=EEI" and "++=E!}E"4 is the magic number"+
Avris
fonte
Se você não estiver usando uma função
interna
2

JavaScript, 382-150-30 = 202 bytes

var o=[0,3,3,5,4,4,3,5,5,4],f=s=>(s[1]==1?[3,6,6,8,8,7,7,9,8,8][s[0]]:o[s[0]]+(s.length>1?[0,3,6,6,5,5,5,7,6,6][s[1]]:0))+(s.length==3?(7+o[s[2]]-(o[s[2]]==0?7:0)):0),l=n=>{var s=(""+n).split("").reverse();return f(s.slice(0,3))+(s.length>3?(f(s.slice(3,6))+8):0)};(n=>{var s="";while(n!=4){s+=n+" is ";n=n>=0?l(n):(l(-n)+8);s+=n+" and ";}console.log(s+"4 is the magic number");})()

A entrada é fornecida como parâmetro para a Expressão de Função Imediatamente Invocada.

Entrada de teste:

999999 ->
    999999 is 50 and 50 is 5 and 5 is 4 and 4 is the magic number
17 ->
    17  is 9 and 9 is 4 and 4 is the magic number
-404 ->
    -404 is 23 and 23 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number

De-golfe:

// array of the lengths of digits in ones place:
// one is 3, two is 3, three is 5, etc... zero is a special case
// and is assigned zero length because zero is never written out in a number name
var o=[0,3,3,5,4,4,3,5,5,4],

// function that computes the length of a substring of the input
// because the input is 6 digits, it can be broken into two 3 digit subsections
// each of which can have it's length calculated separately
f=s=>
  (
  s[1]==1? // check for if the tens digit is a one
    // when the tens is a one, pull the string length from an array that represents
    // ten, eleven, twelve, thirteen, etc...
    [3,6,6,8,8,7,7,9,8,8][s[0]]
  :
    // when the tens digit is not a one, add the ones digit normally and...
    o[s[0]]
    +
    // add the tens digit length from the array that represents
    // zero, ten, twenty, thirty, forty, fifty, sixty, seventy, eighty, ninety
    (s.length>1?[0,3,6,6,5,5,5,7,6,6][s[1]]:0)
  )
  +
  (
  s.length==3? // check if the length is 3 and weren't not accidentally trying to do something wierd with a minus sign
    // if so, then we have to add a hundred (7 characters) to the length and the
    // length of the ones digit that is in the hundreds place like
    // 'one' hundred or 'two' hundred
    (7+o[s[2]]-
      (
        // also, if the hundreds place was a zero, subtract out those 7 characters
        // that were added because 'hundred' isn't added if there's a zero in its
        // place
        o[s[2]]==0?
          7
        :
          0
      )
    )
  :
    // if the length wasn't 3, then don't add anything for the hundred
    0
  ),

// function that computes the length of the whole six digit number
l=n=>{
  // coerce the number into a string and then reverse the string so that the
  // ones digit is the zeroth element instead of last element
  var s=(""+n).split("").reverse();
  return
    // calculate the character length of the first 3 characters
    // like in the number 999888, this does the '888'
    f(s.slice(0,3))
    +
    // then if there actually are any characters after the first 3
    (s.length>3?
        // parse the character length of the second 3 characters
        (f(s.slice(3,6))+8)
      :
        0
    )
};
// lastly is the Immediately-Invoked Function Expression
(n=>{
  var s="";
  // as long as we haven't reached four, just keep going through the loop
  while(n!=4){
    s+=n+" is ";
    n=n>=0?l(n):(l(-n)+8) // this handles negatives by only passing positive values to l and then just adding 8 onto the length for negatives
    s+=n+" and ";
  }
  // finally just say that '4 is the magic number'
  console.log(s+"4 is the magic number");
})(999999)
Davis
fonte
1

Python 641-150 = 501 bytes

Pelo menos não é mais longo que Java! É baseado nisso, exceto no uso de strings.

EDIT : Esqueci 0 e preciso dizer "5 é 4", não pule para "4 é o número mágico" - isso acrescentou um pouco à pontuação.

w={0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fifteen",16:"sixteen",17:"seventeen",18:"eighteen",19:"nineteen",20:"twenty",30:"thirty",40:"forty",50:"fifty",60:"sixty",70:"seventy",80:"eighty",90:"ninety"}
s=""
def i(n):
 global s
 e=""
 o=n%10
 t=n%100
 h=n/100%10
 th=n/1000
 if th:
  e+=i(th)
  e+='thousand'
 if h:
  e+=w[h]
  e+='hundred'
 if t:
  if t<20 or o==0:
   e+=w[t]
  else:
   e+=w[t-o]
   e+=w[o]
 if len(e)==4:s+="4 is the magic number";print s
 else: s+="%d is %d and "%(n,len(e));i(len(e))
In=input()
i(In)

Experimente aqui!

TanMath
fonte
Você não precisa exibir o nome, certo?
Akangka 4/16/16
Isto está incorreto. i(5)imprime 4 is the magic number, em vez de 5 is 4 and 4 is the magic number.
Mbomb007 02/03
1

Moo, 182 176/ 192 188 bytes - 30 = 146/158

Versão de 188 bytes:

u=$string_utils;s="";i=args[0];while(i-4)j=u:english_number(i);s=s+j+(s?" and "+j|"")+" is ";i=length(u:strip_chars(j,"- "}));endwhile;return s+(s?"four and "|"")+"four is the magic number"

Versão dependente da implementação de 176 bytes :

s="";i=args[0];while(i-4)j=#20:english_number(i);s=s+j+(s?" and "+j|"")+" is ";i=length(#20:strip_chars(j," -"));endwhile;return s+(s?"four and "|"")+"four is the magic number"

Ambos são funções.

pppery
fonte
1

PHP, 168 - 30 = 138 bytes

function m($i){$e=strlen(preg_replace('/[^a-z-]/','',(new NumberFormatter("en",5))->format($i)));echo($i==$e?"":"$i is $e and "),($e==4?"4 is the magic number":m($e));}
Jonathan Moyes
fonte