Aritmética ... tock ... tick ... tock

15

Esta pregunta te la trajo un juego que me gusta jugar cuando estoy atrapado en largas reuniones telefónicas.

Dadas dos veces de un reloj de 24 horas (de 00:00 a 23:59), ¿cuántas ecuaciones matemáticas válidas se pueden generar con todas las veces intermedias usando solo operaciones aritméticas básicas?

Entrada: dos cadenas de cuatro dígitos (sin dos puntos) que representan tiempos válidos en un ciclo de 24 horas.

Ejemplos:

Para entrada = 0000, 1300

03:26 produces: "0+3*2=6" and "03*2=6" etc.
11:10 produces quite a few, including: "1*1=1+0" and "1=1=1^0" and  "1=11^0" etc.
12:24 produces: "1/2=2/4" and "1=(2*2)/4" etc.

Las operaciones válidas son:

  • adición
  • sustracción
  • multiplicación
  • división (punto flotante)
  • exponenciación
  • factorial

Otros símbolos permitidos

  • Paréntesis
  • Signos iguales

El código más corto gana.

Notas

  • El objetivo es encontrar el número de expresiones válidas entre dos veces, no el número de veces que contienen una expresión válida.
  • Los dos tiempos dados como entrada se incluyen en el rango de tiempos.
  • Puede agrupar los dígitos de cualquier manera posible, por lo que "1223" puede ser "12 23" o "1 2 23" o "1 223", etc., etc.
  • Puede usar tantos paréntesis como sea necesario.
  • Puede usar más de un =signo. Por ejemplo, el tiempo 11:11tiene la expresión válida 1=1=1=1.
  • Si la primera vez ocurre cronológicamente después de la segunda, el rango de tiempos debe ajustarse como si se cruzara al día siguiente.
  • Los números deben permanecer en su orden original; no puede volver a ordenar los dígitos.
  • Cuando se agrupan números, los ceros pueden ser absolutamente el dígito más delantero, en cuyo caso, se ignoran ("0303" agrupado como "03 03" son solo dos dígitos con el valor de 3.)
  • NO PUEDE usar el signo menos como negación unaria. Por lo tanto, "12:01" NO produce "1-2 = - (01)", pero produce "1-2 = 0-1".
  • NO PUEDE agregar puntos decimales a los dígitos. Por lo tanto, "12:05" NO produce "1/2 = 0.5".
  • Sin encadenamiento de factoriales: un dígito puede ser seguido por un máximo de "!", No más, de lo contrario, muchas veces tendrían infinitas soluciones. Ej: "5!" es válido pero "5 !!" no es válido.
nobillygreen
fuente
44
" Las operaciones válidas incluyen " parece evitar que pueda agregar casos de prueba. Sería una mejor pregunta si cambiara eso a " Las operaciones válidas son " y agregue algunos casos de prueba. También sería útil ser preciso acerca de los puntos finales: para la entrada, ¿ 0000 1300deberían las ecuaciones derivadas 0000e 1300incluirse en el recuento?
Peter Taylor
1
Dados los dígitos "1423", haga "1 + 4 = 2 + 3", "(1 + 4) = (2 + 3)", "(1 + 4) = 2 + 3" y "1 + 4 = (2 +3) "cuenta como una o cuatro ecuaciones? Y ... ¿cuáles son todas las ecuaciones de "0000"? Pienso en unas 100 posibilidades, o incluso más ... ¿Podría ser esto?
bobbel
2
¿Existe alguna restricción en el uso de operadores unarios? En ausencia de tal restricción en las reglas, el factorial se puede aplicar repetidamente y, por lo tanto, una solución perfecta puede resultar imposible.
Michael Stern
1
Michael, esa es una gran observación. Entonces, por el bien del rompecabezas, creo que lo limitaré a un factorial por "dígito", si eso tiene sentido. Por lo tanto, 5! es valido pero 5 !! no es válido.
nobillygreen

Respuestas:

1

Python3, 363 caracteres

Como no se da respuesta hasta hoy, entrego lo que obtuve. Lamentablemente, el bloque try / except es demasiado gordo, no encontré una manera de guardar caracteres allí. Es realmente complicado con los bucles anidados allí, creo que no todo se puede hacer con las comprensiones de listas, pero tal vez alguien pueda decirme cómo.

Sin embargo, restringí el desafío a mí mismo para usar solo las matemáticas básicas '+ - * /' y sin paréntesis.

a,b = input().split()
r=0
for time in [c for c in range(int(a),int(b)) if c/10%10<6]:
 t,*ts='%04d'%time
 e=[t]
 for d in ts:
  e=[(n+o+d,n+d)[o==' '] for o in ' -+*/=' for n in e]
 for h in [g for g in [e.split('=') for e in e if '='in e] if len(g)>1]:
  for k in h:
   try:
    if eval(h[0]) != eval(k):
     break
   except:
    break
  else:
   r+=1
print(r)

Mi código completo (espero algo explicativo) en este CodeGolf se puede encontrar en mi pastebin .

Oliver Friedrich
fuente