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 a
o 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 un8
y 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
n
if si:fuente
n
> = '8' '`ahorra tres bytes.GNU Sed, 32
La puntuación incluye +1 para la
-E
opción de sed.Pruébalo en línea.
an
a
Gracias a @ MartinBüttner por su enfoque de retina que ahorró 10 bytes.
fuente
Juegos de Shell + bsd, 30
Entrada leída desde STDIN.
number
Convierte 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
eval
truco! 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
8
siempre se verifica ( ocho , ochenta y algo , ocho cientos y ), pero11
y18
( 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
a
y cuando se encuentra un prefijo, el resultado se reemplaza poran
.anchorsearch
se 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 pora
estamos seguros de no obtener ningún falso positivo.Para devolver el resultado
a
-o--an
en 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)<1
lugar 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
1e3
conA³
GNU
sed -r
+ BSDnumber
, 34 bytesPrimero lo convertimos al número en inglés. Luego borre todo excepto una posible inicial
e
y prefije cona
. Luego convierta ele
(si está presente) an
. El único truco de golf es hacer coincidir lo opcionale
en 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
/=10
ciclo, como este:Manifestación
fuente
i/=1000
serloi/=1e3
y todo puede&&
llegar a ser&
?&&
puede ser todo&
, porque la resta produce enteros y no booleanos, por ejemplo,19-11
es 8 y19-18
es 1; ve que eso8 && 1
es cierto, pero8 & 1
es 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 seaa
oan
) consay
.Cambios
fuente
$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';say
Guarda 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.-p
lugar de$_=<>
ysay
, eny///c
lugar delength
, y soltando las comillasa
yan
: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==2
se 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