Não é apenas um quebra-cabeça de quatro quatros

11

Nesta variante do quebra-cabeça de quatro quatros, você deve usar até x x's(e nenhum outro número) e um conjunto definido de operações para atingir todos os números de 0 a 100. Se x = 4você pode usar até quatro 4se essa pergunta se torna o clássico quatros quebra-cabeça (exceto que você pode usar até quatro 4s em vez de precisar usar exatamente quatro deles). Nós assumimos 1 < x <= 9.

Nesta versão, apenas os seguintes operadores são permitidos:

  • Adição ( +), Subtração ( -), Multiplicação ( *), Divisão ( /). Note que esta é uma divisão real, de modo que 5/2 = 2.5.
  • Exponenciação (por exemplo, 4 ^ 4), pois isso não envolveria símbolos extras se escrito normalmente à mão.
  • Você pode criar novos números inteiros concatenando xs. Por exemplo, você pode fazer os números inteiros 4, 44, 444, 4444.

Você também pode usar parênteses para agrupar números simplesmente para controlar a ordem de avaliação dos operadores. Você não pode, por exemplo, combinar parênteses com concatenação como em (4/4)(4/4) = (1)(1) = 11.

Nenhum outro símbolo pode ser usado e a ordem padrão de operações se aplica.

Seu programa deve gerar, considerando um xintervalo definido e um nentre 0e 100inclusive, uma solução correta para essa entrada, se existir. Caso contrário, seu código deve gerar algo para indicar que não existe essa solução.

Você deve poder executar seu envio até a conclusão em sua máquina para quaisquer valores de entrada xe ndentro do intervalo permitido. Isso é código de golfe, então a solução mais curta vence.

Essa antiga pergunta relacionada usa mais operadores (e apenas 4s) e, portanto, todos os números de 0 a 100 são solucionáveis, o que não será verdadeiro para esse desafio.

Entrada e saída

Seu código usa dois números inteiros xe ncomo entrada e deve gerar uma solução (ou uma indicação de que não há solução) em qualquer formato legível por humanos que você achar conveniente. A entrada 4 6significaria "Usando até quatro 4s, faça o número 6", por exemplo. Então, se a entrada é 4 6a saída poderia ser (4+4)/4+4.

Anush
fonte
1
Referência útil
Engineer Toast
2
Parens podem ser combinados com concatenação? por exemplo, `(4/4) (4/4) = (1) (1) = 11?
Digital Trauma
1
Adicionando parênteses (e não permitindo parênteses + concatenação) faz este significativamente mais difícil
Draconis
2
Adicionando o operador de exponenciação e um loop externo sobre o número de vezes que o dígito é usado, o IMO não adiciona nada não-trivial ao codegolf.stackexchange.com/q/82884/194 #
Peter Taylor
2
@ PeterTaylor Os parênteses parecem fazer muita diferença. Eu votaria para reabrir se pudesse.
Felipa #

Respostas:

4

Python 3 , 265 bytes

def f(x,n):
 for e in g(x,x-(x>7)):
  try:
   if eval(e)==n:return e
  except:1
g=lambda x,d:{str(x)*-~i for i in range(d)}|{s%(a,b)for a in g(x,d-1)for b in g(x,d-a.count(str(x)))for s in'%s**%s (%s/%s) (%s+%s) (%s-%s) %s*%s %s/%s'.split()['**'in a+b:]}if d else{}

Experimente online!

Funciona para todos os números na referência vinculada pelo Engineer Toast.

Funciona x=8, x=9demora alguns minutos na minha máquina.


A função gretorna um conjunto de todas as combinações com no máximo xnúmero de x's. fdepois percorre-os e retorna o primeiro que é avaliado como o número n.

O número de valores possíveis que encontrei para cada um deles xsão:

x  possible numbers
------
2  5
3  17
4  35
5  56
6  83
7  101
8  101
9  101

Todos os números acima pode ser gerado a partir de (a+b), (a-b), (a+b), a*b, a/b, (a/b), e a^b. a+be a-bnão dê mais números.

a^b também é usado apenas uma vez, caso contrário, grandes números são criados (isso também é verificado no documento de referência acima)


Uma versão alternativa que causa um curto-circuito assim que encontra uma solução (não como golfe):

Isso é muito mais rápido, pois x=7..9todos os números podem ser criados.

Python 3 , 338 289 bytes

def f(x,n,d=-1):
 d=[d,x][d<0];X=str(x);r=set()
 for E in{X*-~i for i in range(d)}|{s%(a,b)for a in[0]*d and f(x,n,d-1)for b in f(x,n,d-a.count(X))for s in'%s**%s (%s/%s) (%s+%s) (%s-%s) %s*%s %s/%s'.split()['**'in a+b:]}:
  try:e=eval(E)
  except:e=-1
  if e==n:exit(E)
  r|={E}
 return r

Experimente online!

TFeld
fonte
Esta é uma resposta muito boa! Eu pensei que você estava sempre usando exatamente (ao contrário de) x xs (por exemplo, (4/4**(4-4))para 4), mas acontece que não é o caso.
Anush
exit(e)é menor quereturn e
mbomb007 16/05