Encontre as operações necessárias para obter resultado

10

Portanto, a tarefa é simples, considerando a matriz de números e o resultado, você precisa encontrar quais operações você precisa usar nos números da matriz para obter o resultado solicitado.

Vamos simplificar o início e permitir apenas operações básicas como: adição, subtração, multiplicação e divisão.

Exemplo:

Input  : [5,5,5,5,5] 100
Output : 5*5*5-5*5

Para dar alguma vantagem a linguagens como Java, solicitar é implementar a função, não o programa inteiro, e o resultado pode ser retornado via parâmetro ou impresso no console.

O código é pontuado com base na quantidade de bytes e, como é um desafio ao código de golfe, a pontuação mais baixa vence.

Outro requisito é que você pode obter -10 pontos adicionais se o array contiver apenas digids, oferecer suporte a soluções nas quais você pode construir números a partir dos dígitos seguintes. Ou seja,

Input  : [1,2,3,4,5] 0
Output : 12-3-4-5

Observe que, desde que as saídas sejam propostas, alguns casos podem ter mais de uma solução. Depende de você fornecer uma ou mais soluções para determinada tarefa.

EDIT: O resultado deve ser válido do ponto de vista matemático, portanto, a divisão é uma divisão racional, não um número inteiro, e a precedência da operação é a mesma da matemática clássica (primeira multiplicação e divisão, depois adição e subtração).

user902383
fonte
4
Tem *e /tem precedência sobre +e -? Seus dois exemplos se contradizem.
Leaky Nun
11
Por favor, no futuro, certifique-se de criar recompensas baseadas em percentuais, para uma linguagem, como java, -10 bytes não é tão bom quanto para a geléia
Bálint
7
Ou até mesmo evitar bônus por completo
Luis Mendo
4
Os números precisam ser usados ​​em ordem? Além disso, para desafios futuros, recomendo vivamente o uso da Sandbox, onde esses tipos de problemas podem ser resolvidos antes de serem postados no Main.
AdmBorkBork
2
@ mbomb007 não é uma duplicata de nenhuma delas. Essas são entradas numéricas arbitrárias, e somente operações matemáticas básicas são permitidas, elas não devem produzir programas reais.
Patrick Roberts

Respostas:

4

Oracle SQL 11.2, 322 304 270 bytes

SELECT o FROM(SELECT REPLACE(SUBSTR(:1,1,1)||REPLACE(SYS_CONNECT_BY_PATH(a||SUBSTR(:1,LEVEL*2+1,1),','),','),'_')o,LEVEL l FROM(SELECT SUBSTR('+-*/_',LEVEL,1)a FROM DUAL CONNECT BY LEVEL<6)CONNECT BY LEVEL<LENGTH(:1)/2)WHERE:2=dbms_aw.eval_number(o)AND l>LENGTH(:1)/2-1;

: 1 é a lista de dígitos
: 2 é o resultado pesquisado

Sem golfe:

SELECT o
FROM   (
         SELECT REPLACE(SUBSTR(:1,1,1)||REPLACE(SYS_CONNECT_BY_PATH(a||SUBSTR(:1,LEVEL*2+1,1),','),','),'_')o,LEVEL l 
         FROM ( -- Create one row per operator 
                SELECT SUBSTR('+-*/_',LEVEL,1)a FROM DUAL CONNECT BY LEVEL<6
              ) CONNECT BY LEVEL<LENGTH(:1)/2  -- Create every combination of operators, one per ','
)
WHERE :2=dbms_aw.eval_number(o)  -- filter on result = evaluation
  AND l>LENGTH(:1)/2-1           -- keep only expressions using every digits
Jeto
fonte
4

TSQL (sqlserver 2016) 310 294 280 bytes

Que oportunidade maravilhosa de escrever código feio:

Golfe:

DECLARE @ varchar(max)= '5,5,5'
DECLARE @a varchar(20) = '125'

,@ varchar(max)='';WITH D as(SELECT @a a UNION ALL SELECT STUFF(a,charindex(',',a),1,value)FROM STRING_SPLIT('*,+,./,-,',',')x,d WHERE a like'%,%')SELECT @+=a+','''+REPLACE(a,'.','')+'''),('FROM D WHERE a not like'%,%'EXEC('SELECT y FROM(values('+@+'null,null))g(x,y)WHERE x='+@b)

Experimente online

Legível: (inserção de ponto decimal (.) E remoção do mesmo é necessário para que o sql aceite que 4/5 não é 0 - a remoção do poço é para as pessoas que o testam)

DECLARE @a varchar(max)= '5,5,5'
DECLARE @b varchar(20) = '5'

,@ varchar(max)=''
;WITH D as
(
  SELECT @a a
  UNION ALL
  SELECT STUFF(a,charindex(',',a),1,value)
  FROM STRING_SPLIT('*,+,./,-,',',')x,d
  WHERE a like'%,%'
)
SELECT @+=a+','''+REPLACE(a,',','')+'''),('
FROM D
WHERE a not like'%,%'

EXEC('SELECT y FROM(values('+@+'null,null))g(x,y)WHERE x='+@b)

Esta solução também pode lidar com estes tipos de entrada:

Entrada: [1,2,3,4,5] 0 Saída: 12-3-4-5

t-clausen.dk
fonte
3

JavaScript (ES6), 165 147 bytes

a=>o=>(c=[],i=c=>{for(j=0;!((c[j]?++c[j]:c[j]=1)%5);)c[j++]=0},eval(`while(eval(e=(a+'').replace(/,/g,(_,j)=>'+-*/'.charAt(c[~-j/2])))!=o)i(c);e`))

Aninhado eval... adorável.

f=a=>o=>(c=[],i=c=>{for(j=0;!((c[j]?++c[j]:c[j]=1)%5);)c[j++]=0},eval(`while(eval(e=(a+'').replace(/,/g,(_,j)=>'+-*/'.charAt(c[~-j/2])))!=o)i(c);e`))
console.log(f([5,5,5,5,5])(100))
console.log(f([1,2,3,4,5])(0))
console.log(f([3,4])(0.75))
console.log(f([3,4,5,6])(339))

Patrick Roberts
fonte
3

Python 3, 170 155 bytes

from itertools import*
def f(n,o):print({k for k in[''.join(map(str,sum(j,())))[1:]for j in[zip(x,n)for x in product('+-*/',repeat=len(n))]]if eval(k)==o})

Crie um gerador com todos os pedidos possíveis dos operadores, combine isso com os números e avalie até obtermos a resposta.

https://repl.it/C2F5

atlasologist
fonte
2
Você pode salvar alguns caracteres substituindo ['+','-','*','/']por '+-*/'; como strings são iteráveis, ele o tratará como um arraycom cada elemento sendo cada caractere no string- portanto, ele funcionará exatamente como você forneceu a matriz que você possui atualmente.
nasonfish
2

Python, 195 186 bytes

Aqui está uma maneira atroz de fazer isso.

def x(i,r):
 t=""
 from random import choice as c
 while True:
  for j in i:
   t+=str(j)
   if c([0,1]):t+="."+c("+-/*")
  t=t.strip("+-*/.")+"."
  v=eval(t)
  if v == r:print t
  t=""

A função xaceita um argumento de a liste a result- x([1,2,3,4,5], 15)por exemplo.

O programa inicia um ciclo em que começamos a selecionar aleatoriamente se devemos acrescentar "+", "-", "*", or "/"entre cada número ou se devemos concatená-los juntos. Parecia uma opção mais concisa do que realmente passar por permutações e tentar todas as combinações para encontrar todos os resultados, e embora demore mais para ser executado e seja muito menos eficiente. (Felizmente, isso não é uma preocupação neste contexto!)

Também anexa "." para cada número para evitar operações com números inteiros como 6/4 = 1. Isso entãoeval a nossa expressão e determina se o resultado é igual ao que estamos esperando e, se sim, produz a expressão.

Este programa nunca sai - ele continuará produzindo resultados até ser morto.

EDIT 1 : Remova novas linhas desnecessárias, onde ifinstruções de uma linha podem ser usadas.

nasonfish
fonte
implementação realmente engraçada. mas fácil de economizar mais alguns bytes Experimente online! (176 bytes)
bobrobbob
2

Matlab, 234 238 258 bytes

Estou assumindo, com base nas limitações das outras respostas, que a ordem numérica da matriz de entrada é mantida por decreto.

n=length(x)-1
k=n*2+2
p=unique(nchoosek(repmat('*-+/',1,n),n),'rows')
p=[p char(' '*~~p(:,1))]'
c=char(x'*~~p(1,:))
o=p(:,r==cellfun(@eval,mat2cell(reshape([c(:) p(:)]',k,[]),k,0|p(1,:))))
reshape([repmat(x',size(o,2),1) o(:)]',k,[])'

Esse código pega uma sequência de números x, digamos, x = '12345'e um resultado r, diz r = 15e retorna todas as sequências de expressões que você pode avaliar para obter rao xusar os quatro operadores.

Eu usei duas maneiras diferentes de comprimento equivalente para evitar o uso de expressões -type ones(length())ou repmat(length())-type: ~~p(1,:)que retorna valores não-not em p(ou seja, uma lista de 1s o mesmo comprimento que a primeira dimensão de p) e 0|p(:,1)que retorna 0 ou está lá -a-value-in p(ou seja, uma lista de 1s do mesmo tamanho que a segunda dimensão de p).

O Matlab não possui um método de nchoosek substituição , por isso dupliquei os operadores o número correto de vezes, calculei todo o espaço nchoosekpara uma seleção maior de operadores e usei uma uniquechamada para comparar o resultado com o que deveria ser (removendo combinações equivalentes como '*** +' e '*** +'). Eu adiciono um espaço à direita para corresponder ao comprimento do vetor de entrada para fins de concatenação e, em seguida, componho as seqüências de caracteres do operador com as de entrada nas colunas de uma matriz. Em seguida, avalio as expressões em colunas para obter resultados e encontrar a ordem dos operadores que correspondem a essas colunas com resultados que correspondem à nossa entrada r.

Teste: x = '12345', r = 15:

1*2*3+4+5 
1+2+3+4+5 
1-2*3+4*5 

Se eu precisasse usar uma matriz de valores duplos de precisão, seria necessário x = num2str(x,'%d');converter os dígitos em uma sequência de caracteres, adicionando 21 (20 sem o ;) à minha pontuação. * Os bytes extras foram ponto-e-vírgula que eu deixei apenas para que qualquer pessoa executando esse código não veja seu prompt de comando explodir com longas matrizes. Como minha edição produz agora uma pilha gigante de avisos sobre lógicos e operandos de dois pontos, removi o ponto e vírgula na nova versão.

Editar 2: Esqueceu de substituir um 2*n+2com k.

Resposta antiga:

n=length(x)-1;
p=unique(nchoosek(repmat(['*','-','+','/'],1,n),n),'rows');
l=length(p);
p=[p repmat(' ',l,1)]';
c=reshape([repmat(x',l,1) p(:)]',n*2+2,[]);
o = p(:,r == cellfun(@eval, mat2cell(c,n*2+2,ones(l,1))));
reshape([repmat(x',size(o,2),1) o(:)]',n*2+2,[])'
sintax
fonte
2

JavaScript (ES6), 88 bytes

a=>o=>eval(`while(eval(e=(a+'').replace(/,/g,_=>'+-*/'.charAt(Math.random()*5)))!=o);e`)

Jogou um pouco de aleatoriedade para a mistura. Muito mais fácil do que iterar sistematicamente pelas combinações.

Suíte de teste

f=a=>o=>eval(`while(eval(e=(a+'').replace(/,/g,_=>'+-*/'.charAt(Math.random()*5)))!=o);e`)
console.log(f([5,5,5,5,5])(100))
console.log(f([1,2,3,4,5])(0))
console.log(f([3,4])(0.75))
console.log(f([3,4,5,6])(339))

Patrick Roberts
fonte
1

PHP, 108 bytes

for(;$i=$argc;eval("$s-$argv[1]?:die(\$s);"))for($s="",$x=$p++;--$i>1;$x/=4)$s.="+-*/"[$s?$x&3:4].$argv[$i];

recebe entrada dos argumentos da linha de comando na ordem inversa. Corra com -r.

demolir

for(;                   # infinite loop:
    $i=$argc;               # 1. init $i to argument count
    eval("$s-$argv[1]?:"    # 3. if first argument equals expression value,
        ."die(\$s);")       #    print expression and exit
    )
    for($s="",              # 2. create expression:
        $x=$p++;            #    init map
        --$i>1;                 # loop from last to second argument
        $x/=4)                  # C: shift map by two bits
        $s.="+-*/"[$s?$x&3:4]   # A: append operator (none for first operand)
            .$argv[$i];         # B: append operand
Titus
fonte
1

Perl 5 com -pa, 46 bytes

$"="{,\\*,/,+,-}";$x=<>;($_)=grep$x==eval,<@F>

Experimente online!

Dom Hastings
fonte