Automatiza tu ejercicio de conteo de primer grado

36

CodeGolf Challenge

PWSSHHHH! Te despiertas en un laboratorio de criogenia en el año 3000. Al ser escoltado a la oficina de asignación para recibir tu chip de carrera, presumiblemente el de un repartidor, una sonda detecta que eres del año 2000. Debido a esto, y algunos estereotipos, se supone estúpido en comparación con el de hoy humano moderno y se ve obligado a repetir la escuela primaria.

Entras en tu clase de primer grado y el maestro está asignando una tarea. Ella dirá o escribirá un número hasta 50. Si escribe el número en la pizarra (por ejemplo: 25), entonces debe decir los números hasta ese número "uno, dos, tres, ..., veinticinco ". Si dice el número en voz alta (por ejemplo: "seis"), entonces, en su tableta, debe escribir los números hasta ese número "1, 2, 3, 4, 5, 6"

Esto se vuelve muy tedioso y decides que automatizarás el proceso con tu conocimiento de programación aún funcional, pero arcaico, del siglo XXI.


Objetivo:

Su programa debe tomar una entrada. Esta entrada será un número decimal ( 1 thru 50) o un número escrito ( one thru fifty).

• Si la entrada es un número decimal, su salida debe contar de uno a dicho número, utilizando un estilo escrito. (por ejemplo, treinta y dos )

• Si la entrada es un número escrito, su salida debe contar de 1 a dicho número, usando el estilo decimal. (por ejemplo, 32 )


Reglas:

La entrada y la salida pueden ser en cualquier caso de su elección (por lo que puede hacer un programa que solo acepte mayúsculas si lo desea).

Los números decimales de entrada no tienen que ser de un tipo de número (por ejemplo, int), pueden ser una cadena de entrada que contiene números (25 frente a "25"). O bien, puedes elegir cuál quieres que acepte tu programa. (Su programa no necesita aceptar ambos)

El estilo escrito NO requiere un guión entre palabras compuestas, pero puede hacerlo si lo desea.

Los valores de salida deben estar separados de alguna forma, cualquier separador está bien 1,2,3 1 2 3 etc

No puede agregar bibliotecas adicionales como num2words (python) etc. (Sin embargo, las bibliotecas del sistema están bien)

Aunque la historia de fondo dice que eres del año 2000, puedes usar idiomas creados después de esa fecha (risas)


Este es el , por lo que gana el programa con el bytecount más corto.

Albert Renshaw
fuente
1
¿Se nos permite usar bibliotecas como num2words en caso de python?
Gurupad Mamadapur
1
@AlbertRenshaw, pero ¿qué pasa con las incorporaciones que hacen eso? (Mathematica)
Pavel
1
@coredump O significa que puede elegir uno u otro o ambos. No tiene que ser capaz de manejar ambos tipos de entradas
Albert Renshaw el
2
"¡Muerde mi brillante culo de metal!" No me
contaré a
1
Sigo pensando que el título es "tu primer (recuento de grado)" no "tu (primer grado) contando"
CAD97

Respuestas:

32

Perl 6 , 119113 bytes

{my \n=<①     ㊿>.map:{|map *.uniname.words[2..*].join,$^a..$^b}
/\d/??n[^$_]!!1..1+first $_,n,:k}

Base de datos Unicode FTW!

Utiliza números escritos en mayúscula sin guión, por ejemplo TWENTYTWO.
Devuelve una lista de cadenas o un rango de números. (Ambos usan el espacio como separador cuando se imprime con put).

smls
fuente
3
Muy inteligente ahahaha! Me encanta
Albert Renshaw
13

Python3, 276 271 269 243 237 235 232 217 bytes

Siguiendo el ejemplo de la presentación de @smls perl ...

from unicodedata import*
o=[name(chr(k)).split(' ',2)[-1]for j in['①⑴','㉑㉠','㊱㋀']for k in range(ord(j[0]),ord(j[1]))]
i=input()
w=i in o
for i in range(w and o.index(i)+1or int(i)):print(w and i+1or o[i])

Sospecho que podría jugarse un poco más.

Utiliza la biblioteca del sistema unicodedatapara buscar nombres para números. Requiere nombres en mayúsculas (separados por espacio:FORTY TWO :) o enteros decimales como entrada.

(Esta es mi primera presentación de código de golf).

(También me di cuenta de que estaba contando mal la longitud (codificación), por lo que son unos pocos bytes menos de lo que se pensaba anteriormente. Sin embargo, solo he actualizado el recuento de bytes más reciente. Vaya).

unayok
fuente
Bienvenido a PPCG!
AdmBorkBork
En defensa: unicodedataes una biblioteca del sistema que viene con la instalación predeterminada, no una biblioteca "adicional" que debe instalarse por separado.
unayok
Bienvenido al sitio! Puede eliminar muchos espacios de su código .
xnor
1
Bienvenido a PPCG. Puede perder 3 bytes colocando la impresión dentro de un forbucle y teniendo nuevas líneas entre cada salida. print()no le importa si es un entero o una cadena entonces. Pruébalo en línea!
ElPedro
1
Creo que puedes en import*lugar de import nameguardar un par de bytes
Wheat Wizard
10

Lisp común, 297 253 243 242 144 128

(lambda(s)(#1=dotimes(u(or(#1#(i 51)(if(equal(#2=format()"~R"i)s)(return i)))s))(#2#t"~[~:;, ~]~:[~R~;~D~]"u(stringp s)(1+ u))))

Detalles

(lambda (s) 
  (dotimes                         ; iterate...                                                                          
      (u                           ; for u from zero below ...                
       (or                         ; if s is a string, then                   
        (dotimes (i 51)            ;   parse s by iterating from 0 to 50      
          (if (equal               ;   until we find a match between          
               (format nil "~R" i) ;   the English word(s) for i              
               s)                  ;   and the given s                        
              (return i)))         ;   (exit loop)                            
        s))                        ; otherwise, use s, which is a number      
    (format t                      ; for each U, print to standard output     
            "~[~:;, ~]~:[~R~;~D~]" ; (see below for details)                  
            u                      ; ...                                      
            (stringp s)            ; ... arguments to format                  
            (1+ u))))              ; ...                                      
  • ~[ 0 ~; 1 ~; ... ~:; else ~]es un conmutador, basado en el siguiente valor del argumento disponible, que salta al formato de subcontrol apropiado. Aquí, solo tengo un caso de "0" y de "else". Esto se utiliza para insertar un separador antes de cada número, excepto el primero, gracias a U a partir de cero.

  • ~:[ FALSE ~; TRUE ~]es un formato condicional; aquí sacamos cosas de manera diferente si la entrada s es una cadena o no.

  • ~Rescribe un número como un número cardinal en inglés, mientras que ~Dsimplemente imprime el número.

Ejemplos

CL-USER> (test "five")
1, 2, 3, 4, 5

CL-USER> (test 32)
one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty, twenty-one, twenty-two, twenty-three, twenty-four, twenty-five, twenty-six, twenty-seven, twenty-eight, twenty-nine, thirty, thirty-one, thirty-two
volcado de memoria
fuente
Por lo que entiendo de la pregunta, debe poder analizar ambos estilos, no solo uno, por lo que su solución de 55 bytes podría no ser válida. "Su programa no necesita aceptar ambos" se refiere a 25 vs "25", el decimal como un número o como una cadena.
Tom
@TomDevs Gracias. Esto definitivamente es confuso. Sin duda, si defino fque "(f 2)" imprime "uno, dos" e (f "two")imprime "1, 2", ¿le parece bien?
coredump
Sí, creo que es correcto.
Tom
@TomDevs Gracias, lo arreglé
coredump
1
@AlbertRenshaw No, solo inglés; esta característica podría considerarse ya como hinchada, pero como ya se implementó en algunos Lisps, se estandarizó.
coredump
8

JavaScript ES6, 559 526 381 368 364 358 332 327 315 bytes

a="one0two0three0four0five0six0seven0eight0nine0ten0eleven0twelve0thir10four10fif10six10seven10eigh10nine1".replace(/1/g,'teen').split(0),b="twenty0thirty0forty0fifty".split(0),c=(n,d=Array,e=b.forEach(i=>a=a.concat(i,a.slice(0,9).map(x=>i+x))))=>1/n?a.slice(0,n).join():d.from(d(a.indexOf(n)+1),(x,i)=>i+1).join();

Gracias a Kritixi Lithos por la idea de dividir la matriz y Arnauld por el truco de 1 / n.

a="one0two0three0four0five0six0seven0eight0nine0ten0eleven0twelve0thir10four10fif10six10seven10eigh10nine1".replace(/1/g,'teen').split(0),b="twenty0thirty0forty0fifty".split(0),c=(n,d=Array,e=b.forEach(i=>a=a.concat(i,a.slice(0,9).map(x=>i+x))))=>1/n?a.slice(0,n).join():d.from(d(a.indexOf(n)+1),(x,i)=>i+1).join();

console.log(c("twentyfive"));
console.log(c("fifty"));
console.log(c(50));

Tom
fuente
1
Puede eliminar el vary puede cambiar la matriz ['one,'two',..]a"one0two0three0...".split(0)
Kritixi Lithos
Espacio en blanco redundante en null, Array(n).
Yytsi
2
Puedes reemplazar !isNaN(n)por 1/n. Esto le proporciona NaNuna cadena (falso), un flotador distinto de cero para un número entero distinto de cero (verdadero), o Infinitypara 0 (también verdadero).
Arnauld
Agregue 4 espacios delante de cada línea de código
sagiksp
@sagiksp Sí, debe haber estropeado algo al editar la publicación, debería arreglarse ahora :)
Tom
6

Python 2 , 503 499 494 490 479 bytes

-5 gracias a @JonathanAllan

l='one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#'.replace('#','teen ').split()
m='twenty','thirty','forty','fifty'
i,z,R=raw_input(),' ',range
try:n=int(i);p=(n/10)-2;o=(l+sum([[m[x]]+[m[x]+z+l[y]for y in R(9)]for x in R(p)],[])+[m[p]]+[m[p]+z+l[y]for y in R(n%10)],l[:n])[n<20]
except:j=i.split();o=map(str,R(1,(m.index(j[0])+2)*10+l.index(j[1])+2if z in i else l.index(i)+2if i in l else(m.index(i)+2)*10+1))
print','.join(o)

Pruébalo en línea!

Ingrese un número o una ortografía separada por espacios de un número.

Versión ligeramente menos golfizada y más legible:

l='one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen'.split()
m='twenty','thirty','forty','fifty'
i=raw_input()
try:
 n=int(i)
 if n<20:
  o=l[0:n]
 else:
  o=l
  for x in range((n/10)-2):
   o+=[m[x]]+[m[x]+' '+l[y]for y in' '*9]
  p=m[(n/10)-2]
  o+=[p]+[p+' '+l[y]for y in' '*n%10]
except:
 if' 'in i:
  t=i.split()
  s=((m.index(t[0])+2)*10)+l.index(t[1])+2
 else:
  s=l.index(i)+2 if i in l else((m.index(i)+2)*10)+1
 r=range(1,s)
 o=map(str,r)
print','.join(o)
ElPedro
fuente
1
6 bytes guardado conl="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nin#".replace("#","teen ").split()
Jonathan Allan
... Uy 5, se perdió el ede nineteen.
Jonathan Allan
¿Hay alguna razón por la que necesite usar Python 2, sin ella la impresión sería más larga, pero la entrada sin procesar podría ingresarse? (La misma pregunta para su otra respuesta)
nedla2004
@ nedla2004 - No hay otra razón que no sea que todavía no he podido instalar Python 3 en mi última computadora portátil :-)
ElPedro
6

Esquema, 161 , 152 , 149

(define (c x)(let((r(string->number x)))(let l((i 1))(let((n (format #f "~r" i)))(display(if r n i))(newline)(or(eq? r i)(equal? x n)(l (+ i 1)))))))

Sin comprimir:

(define (count limit)
  (let ((numerical-limit (string->number limit)))
    (let l ((i 1))
      (let ((current-number (format #f "~r" i)))
        (display (if numerical-limit current-number i))
        (newline)
        (or (eq? numerical-limit i)
            (equal? limit current-number)
            (l (+ i 1)))))))
Michael Vehrs
fuente
¿Cómo se convierte, por ejemplo, de "cuatro" a 4? No estoy seguro de string->numberhacer esto, lo verifiqué rápidamente y parece que se usa para convertir, por ejemplo, de cadena "4"a número 4.
coredump
@coredump Eso es correcto. (string->number "four")vuelve #f.
Michael Vehrs
¿Qué esquema estás ejecutando?
coredump
1
@coredump guile 2.0.9
Michael Vehrs
6

PHP - 397 372 349 344 329 bytes

Inspirado en la solución JS de TomDevs

Ahorró 25 bytes al reemplazar $a=[...]por$a=explode(...)

Ahorró otros 23 bytes volviendo a una matriz sin delimitadores de cadena y almacenando teenen una variable, gracias a @ user59178

Se guardaron otros 5 bytes al eliminar el (int)encasillado

Ahorró otros 15 bytes al soltarlos $b, $ien las fordeclaraciones y las llaves, gracias a @ user59178 nuevamente

$a=[one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir.$t=teen,four.$t,fif.$t,six.$t,seven.$t,eigh.$t,nine.$t];foreach([twenty,thirty,forty,fifty] as$c){$a[]=$c;for($i=0;$i<9;)$a[]=$c.'-'.$a[$i++];}if($argv[1]!=0)for($i=0;$i<$argv[1];)echo$a[$i++].' ';else for($i=1;$i<=array_search($argv[1],$a)+1;)echo$i++.' ';

Sin golf:

$a =[one,two,three,four,five,six,seven,eight,nine,ten,eleven,‌​twelve,thir.$t=teen,‌​four.$t,fif.$t,six.$‌​t,seven.$t,eigh.$t,n‌​ine.$t];
foreach ([twenty,thirty,forty,fifty] as $c){
    $a[] = $c;
    for ($i=0;$i<9;)
        $a[] = $c . '-' . $a[$i++];
}
if( $argv[1] !=0 )
    for ($i=0;$i<$argv[1];)
        echo $a[$i++] . ' ';
else
    for ($i=1;$i<=array_search($argv[1], $a)+1;)
        echo $i++ . ' ';

Pruébelo para una cadena de entrada o para un número de entrada

roberto06
fuente
1
Al jugar al golf, puede usar muchas cadenas directamente sin comillas, incluido todo el número que usa. Esto causa un aviso pero eso puede ser ignorado. Además, es más corto (en 2 bytes completos) para almacenar teenen una variable en lugar de repetirlo cada vez. Como tal, se convertiría en:$a=[one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir.$t=teen,four.$t,fif.$t,six.$t,seven.$t,eigh.$t,nine.$t];
user59178
No había pensado en eso, gracias;)
Roberto06
Puede guardar 7 bytes más al soltar $by colocar la segunda matriz directamente en el foreach, 6 bytes más al soltar todos los corchetes (aunque necesita ponerlos $a=$cen la configuración del bucle for) y 6 bytes más mediante el incremento posterior $icuando lo usas en lugar de en el bit 'after' de los bucles for.
user59178
Ahorre seis bytes (dos por ciclo) moviendo el incremento posterior de for a la siguiente línea:for ($i=0;$i<9;)$a[]=$c.'-'.$a[$i++];
Alex Howansky
Ooops, lo siento, acabo de notar que @ user59178 sugirió lo mismo ...
Alex Howansky
6

Python 2, 262 bytes

x="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#".replace("#","teen ").split()
x+=[a+"ty"+b for a in"twen","thir","for","fif"for b in['']+x[:9]]
v=input()
for s in range(1,x.index(v)+2)if v>50else x[:v]:print s

repl.it

Las cadenas de entrada y salida están en minúsculas y concatenadas *, por lo que para probar una entrada de cadena, ingrese, por ejemplo, "thirtyfive"en el indicador.

Construye la lista de todas las palabras (más "fiftyone"a "fiftynine"), xluego comprueba si inputes una palabra con el proxy v>50(las cadenas son mayores que los números en Python 2, y todos los números en el rango de entrada válido de la especificación son <=50) y son printlos apropiados los valores por rebanar ya sea la lista, x[:v]o la construcción de una serie de números enteros, range(1,x.index(v)+2).

* Agregar guiones en ambos costos 11 bytes, reemplazando a+"ty"bcon a+"ty"+'-'*(b>'')+b.

Jonathan Allan
fuente
5

Wolfram Language, 92 bytes

If[NumberQ@#, Do[Print@IntegerName@i, {i, #}], 
  Do[Print@i, {i, Interpreter["SemanticNumber"]@#}]] &

(Soy nuevo en esto, avíseme si hice algo mal)

usuario6014
fuente
2
-10 bytes:Do[Print@If[#>0,i,,IntegerName@i],{i,If[#>0,#,,Interpreter["SemanticNumber"]@#]}]&
JungHwan Min
5

JavaScript (ES6), 261 bytes

Nota: la cadena asignada a z está codificada con atob. En la cadena codificada hay 11 bytes que no puedo publicar en este sitio, incluso si son caracteres válidos en una cadena de JavaScript. Entonces usé un escape hexadecimal en la forma \ xHH. Cada uno de estos escapes se cuenta como 1 byte.
La cadena original sin comprimir es la versión menos golfizada .

x=>(z=btoa('ö\x89ÞöÜ(öØkyï_¢êý~+Þöȱöǯz\x7f^\x8a\x08möx§{Û^\x9f×¥z÷§öÜ\x1e\x96÷½¶\x18«÷×â\x7fß}z(!÷Ûpz\x7f}~\x8aý').split(9),o=(0+z.map((v,i)=>i<20?i<13?v:(v||z[i-10])+'teen':z.slice(0,10).map(d=>(z[i]||z[i-8]||z[i-18])+'ty'+d))).split`,`,p=o.indexOf(x),o.slice(1,-~x+p+!~p).map((x,i)=>~p?i+1:x))

Menos golf

x => (
  z = '9one9two9three9four9five9six9seven9eight9nine9ten9eleven9twelve9thir99fif999eigh99twen99for9'
      .split(9),
  o = (0 + // 0 + array to build a comma separated string
       z.map( (v, i) => 
         i < 20 
         ? i < 13 
           ? v // 1 to 13 are 'as is'
           : (v||z[i-10])+'teen' // compose for 14 to 19
         : z.slice(0,10).map(d=>(v||z[i-8]||z[i-18])+'ty'+d)) // 20s, 30s, 40s, 50s
      ).split`,`, // from comma separated to array again
  // o contains strings from one to fiftynine
  p = o.indexOf(x), // look for input
  o.slice(1, -~x+p+!~p).map((x,i) => ~p?i+1:x)
)

Prueba

F=
x=>(z=btoa('ö\x89ÞöÜ(öØkyï_¢êý~+Þöȱöǯz\x7f^\x8a\x08möx§{Û^\x9f×¥z÷§öÜ\x1e\x96÷½¶\x18«÷×â\x7fß}z(!÷Ûpz\x7f}~\x8aý').split(9),o=(0+z.map((v,i)=>i<20?i<13?v:(v||z[i-10])+'teen':z.slice(0,10).map(d=>(v||z[i-8]||z[i-18])+'ty'+d))).split`,`,p=o.indexOf(x),o.slice(1,-~x+p+!~p).map((x,i)=>~p?i+1:x))

function update() {
  var i=I.value
  O.textContent = F(i)
}  

update()
<input id=I value=25 oninput='update()'><pre id=O></pre>

edc65
fuente
ö\x89ÞöÜ(öØ...esto es genial jajaja
Albert Renshaw
Relevante para su nota principal: meta.stackoverflow.com/questions/342546/…
Albert Renshaw
5

Python 3 , 305 303 bytes

Convertido a Python 3 después del consejo de @ nedla2004. Ahora tampoco tiene espacio entre los números escritos en la entrada o salida, por ejemplo, ingrese veinte

l='one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#'.replace('#','teen ').split()
m='twenty','thirty','forty','fifty'
i,R=input(),range
l+=sum([[m[x]]+[m[x]+l[y]for y in R(9)]for x in R(3)],[])
for x in R(1,l.index(i)+2)if i in l else l[:int(i)]:print(x)

Pruébalo en línea 3!

Python 2 , 327 320 313 308 bytes

l='one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#'.replace('#','teen ').split()
m='twenty','thirty','forty'
i,R=raw_input(),range
l+=sum([[m[x]]+[m[x]+l[y]for y in R(9)]for x in R(3)],[])+['fifty']
for x in R(1,l.index(i)+2)if i in l else l[:int(i)]:print x

Pruébelo en línea 2!

163 170 177 bytes más corto que mi respuesta original, así que lo publico como alternativa. Esto se usa foren las dos listas para construir una lista completa de todas las representaciones de cadena de los números, luego identifica la correcta en la lista e imprime todo en ella, ya sea por valor o por índice. Emite una nueva línea para cada valor.

ElPedro
fuente
5

Python 2, 432 422 416 403 bytes

Estoy seguro de que esto se puede mejorar. Por lo menos, si puedo evitar codificar el valor en el que se va a trabajar y no necesitar una función, puedo guardar 20. Necesita un espacio para separar las palabras en la entrada de texto. Ahorré 6 bytes gracias al comentario de JonathanAllan sobre la respuesta de ElPedro, 4 por reorganizar las matemáticas.

def z(f):
 a,b,i,d="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#".replace("#","teen ").split()+[""],"twenty thirty forty fifty".split(),1,f>50
 if d:f=f.split();f=a.index(f[-1])+21+b.index(f[-2])*10 if len(f)>1 else b.index(f[-1])*10+20 if f[-1]in b else a.index(f[-1])+1
 while i<=f:s=i if d else a[i-1]if i<20 else b[i//10-2]+a[i%10-1];print s;i+=1

(Nota: la versión real de esto usa pestañas para sangrar en lugar de espacios. QPaysTaxes agregó un solo espacio porque no se procesó correctamente, para garantizar que el código dado se compila. No debería cambiar el recuento de bytes).

Chris H
fuente
El comentario de @ JonathanAllan sobre la respuesta de ElPedro también funciona aquí para -6
Chris H
1
len(`f`)>2puede ser ...`f`[2:]por otros 3, creo. (ignore que ...parece que los backticks no funcionan correctamente)
Jonathan Allan
De hecho, en Python 2 podrías ir por f>506. (y otro por no usar d)
Jonathan Allan
@JonathanAllan que no funciona para el paso de los números como enteros, que actualmente hago: TypeError: 'int' object has no attribute '__getitem__'. Si paso la entrada numérica como una cadena, f[2:]se acerca pero sigue fallando cuando se trata como un booleano ( print f[2:] and Trueimprime una línea en blanco si len (f) <2, no Trueo False)
Chris H
@JonathanAllan f>50funciona, gracias. Dejar caer dno es tan simple como siempre pongo el valor final del bucle en la flínea 8 para que no se pueda cambiar if f>50ya que nunca será cierto.
Chris H
4

C ++ 11, 484 480 477 bytes

#import<iostream>
#import<cstdlib>
#import<vector>
using namespace std;f(){int j,i=2;string s="teen";vector<string>v={"","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"};for(;i++<9;)v.push_back(v[i]+s);v[13]="thir"+s;v[15]="fif"+s;v[18]="eigh"+s;for(i=19;i++<50;){string n[4]={"twenty","thirty","forty","fifty"};v.push_back(n[i/10-2]+v[i%10]);}cin>>s;if(i=atoi(s.c_str()))for(j=0;j++<i;)cout<<v[j]<<" ";else while(v[i++]!=s)cout<<i<<" ";}

Entrada de texto en minúsculas sin guiones.

Steadybox
fuente
3

PowerShell , 362 bytes

$z=0..50|%{("0twenty0thirty0forty0fifty"-split0)[+(($b="$_"[0])-gt49)*($_-gt19)*(+"$b"-1)]+($x=(("0one0two0three0four0five0six0seven0eight0nine0ten0eleven0twelve"-split0)+(-split'thir four fif six seven eigh nine'|%{$_+'teen'})))[($_%10)*($_-gt19)]+$x[$_*($_-le19)]}
if(($n=-split$args)[0][0]-in48..57){$z[$n[0]..$n[2]]}else{$z.IndexOf($n[0])..$z.IndexOf($n[2])}

Pruébalo en línea! entrada de palabras o entrada de números

Esto es un desastre, y no estoy terriblemente feliz con eso, pero aquí está. Sugerencias de golf bienvenidas.

La primera línea se establece $zcomo un conjunto de palabras completas en inglés. Se puede ver la -split0de los números 1a 12, y el bucle para construir todas las teens, y luego hay un montón de lógica para poner todo junto derecha.Pruébalo en línea!

La segunda línea comienza con algo de lógica. Tomamos la entrada $args(como una cadena), la -splitalmacenamos en un espacio en blanco, la almacenamos $npara usarla más tarde, tomamos la primera [0]palabra y el primer [0]carácter de eso, y verificamos si es -inun rango 48..57(es decir, ASCII 0para9 ). Entonces, estamos verificando si tenemos entrada decimal o entrada en inglés.Pruébalo en línea!

En el primer caso, construimos un rango basado en las entradas decimales $n[0]..$n[2]y lo usamos para indexar $z[...]. En el otro caso, encontramos la .indexOf()primera palabra y la última palabra, y construimos solo un rango numérico a partir de eso. En cualquier situación, ahora tenemos una matriz de objetos en la tubería (cadenas o enteros), y un implícito Write-Outputal finalizar el programa nos da una nueva línea entre los elementos.

AdmBorkBork
fuente
3

Swift3, 402 bytes

let f=["one","two","three","four","five","six","seven","eight","nine"]
let g=["twenty","thirty","forty","fifty"]
let v=[f,["ten","eleven","twelve"],["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"},[g[0]],f.map{g[0]+$0},[g[1]],f.map{g[1]+$0},[g[2]],f.map{g[2]+$0},[g[3]]].flatMap{$0}
func c(s:String){if let i=Int(s){print(v.prefix(upTo:i))}else{for j in 1...v.index(of:s)!+1{print(j)}}}

Sin golf:

let f = ["one","two","three","four","five","six","seven","eight","nine"]
let g = ["twenty","thirty","forty","fifty"]

let values = [f,["ten","eleven","twelve"],["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"},
              [g[0]], f.map{g[0]+$0},
              [g[1]], f.map{g[1]+$0},
              [g[2]], f.map{g[2]+$0},
              [g[3]]].flatMap{$0}

func count(s:String){
    if let i = Int(s) {
        print(values.prefix(upTo: i))
    } else {
        for j in 1...values.index(of: s)!+1{
            print(j)
        }
    }
}

count(s:"29")
count(s:"twentyeight")

Nada especial aquí, solo usando una matriz para hacer una copia de seguridad de los números escritos.

Originalmente pensé que esta solución usaba esta otra forma de calcular la valuesmatriz:

let values = f + ["eleven","twelve"]
    + ["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"}
    + [g[0]] + f.map{g[0]+$0}
    + [g[1]] + f.map{g[1]+$0}
    + [g[2]] + f.map{g[2]+$0}
    + [g[3]]

Que podría ser golf para:

let v=f+["eleven","twelve"]+["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"}+[g[0]]+f.map{g[0]+$0}+[g[1]]+f.map{g[1]+$0}+[g[2]]+.map{g[2]+$0}+[g[3]]

reemplazando la tercera línea en el código de golf

Podría haber puntuado 381 bytes, pero hay un error del compilador que dice: "la expresión era demasiado compleja para ser resuelta en un tiempo razonable", puede encontrar más información sobre el error aquí

Rodrigo Ruiz Murguía
fuente
Me encanta ver rápido aquí, tendré que revisar esto más cuando regrese
Albert Renshaw
3

R, 452 430 424 bytes

o=c("","one","two","three","four","five","six","seven","eight","nine") 
t=gsub(0,"teen",c("ten","eleven","twelve","thir0","four0","fif0","six0","seven0","eigh0","nine0"))
s=c("twenty","thirty","forty") 
p=""
for(i in s){for(j in o){p=paste0(p,i,j," ")}}
as.data.frame(t(d<-1:50))
names(d)=c(o[-1],t,as.vector(strsplit(p," ")[[1]]),"fifty")
f=function(x){if(is.numeric(x)){names(d)[1:x]}else{matrix(d[1:d[x]],dimnames=NULL)}}

#> f(5)
#[1] "one"   "two"   "three" "four"  "five" 

#> f('five')
#     [,1]
#[1,]    1
#[2,]    2
#[3,]    3
#[4,]    4
#[5,]    5

Coloca los números en un marco de datos con números escritos como nombres de columna, lo que hace que la traducción entre los dos (y la posterior impresión) sea bastante fácil.

El principal intento de jugar golf fue crear los números escritos para 20-49, probablemente mucho más para jugar golf aquí.

Hice un intento de as.matriximprimir el hoja.de.datos con sólo los números, pero aún tengo una cabecera de matriz. Espero que esté bien.

Sin golf:

ones <- c("","one","two","three","four","five","six","seven","eight","nine") 
teens <- c("ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen")
tens <- c("twenty","thirty","forty") 

p=""
for(i in tens){
  for(j in ones){
    p=paste0(p, i, j," ")
  }
}

nums <- 1:50
as.data.frame(t(nums))
names(nums) <- c(ones[-1], teens, as.vector(strsplit(p, " ")[[1]]), "fifty")
f <- function(x){
  if(is.numeric(x)){
    names(nums)[1:x]
  } else {
    matrix(nums[1:nums[x]], dimnames = NULL)
  }
}
BLT
fuente
Ligera mejora de 359 Bytes:o=c("","one","two","three","four","five","six","seven","eight","nine") ; v=c("ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"); w=c("twenty","thirty","forty"); a=data.frame(0:50, c(o,v, sapply(w[1:3],function(y) sapply(o,function(x) paste0(y,x))),"fifty")); b=which(a==i); a[if(b<52) 2:b else 2:(b-51),ifelse(b<52,2,1)]
recuento de
¡@count parece una gran mejora! Sin embargo, parece que no puedo entender dónde está la función o dónde tomarías una discusión.
BLT
2

C, 342 331 bytes

char*x[]={"teen","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thir","four","fif","twenty","thirty","fourty","fifty"};void main(int z,char**i){for(z=1;z<=atoi(i[3]);z++)printf("%s%s%s\n",z<16?x[z]:z<20?z^18?x[z-10]:"eigh":x[z/10+14],z>20&&z%10?"-":z>12&&z<20?*x:"",z>20&&z%10?x[z%10]:"");}

Pruébalo en línea!

Ahemone
fuente
Mi idioma favorito :)
Albert Renshaw
1
En realidad no necesita el 1 o el 1; todo lo que requiere este codegolf es tu tercer argumento. Los dos primeros siempre serán "1 y hasta" (o "uno y hasta")
Albert Renshaw
@AlbertRenshaw ¡Buena llamada! Gracias :)
Ahemone
1

SAS, 179

%macro c(n);%let f=words.;%if%length(&n)>2%then%do;%do c=1%to 50;%if%qsysfunc(putn(&c,&f))=&n%then%let n=&c;%end;%let f=2.;%end;%do i=1%to &n;%put%sysfunc(putn(&i,&f));%end;%mend;

La salida se escribe en el registro separada por nuevas líneas. SAS tiene un formato incorporado para convertir dígitos a palabras, lo cual es una gran ventaja para este desafío, pero molestamente carece de información para hacer lo contrario.

usuario3490
fuente