Duolingo, la aplicación de aprendizaje de idiomas, tiene muchas cosas a su favor, pero hay un problema importante que me vuelve loco. Me dice cuántos días seguidos he usado la aplicación con un mensaje como ¡Estás en una racha de 7 días! Dejando a un lado la separación silábica y si el número se debe deletrear, esto funciona bien para la mayoría de los números, ¡pero es indiscutiblemente incorrecto cuando dice que estás en una racha de 8 días! No lo estoy usando para aprender inglés, pero este sigue siendo un comportamiento desafortunado para una aplicación de idiomas.
Ayudará al equipo de Duolingo escribiendo un programa completo o una función que determine si un número dado debe estar precedido por a o an . Un número está precedido por un si su pronunciación en inglés hablado comienza con un sonido de consonante o semivowel , y está precedido por un si su pronunciación comienza con un sonido de vocal. Por lo tanto, los únicos números precedidos por un son aquellos cuya pronunciación comienza con ocho , once , dieciocho u ochenta .
Presumiblemente, el equipo de desarrollo de Duolingo dejó este error porque se quedaron sin espacio para más código fuente en la aplicación, por lo que debe hacer que este código sea lo más breve posible con la esperanza de que puedan introducirlo.
Su código debe tomar un número entero de 0 a 2,147,483,647 y generar ao an. Una nueva línea final es opcional. Para los propósitos de este desafío, 1863 se lee como mil ochocientos sesenta y tres , no mil ochocientos sesenta y tres .
Casos de prueba:
0 → a
8 → an
11 → an
18 → an
84 → an
110 → a
843 → an
1111 → a
1863 → a
8192 → an
11000 → an
18000 → an
110000 → a
180000 → a
1141592 → a
1897932 → a
11234567 → an
18675309 → an

Respuestas:
Pyth, 23 bytes
Esto selecciona cuántas letras se cortarán al final
"an"al verificar si la primera letra no es un8y que el primer dígito del número cuando se considera en la base 1000 no es ni 11 ni 18. El booleano resultante es el número de caracteres para cortar el fin.fuente
Python 2, 60 bytes
Una función anónima. Agrega un
nif si:fuente
n> = '8' '`ahorra tres bytes.GNU Sed, 32
La puntuación incluye +1 para la
-Eopción de sed.Pruébalo en línea.
anaGracias a @ MartinBüttner por su enfoque de retina que ahorró 10 bytes.
fuente
Juegos de Shell + bsd, 30
Entrada leída desde STDIN.
numberConvierte una cadena decimal en palabras. Entonces es una cuestión simple decidir si el resultado comienza o noe.fuente
Retina , 27 bytes
Esto no es muy diferente de la respuesta Retina de DigitalTrauma, pero insistieron en que publique esto yo mismo.
Pruébalo en línea.
La primera expresión regular reemplaza todos los números relevantes con
an, y la segunda reemplaza todos los números restantes cona. Esto funciona para los mismos bytes:fuente
C ++, 101
Este es mi desafío, por lo que no pretende ser una respuesta competitiva. Solo quería ver qué tan corto podría obtenerlo en C ++. Las operaciones de cadena son demasiado detalladas, por lo que esto se hace con las matemáticas. Siento que debe haber una forma de reducir esa condición, pero no puedo entenderlo.
fuente
Mathematica, 53 bytes
Una solución que utiliza el procesamiento de cadenas en realidad terminaría siendo más larga.
fuente
PostScript,
119113caracteresCon código de prueba:
fuente
JavaScript (ES6)
70614638 bytesWiki de la comunidad porque la solución actual es muy diferente a la original. ¡Gracias a todos!
Demostración: http://www.es6fiddle.net/iio40yep/
fuente
evaltruco! Sabía que también tenía que haber una mejor expresión regular, pero no podía entender nada que fuera más corto. ¡Gracias!n=>/^8|^(?=1[18])..(\d{3})*$/.test(n)?'an':'a'( es6fiddle.net/iiehl1ex ). Tiene 46 bytes de longitud.8, si comienza con1[18]y si la longitud de los números es2 * (3n). Básicamente, es todo su código, pero dentro de una expresión regular.En serio,
4340 bytesLa estrategia aquí es mirar solo los 1, 2 o 3 dígitos más significativos, dividiendo la entrada por el valor más grande
10^(3n)que sea menor que la entrada.Pruébalo en línea
Explicación:
fuente
Retina , 34
Traducción directa de mi respuesta sed :
Pruébalo en línea.
Un byte guardado gracias a @Timwi.
fuente
Perl 6 ,
3130 bytes(Perl 6 se usa
[ ]en expresiones regulares para no capturar( )y<[ ]>para juegos de caracteres)Uso:
fuente
PostScript, 109 bytes
El código verifica si el número comienza con ciertos prefijos. El prefijo
8siempre se verifica ( ocho , ochenta y algo , ocho cientos y ), pero11y18( once y dieciocho ) se verifican solo cuando el número de dígitos es un múltiplo de 3 más 2.Comenzamos con un resultado tentativo de
ay cuando se encuentra un prefijo, el resultado se reemplaza poran.anchorsearchse usa para evitar extraer un prefijo de la cadena. Incluso si se encuentra una coincidencia, continuamos verificando el resto de los prefijos: ¿por qué desperdiciar 5 bytes para elexit? -, pero debido a que la cadena original se reemplaza poraestamos seguros de no obtener ningún falso positivo.Para devolver el resultado
a-o--anen la pila de operandos en lugar de imprimirlo, elimine el final=(longitud resultante: 107 bytes).Código de prueba:
fuente
PostScript (con tokens binarios), 63 bytes
El
’son bytes con el valor 146 (decimal),¥es un 165 y$es un 3. Todos los demás son imprimibles caracteres ASCII de 7 bits.Esto es lo mismo que mi versión PostScript [ASCII puro], pero usa tokens binarios donde esto ayuda a reducir la longitud total. Lo publico por separado por 3 razones:
fuente
Python 3,
11093917674706564 bytesAquí hay uno largo, pero simple.
Editar: corregido con gracias a Isaac . Guarde algunos espacios en blanco después de las comparaciones. Muchos bytes guardados gracias a Timwi , Mego , Benpop y Alissa .
o para el mismo número de bytes.
Sin golf:
fuente
843, "ochocientos cuarenta y tres", que debería seran.(-~len(n)%3)<1lugar delen(n)%3==2?(n[:2]=="11"or n[:2]=="18")ser acortado a"118".contains(n[:2])?n[:2]in"118"?Java 10, 102 bytes
Pruébalo en línea.
Explicación:
fuente
Japt ,
2827 bytesPruébalo en línea!
Desempaquetado y cómo funciona
fuente
1e3conA³GNU
sed -r+ BSDnumber, 34 bytesPrimero lo convertimos al número en inglés. Luego borre todo excepto una posible inicial
ey prefije cona. Luego convierta ele(si está presente) an. El único truco de golf es hacer coincidir lo opcionaleen la primera sustitución, para que podamos reutilizar el patrón en la siguiente línea.Manifestación
fuente
TeaScript , 35 bytes
Pruébalo aquí
Explicación
fuente
Python 2.7, 66
Obviamente no tan corto como el
lambda.fuente
05AB1E , 26 bytes
Probablemente se pueda jugar un poco más, pero está funcionando.
Pruébelo en línea o verifique todos los casos de prueba .
Explicación:
fuente
QuadS , 32 bytes
Pruébalo en línea!
fuente
Stax , 25 bytes
Ejecutar y depurarlo
Desempaquetado, sin golf y comentado, se ve así.
Ejecute este
fuente
Espacio en blanco , 243 bytes
Se agregaron letras
S(espacio),T(tabulación) yN(nueva línea) solo como resaltado.[..._some_action]agregado solo como explicación.Pruébelo en línea (solo con espacios en bruto, pestañas y nuevas líneas).
El programa se detiene con un error: no se encontró ninguna salida.
Explicación en pseudocódigo:
fuente
C ++,
8079 bytesResultó 4 bytes más corto para probar explícitamente contra 8xx y 8x que para tener otro
/=10ciclo, como este:Manifestación
fuente
i/=1000serloi/=1e3y todo puede&&llegar a ser&?&&puede ser todo&, porque la resta produce enteros y no booleanos, por ejemplo,19-11es 8 y19-18es 1; ve que eso8 && 1es cierto, pero8 & 1es falso. Podríamos usar&, pero tendríamos que cambiar-a!=y también añadir entre paréntesis.&hecho no funciona aquí, mi mal. Por cierto, ¿por qué no agrega un enlace TIO a su respuesta también?Perl 5
-p, 26 bytesPruébalo en línea!
fuente
Perl,
715549 bytesSabía que el operador ternario ayudaría algún día ...
Déjame analizar esto.
$_=<>acepta un número como entrada.$_=...bloque grande establecerá el valor de$_después de que se use....?...:...es el operador ternario. Si la condición (primer argumento) es verdadera, devuelve el segundo argumento. De lo contrario, devuelve el tercero./^8/||(/^1[18]/&&length%3==2)comprueba si el número comienza con 8 o comienza con 11 o 18 (1[18]acepta cualquiera) y tiene una longitud mod 3 de 2.$_se establece enan. De lo contrario, se establece ena.$_(ya seaaoan) consay.Cambios
fuente
$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';sayGuarda algunos bytes. (Aunque el número de comparar a ella depende de lo que su carácter de nueva línea es, pero eso no cambia el número de bytes.)length($_)alength(o al menos descartar a los padres), pero eso no funciona para mí por alguna razón.($_)obtener$_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';say, que son solo 49 bytes.-plugar de$_=<>ysay, eny///clugar delength, y soltando las comillasayan:perl -pe'$_=/^8/||/^1[18]/&&y///c%3==2?an:a'(34 bytes + 1 para-p). Tenga en cuenta que de entrada no puede terminar en una línea:echo -n 11 | perl -pe'...'. Esto también corrige un error:length%3==2se analiza comolength(%3)==2, no comolength($_)%3==2, por lo que siempre devuelve falso.Pyth,
2931Invierte la cadena, la divide en secciones de tres, la invierte nuevamente, luego elige el final apropiado.
fuente
111- daan