Pangramas de autoenumeración

12

Pangramas

El rápido zorro marrón saltó sobre el perro perezoso.

Este es un ejemplo de pangrama, una oración que contiene cada letra del alfabeto al menos una vez.

Un pangrama de enumeración automática es una oración que cumple los criterios para ser un pangrama al producir un análisis de su propio recuento de letras.

Un ejemplo de lograr esto es la oración

Este pangrama contiene cuatro As, una B, dos Cs, una D, treinta Es, seis Fs, cinco Gs, siete Hs, once Es, una J, una K, dos Ls, dos Ms, dieciocho Ns, quince Os, dos Ps , una Q, cinco Rs, veintisiete Ss, dieciocho Ts, dos Us, siete Vs, ocho Ws, dos Xs, tres Ys y una Z.


El reto

Produzca una función con la entrada que es la cadena que conduce al inventario de letras. En el ejemplo, la entrada sería "Este pangrama contiene". La cantidad de cada letra debe estar en forma escrita y contribuir al recuento de letras que se muestra.


Reglas

  • La coma de Oxford es opcional
  • Use un signo "y" antes de Z (o, para el modo difícil, incluya la capacidad de cambiar entre "&" y "y" en la función)
  • Cada letra cuenta para el total de letras
  • No hay números no escritos.
  • Este es el por lo que gana el código más corto en bytes
  • En hono u r de la pareja este fin de semana, los números deben ser escritos en Inglés de la Reina. por ejemplo, nine hundred and ninety-nine Gspara 999 apariciones de la letra G y nine hundred and nine Gspara 909.
  • Los órdenes de magnitud deben escribirse en la convención de nomenclatura estándar a pequeña escala

Casos de borde

  • Hay algunos casos en los que el código se atasca en un bucle; por ejemplo, si hay dos Os, el código aumentará el recuento a tres Os, lo que hace que el código cuente dos Os nuevamente. Si calcular cualquier otra letra antes de volver a esto no puede resolver el problema, considere que la entrada es un arranque y salida falsos false, nullo una cadena vacía.
  • Si una carta tiene más de 999 apariciones, la entrada debe considerarse un falso iniciador.

Casos de prueba

  • "Este pangrama contiene" debería mostrar la oración de ejemplo
Robar
fuente
8
No lo he probado, pero estoy bastante seguro de que hay algunos casos en los que no se puede construir una solución válida, ¿cuál debería ser la salida en ese caso? Por ejemplo, si tiene una cadena que contiene dos o-s sin la palabra para el recuento, cuando la deletrea two, toda la cadena ahora tiene tres o-s, lo que significa que la palabra ahora es incorrecta, cambiarla la vuelve a hacer incorrecta , etc.
Nit
2
¿Cuál es el número escrito más grande que la solución tiene que soportar? ¿Cien, mil, un millón?
Nit
77
Buena primera pregunta! Sin embargo, personalmente recomendaría limitar el número máximo de letras a 999 o tal vez incluso a 99. Esto haría que el desafío sea más accesible para los idiomas que no tienen incorporados decimales a texto, al tiempo que preserva toda la diversión. (Además, puede que ni siquiera sea posible probar entradas con millones de letras en algunos idiomas.)
Arnauld
1
Rob enjoys any sentence with two As, two Bs, two Cs, one D, thirty five Es, four Fs, three Gs, nine Hs, eight Is, two Js, one K, two Ls, one M, twenty two Ns, eighteen Os, one P, one Q, nine Rs, twenty three Ss, twenty three Ts, three Us, four Vs, eleven Ws, one X, seven Ys, & one Z.
Chas Brown

Respuestas:

6

Python 2 , 615 bytes

def g(n):S=str.split;D=S('z one two three four five six seven eight nine');K=' fif six seven eigh nine';n,m=n/100,n%100;e,d=m/10,m%10;return' '.join([D[n],'hundred']*(n>0)+([S('ten eleven twelve thir four'+K)[d]+'teen'*(d>2)]if 9<m<20else[S('twen thir for'+K)[e-2]+'ty']*(e>0)+[D[d]]*(d>0)))
from random import*
X='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def f(p):
 T=set();s='';i=0
 while 1:
	Q=s.upper().count;t=p+' '+', '.join(['& '*(c=='Z')+g(Q(c))+' '+c+'s'*(Q(c)!=1)for c in X])+'.'
        if s==t:return i,t
	if t in T:t=''.join(c*max(1,t.upper().count(c)+(randint(0,6)-3)*(random()<0.25))for c in X)
	T.add(t);s=t;i+=1

Pruébalo en línea!

La función ftoma pcomo prefijo de cadena; y devuelve una tupla de un número entero que representa el número de pasos dados y el autograma.

La función gcodifica un número 1<=n<=999a su cadena inglesa; ocupa 291 bytes, aproximadamente la mitad del recuento total de bytes. El código

Q=s.upper().count
t=p+' '+', '.join(['& '*(c=='Z')+g(Q(c))+' '+c+'s'*(Q(c)!=1)for c in X])+'.'

codifica la cadena sen un pangrama (potencialmente autogramático) t.

Hacemos un bucle sobre el proceso, esperando la situación en la que encontramos un ttal que tes un autograma (es decir, dónde t==s). Si cuando entramos en un ciclo, empujamos aleatoriamente los recuentos de letras de una manera completamente ad hoc.

Para la mayoría de los valores de p, este proceso expirará en TIO. Por lo general, se examinan millones de posibilidades antes de encontrar una combinación 'ganadora'.

No tengo ninguna prueba en absoluto, pero mi suposición es: (a) aparte de una exhaustiva búsqueda de fuerza bruta similar a la que el autor Lee Sallows describe aquí e implementa en hardware (!), Este tipo de heurística aleatoria es casi como bueno como puedes conseguir; y (b) no habrá soluciones para muchas (¿la mayoría?) frases iniciales p.

Chas Brown
fuente
map(chr,range(65,91))Guarda algunos bytes.
ბიმო