Distancia a cuatro

13

Este desafío se basa en este video . Te recomiendo que lo mires antes de intentar este desafío.

Primero definimos una función. Esta función ( OEIS ) toma un número entero n como entrada y genera el número de letras en la representación inglesa de n (sin espacios ni guiones). Por ejemplo, "tres" tiene 5 letras, de modo que 3 se asignan a 5.

Como se demostró en el video que comienza con cualquier número que se repita, este proceso eventualmente dará como resultado un cuatro, que se asignará a sí mismo para siempre.

Aquí hay un gráfico dirigido bruto que muestra las órbitas de los números menores que 16:

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

Su desafío es determinar la cantidad de pasos que tomará un número (o la cantidad de veces que esta función debe aplicarse a un número) antes de llegar a cuatro (es decir, el nivel en el gráfico dirigido en la imagen).

Formando números ingleses

Aquí hay una breve explicación de cómo se deben formar palabras en inglés para este desafío:

Los números del uno al diecinueve son:

uno, dos, tres, cuatro, cinco, seis, siete, ocho, nueve, diez, once, doce, trece, catorce, quince, dieciseis, diecisiete, dieciocho, diecinueve

Para números mayores de diecinueve, el proceso es el siguiente:

Si el número tiene un lugar de cientos, comience con el nombre del dígito en el lugar de cientos y "cien".

p.ej

100 -> "onehundred"

Si el resto es inferior a veinte, agregue la representación en inglés del resto.

p.ej

714 -> "sevenhundredfourteen"

De lo contrario, si el dígito de las decenas no es cero, agregue la representación adecuada:

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

p.ej

470 -> "fourhundredseventy"

Finalmente, si hay un dígito, agregue su representación

p.ej

681 -> "sixhundredeightyone"

Estipulaciones adicionales

  • Para números superiores a cien, debe omitir "y" al contar el número de letras. Por ejemplo, 577 es "quinientos setenta y siete" que tiene 23 letras.

  • Su programa debe aceptar todos los enteros mayores que 0 y menores que 1,000 como entrada a través de métodos estándar.

  • Su programa debe generar la cantidad de pasos necesarios para los métodos de salida estándar.

  • Este es codegolf, por lo que gana la solución con la menor cantidad de bytes.

Casos de prueba

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 
Post Rock Garf Hunter
fuente
1
Relacionado , pensé que esto era un engaño, pero no puedo encontrarlo.
James
¿Qué pasó con "y"? O más bien, ¿por qué dejar de lado y?
Jonathan Allan
@JonathanAllan porque 'Murica
LegionMammal978

Respuestas:

5

JavaScript (ES6), 106 bytes

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]))

Las cadenas parecen ser la mejor manera de codificar la longitud, a pesar de la sobrecarga de conversión numérica.

Neil
fuente
Dios mío, eso es casi exactamente lo que parecía mi respuesta (casi publicada), solo 11 bytes más corta.
ETHproductions
@ETHproductions ¡Qué bueno que jugué 16 bytes antes de publicarlo!
Neil
2

Python, con num2words, 97113115 94 93 92 bytes

+16 bytes (olvidaron de la separación de palabras que num2words aplica que en realidad no cambiar los resultados de cualquiera de los casos de prueba, a pesar de que 23y 577cada uno tiene un guión)
+2 bytes (olvidaron de incluir f=aunque recursiva)
-20 bytes (uso re)
-8 bytes gracias a @Wheat Wizard (usar ~, reemplazar n!=4con n-4y ... importación de una línea> _ <)
-1 byte gracias a @Cyoce (espacio desde 4 and)

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

Solo cuenta la cantidad de pasos; también funciona para enteros enormes y negativos ( \Wencuentra los espacios, comas y guiones en el resultado de 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

Aquí está el último caso, paso a paso:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five
Jonathan Allan
fuente
1
No necesita un f=antes de su función lambda
Post Rock Garf Hunter
1
Intente en import re,num2words as rlugar de las dos declaraciones diferentes.
Post Rock Garf Hunter
1
n-4es lo mismo quen!=4
Post Rock Garf Hunter
1
@WheatWizard num2wordses w, resigue siendo re- tenga en cuenta que tanto el módulo como la función se llamannum2words
Jonathan Allan
1
Ok, el último, and 1+se puede reemplazar and-~para guardar un byte
Post Rock Garf Hunter
1

Pyth - 54 bytes

Intentará refactorizar.

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

Test Suite .

Maltysen
fuente
1

Mathematica, 89 bytes

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

Mathematica típica: funciones incorporadas buenas, nombres largos de funciones malos. FixedPointListaplica su primer argumento (una función) al segundo argumento repetidamente hasta que la respuesta no cambie, enumerando todos los resultados; los resultados incluyen la entrada original y dos copias de la salida repetida, por lo tanto, -2al final. El incorporado de Mathematica IntegerNamecontiene espacios y guiones, por lo que debemos eliminarlos a mano.

Molesto, IntegerNamela salida contiene el carácter "-" (Unicode # 8208) en lugar de guiones normales; es por eso que este envío es de 89 bytes en lugar de 88. (Y no podría preceder el código anterior con cuatro espacios y hacer que acepte el carácter Unicode, ¿alguna ayuda?), de modo que el código anterior no funcionará exactamente si se corta y pega .)

Greg Martin
fuente
1

Python 2.7, 344 216 208 bytes:

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

No utiliza ninguna biblioteca externa a diferencia de otras respuestas de Python. Toma entradas stdiny salidas a stdout.

Repl.it con todos los casos de prueba!

Explicación

Primero crea 3 diccionarios con cada uno emparejando la longitud de las representaciones de palabras en inglés de cada número con el número que representa en el intervalo cerrado [1,9]en el lugar de las unidades, decenas y cientos, respectivamente. Por ejemplo, la primera entrada en el diccionario des 1:3como 1se escribe oneen inglés y tiene 3letras.

Luego, cada lugar de dígitos en alguna entrada de cadena xse asigna a su diccionario correspondiente, después de lo cual cada número en cada lugar se corresponde con su valor en el diccionario correspondiente. Por ejemplo, suponga que el número de entrada fue 23. En 20el lugar de las decenas se emparejaría con el diccionario e, en el que se empareja 6, y 3en el lugar de las unidades se emparejaría con el diccionario d, en el que se empareja 5. Estos dígitos coincidentes se suman para representar la longitud de la representación en inglés del número, que se asigna xcomo una cadena y, x!='4'mientras el ciclo while continúe, incrementándose cen1cada vez para representar el número de pasos dados hasta ahora. Por 23lo tanto, correspondería a 11, que a su vez correspondería a 6cuál se convertiría en 3y luego a 5y finalmente a 4, lo que da como resultado 5pasos totales.

Finalmente, una vez que finaliza el bucle, cse emite para stdoutrepresentar la "Distancia a cuatro", que en este caso sería 5.

R. Kap
fuente
1

Java, 556 295 bytes

Gracias a @KevinCruijssen por guardar 261 bytes

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


Sin 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);
}
Nudo numérico
fuente
Creo que tiene un error en su código, porque s++no es posible en un String-array ..: S
Kevin Cruijssen
@KevinCruijssen Declaro S (contador) como INT y STRING también ... Java decide automáticamente que es un INT.
Numberknot
Bueno, si ejecuto su código en ideone o mi IDE de Eclipse, falla porque tiene dos s... Por cierto, puede jugar golf su código en una cantidad bastante grande como esta: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
Estoy conmocionado ... qué pasó con mi código y gracias @ KevinCruijssen ... y lo estoy corrigiendo ... Gracias de nuevo.
Numberknot
Np :) Creo que podría jugarse un poco más de alguna manera sin usar el if-else y entrar allí (pero se lo dejaré a otra persona), pero su código inicial fue una gran base para abordar el desafío, así que +1 de mi parte.
Kevin Cruijssen