El sistema principal es un dispositivo mnemotécnico para convertir números en palabras para que puedan memorizarse más fácilmente.
Se basa en cómo suenan las palabras fonéticamente, pero para simplificar las cosas para el desafío, solo nos preocuparemos de cómo se deletrean las palabras. Esto significa que habrá algunas conversiones incorrectas, pero está bien.
Para convertir un número en una palabra utilizando nuestro sistema principal simplificado:
- Reemplace cada uno
0
cons
oz
. (Algunos podrían sers
y otros podrían serz
. Lo mismo va abajo).- Reemplace cada uno
1
cont
od
oth
.- Reemplace cada uno
2
conn
.- Reemplace cada uno
3
conm
.- Reemplace cada uno
4
conr
.- Reemplace cada uno
5
conl
.- Reemplace cada uno
6
conj
osh
och
.- Reemplace cada uno
7
conk
oc
og
oq
.- Reemplace cada uno
8
conf
ov
.- Reemplace cada uno
9
conp
ob
.- Agregue las letras
aehiouwxy
en cualquier lugar en cualquier cantidad para hacer una palabra real en inglés, si es posible .
La única excepción es queh
no se puede insertar después de uns
oc
.El número en realidad puede ser cualquier cadena de los dígitos 0-9 (sin decimales, comas o signos).
La palabra solo puede contener las letras minúsculas az.
Ejemplos
El número 32
debe convertirse como ?m?n?
, donde ?
representa cualquier cadena finita hecha de las letras aehiouwxy
(una cadena del monoide libre si lo prefiere). Hay muchas maneras en que esto podría convertirse en una verdadera palabra Inglés: mane
, moon
, yeoman
, etc.
El número 05
se puede convertir como ?s?l?
o ?z?l?
. Algunas posibilidades son easily
, hassle
y hazel
. La palabra shawl
no está permitida porque h
no se puede colocar después s
; se leería incorrectamente como 65
.
Desafío
Escriba un programa o función que tome una cadena de los dígitos 0-9 y encuentre todas las palabras en las que podría convertirse utilizando el sistema principal simplificado mnemónico.
Su programa tiene acceso a un archivo de texto de lista de palabras que define cuáles son todas las palabras "reales" en inglés. Hay una palabra az minúscula en cada línea de este archivo, y opcionalmente puede suponer que tiene una nueva línea final. Aquí hay una lista de palabras reales que puede usar para probar. Puede suponer que este archivo de lista de palabras se llama f
(o algo más largo) y se encuentra en cualquier directorio conveniente.
Para una penalización de 35 bytes (agregue 35 a su puntaje), puede suponer que la lista de palabras ya está cargada en una variable como una lista de cadenas. Esto es principalmente para idiomas que no pueden leer archivos, pero cualquier envío puede aprovecharlo.
Su programa debe generar todas las palabras en la lista de palabras a las que se puede convertir el número de entrada. Deben imprimirse en stdout (o similar), uno por línea (con una nueva línea final opcional), o pueden devolverse como una lista de cadenas si elige escribir una función. La lista de palabras no está necesariamente alfabetizada y la salida tampoco necesita serlo.
Si no hay palabras posibles, la salida (o la lista) estará vacía. La salida también está vacía si se ingresa la cadena vacía.
Tome la entrada a través de stdin, línea de comando o como argumento de cadena a una función. La lista de palabras, o su nombre de archivo, no debe ser parte de la entrada, solo la cadena de dígitos.
Solo está haciendo coincidir palabras individuales en la lista de palabras, no secuencias de palabras. La palabra noon
probablemente sería uno de los resultados 22
, pero la secuencia de palabras no one
no lo sería.
Casos de prueba
Supongamos que esta es la lista de palabras:
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
zdnmrlshchvb
sthnmrlchgvb
shthnmrlchgvb
bob
pop
bop
bopy
boppy
La entrada 0123456789
debe dar todas las palabras largas excepto zdnmrlshchvb
y shthnmrlchgvb
:
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
La entrada 99
debe dar:
bob
pop
bop
bopy
(Las palabras de salida pueden estar en cualquier orden).
Puntuación
La presentación más corta en bytes gana. Tiebreaker va a la presentación publicada primero.
Respuestas:
Perl,
8784Toma la entrada como el parámetro de línea de comando:
Se puede acortar un poco si se permitiera la lista de palabras en la entrada estándar:
fuente
A
significa enopen A,f
?<A>
).Python 2,
215208 bytesEsta solución de Python crea una expresión regular a partir de partes indexadas por el argumento de la línea de comando, luego prueba cada palabra con esa expresión regular (bastante grande).
Fuente original antes del minificador:
Por ejemplo, la expresión regular para la prueba
99
es:El
(?<![sc])h
bit es un componente de "mirar detrás de la afirmación negativa" que asegura que ah
no siga as
oc
en las partes de relleno generales.Gracias calvin Este desafío me motivó a repasar mis habilidades oxidadas de expresiones regulares.
fuente
b=c='((?<![sc])h|[aeiouwxy])*'
ahorrará dos bytes.t|th -> th?
guarda un bytePitón 3, 170
Versión legible:
El código hace uso del hecho de que
th
es redundante (ya que se asigna al mismo número quet
, yh
es un carácter de relleno).La
maketrans
función estática crea una tabla que asigna los caracteres del primer argumento a los del segundo argumento y los caracteres del tercer argumento aNone
(lo que dará como resultado que esos caracteres se eliminen).El código final podría acortarse unos pocos bytes creando la tabla como argumento directo de
translate
.fuente
input()
se pueda usar, porque se llama dentro de un bucle. Además, su expresión regular sugerida tiene la misma longitud que la que ya estoy usando (5 bytes).sed, pegar, grep, cortar - 109
Toma un archivo "w", convierte cada palabra en su número, vuelve a pegarla al original, grep para el número y devuelve la palabra coincidente. Tenga en cuenta que el espacio en blanco después de la cita después de grep es una pestaña, delimitador predeterminado de pegar.
Sé que Perl está muy por delante, solo quería una mejor versión de shell como ejemplo.
Ah, sí, la parte de $ 1 significa que se supone que se debe ejecutar desde un script de shell (la mayoría de los shells deberían funcionar), por lo que requiere un argumento de línea de comandos.
fuente
sed
para evitar la apertura y la@ARGV
sobrecarga de Perl , pero la falta de rangos y funciones de eliminación lay///
rompe. Sorprendentemente, aunque no hay variables en las que pueda expresar la lógica directamentesed
. Aquí está mi solución 92:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
Bash + coreutils, 216
w
sed
reemplaza los dígitos con sus posibles reemplazos.eval printf
usos shell expansiones abrazadera para ampliar a cabo todas las posibles sustitucionessed
en la primera línea eliminaaeiouwxy
yh
(cuando no está precedido por[sc]
) de la lista de palabrasaeiouwxy
yh
de la lista de palabras, el últimosed
convierte los resultados de grep (números de línea de cada coincidencia) en otrased
expresión, que es procesada por el exteriorsed
para revelar todas las palabras posibles de la lista de palabras.Salida:
El archivo de lista de palabras se especifica como un argumento de línea de comando, seguido del número para mnemonizar:
fuente
tr, sed, grep, xargs, sh, 77
Espera el número en stdin y la lista de palabras debe almacenarse en el archivo
f
.No utiliza todos los reemplazos (1 siempre será z, 7 siempre será k), por lo que puede llamarse una solución perezosa, pero encuentra al menos un mnemónico para 95 números en [1-100].
fuente
1
siempre seaz
o7
siemprek
. Esto no es válido