Aritmética… tique… tique… tique

15

Esta pergunta foi trazida a você por um jogo que eu gosto de jogar quando fica preso em longas reuniões telefônicas.

Dadas duas vezes a partir de um relógio de 24 horas (das 00:00 às 23:59), quantas equações matemáticas válidas podem ser geradas com todos os tempos intermediários usando apenas operações aritméticas básicas?

Entrada: duas cadeias de quatro dígitos (sem dois pontos) representando tempos válidos em um ciclo de 24 horas.

Exemplos:

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.

As operações válidas são:

  • Adição
  • subtração
  • multiplicação
  • divisão (ponto flutuante)
  • exponenciação
  • fatorial

Outros símbolos permitidos

  • Parênteses
  • Sinais de igual

O menor código vence.

Notas

  • O objetivo é encontrar o número de expressões válidas entre duas vezes, não o número de vezes que contém uma expressão válida.
  • Os dois tempos dados como entrada estão incluídos no intervalo de tempos.
  • Você pode agrupar os dígitos de qualquer maneira possível, para que "1223" possa ser "12 23" ou "1 2 23" ou "1 223" etc. etc.
  • Você pode usar quantos parênteses forem necessários.
  • Você pode usar mais de um =sinal. Por exemplo, o tempo 11:11tem a expressão válida1=1=1=1 .
  • Se a primeira vez ocorrer cronologicamente após a segunda, o intervalo de tempos deve ser encerrado como se estivesse cruzando para o dia seguinte.
  • Os números devem permanecer na ordem original - você não pode reordenar os dígitos.
  • Ao agrupar números, o zero pode ser absolutamente o dígito mais à frente; nesse caso, eles são ignorados ("0303" agrupado como "03 03" tem apenas dois dígitos com o valor 3.)
  • Você NÃO PODE usar o sinal de menos como negação unária. Portanto, "12:01" NÃO produz "1-2 = - (01)", mas produz "1-2 = 0-1".
  • Você NÃO pode adicionar pontos decimais aos dígitos. Portanto, "12:05" NÃO produz "1/2 = 0,5".
  • Nenhum encadeamento de fatoriais - um dígito pode ser seguido por no máximo um "!", Não mais, caso contrário, muitas vezes teriam soluções infinitas. Ex: "5!" é válido, mas "5 !!" não é válido.
nobillygreen
fonte
4
" Operações válidas incluem " parece impedir que você possa adicionar casos de teste. Seria uma pergunta melhor se você mudasse para " Operações válidas " e incluiu alguns casos de teste. Também seria útil ser preciso sobre os pontos de extremidade: para entrada 0000 1300, as equações devem ser derivadas 0000e 1300incluídas na contagem?
Peter Taylor
1
Dados os dígitos "1423", faça "1 + 4 = 2 + 3", "(1 + 4) = (2 + 3)", "(1 + 4) = 2 + 3" e "1 + 4 = (2 +3) "conta como uma ou quatro equações? E ... quais são todas as equações de "0000"? Penso em cerca de 100 possibilidades, ou até mais ... Poderia ser isso?
bobbel
2
Existe alguma restrição ao uso de operadores unários? Na ausência de tal restrição nas regras, o fatorial pode ser aplicado repetidamente e, portanto, uma solução perfeita pode ser impossível.
Michael Stern
1
Michael, é uma ótima observação. Então, pelo bem do quebra-cabeça, acho que vou limitá-lo a um fatorial por "dígito", se isso fizer sentido. Portanto, 5! é válido mas 5 !! não é válido.
Nobillygreen

Respostas:

1

Python3, 363 caracteres

Como nenhuma resposta é dada até hoje, eu entrego o que recebi. Infelizmente, o bloco try / except é muito gordo, não encontrei uma maneira de salvar caracteres lá. É realmente complicado com os loops aninhados, nem tudo pode ser feito com a compreensão da lista, mas talvez alguém possa me dizer como.

No entanto, eu me restringi ao desafio de usar apenas matemática básica '+ - * /' e sem parênteses.

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)

Meu código completo (espero que seja explicativo) neste CodeGolf pode ser encontrado no meu pastebin .

Oliver Friedrich
fonte