Trova le operazioni necessarie per ottenere il risultato


10

Quindi l'attività è semplice, dato l'array di numeri e il risultato, è necessario trovare quali operazioni è necessario utilizzare sui numeri dell'array per ottenere il risultato richiesto.

Semplifichiamo l'avvio e consentiamo solo operazioni di base come: addizione, sottrazione, moltiplicazione e divisione.

Esempio:

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

Per dare un vantaggio a linguaggi come Java, la richiesta è quella di implementare la funzione, non l'intero programma, e il risultato può essere restituito tramite parametro o stampare sulla console.

Il codice viene assegnato in base alla quantità di byte e, poiché si tratta della sfida del codice golf, vince il punteggio più basso.

Un altro requisito è È possibile ottenere ulteriori -10 punti se per l'array sono presenti solo numeri, supportare soluzioni in cui è possibile costruire numeri a partire dalle cifre seguenti. ie

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

Si noti che, a condizione che gli output vengano proposti, alcuni casi potrebbero avere più di una soluzione. Sta a te fornire una o più soluzioni per un determinato compito.

EDIT: il risultato deve essere valido dal punto di vista matematico, quindi la divisione è divisione razionale, non intera, e la precedenza dell'operazione è la stessa della matematica classica (prima moltiplicazione e divisione poi addizione e sottrazione).


4
Fa *e /hanno la precedenza sugli +e -? I tuoi due esempi si contraddicono a vicenda.
Leaky Nun,

1
Per favore, in futuro, assicurati di creare taglie basate su percentuale, per una lingua, come java, -10 byte non è buono come per la gelatina
Bálint


4
I numeri devono essere usati in ordine? Inoltre, per le sfide future, consiglio vivamente di utilizzare Sandbox in cui è possibile risolvere questo tipo di problemi prima di pubblicare su Main.
AdmBorkBork,

2
@ mbomb007 non è un duplicato di nessuno dei due. Questi sono input numerici arbitrari e sono consentite solo operazioni matematiche di base, non si suppone che producano programmi reali.
Patrick Roberts,

Risposte:



4

Oracle SQL 11.2, 322 304 270 byte

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 è l'elenco delle cifre
: 2 è il risultato cercato

Non golfato:

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

4

TSQL (sqlserver 2016) 310 294 280 byte

Che meravigliosa opportunità di scrivere brutti codici:

golfed:

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)

Provalo online

Leggibile: (l'inserimento del punto decimale (.) E la rimozione dello stesso sono necessari per consentire a sql di accettare che 4/5 non sia 0 - anche la rimozione è per le persone che lo testano)

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)

Questa soluzione può anche gestire questi tipi di input:

Ingresso: [1,2,3,4,5] 0 Uscita: 12-3-4-5


3

JavaScript (ES6), 165 147 byte

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`))

Annidato eval... adorabile.

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))


3

Python 3, 170 155 byte

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})

Crea un generatore con tutti i possibili ordini degli operatori, combinalo con i numeri, quindi valuta fino ad ottenere la risposta.

https://repl.it/C2F5


2
È possibile salvare alcuni caratteri sostituendoli ['+','-','*','/']con '+-*/'; poiché strings sono iterabili, lo tratterà come un arraycon ogni elemento che è ogni personaggio nel string- quindi si comporterà proprio come hai fornito l'array che hai attualmente.
nasonfish,

2

Python, 195 186 byte

Ecco un modo atroce per farlo.

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=""

La funzione xaccetta un argomento di a liste a result- x([1,2,3,4,5], 15)per esempio.

Il programma inizia un ciclo in cui iniziamo a selezionare casualmente se aggiungere "+", "-", "*", or "/"tra ciascun numero o se dovremmo concatenarli insieme. Sembrava un'opzione più concisa rispetto al passare attraverso le permutazioni e provare ogni combinazione per trovare tutti i risultati, anche se richiede più tempo per essere eseguita ed è molto meno efficiente. (Fortunatamente non è un problema in questo contesto!)

Aggiunge anche "." a ciascun numero per evitare di eseguire operazioni arrotondate per intero come 6/4 = 1. Quindi evalè la nostra espressione e determina se il risultato è uguale a quello che ci aspettiamo e, in tal caso, genera l'espressione.

Questo programma non esce mai - continuerà a produrre continuamente risultati fino alla sua morte.

MODIFICA 1 : rimuove le righe non necessarie in cui è ifpossibile utilizzare istruzioni a riga singola .


implementazione davvero divertente. ma è facile salvare qualche altro byte Provalo online! (176 byte)
bobrobbob,

2

Matlab, 234 238 258 byte

Sto assumendo in base ai limiti delle altre risposte che l'ordine numerico dell'array di input è gestito da Fiat.

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,[])'

Questo codice prende una stringa di numeri x, dire x = '12345'e di conseguenza r, dire r = 15e restituisce tutte le stringhe di espressioni si può valutare per ottenere rda xutilizzando i quattro operatori.

Ho usato due modi diversi equivalenti di lunghezza per evitare l'uso di espressioni ones(length())-type o repmat(length())-type: ~~p(1,:)che restituisce valori non-not in p(cioè, un elenco di 1s la samelength come prima dimensione di p) e 0|p(:,1)che restituisce 0 o is-there -a-value-in p(ovvero un elenco di 1s della stessa lunghezza della seconda dimensione di p).

Matlab non ha un metodo nchoosek con sostituzione , quindi ho duplicato gli operatori il numero corretto di volte, ho calcolato l'intero spazio nchoosekper quella più ampia selezione di operatori e quindi ho usato una uniquechiamata per abbinare il risultato a quello che dovrebbe essere (rimuovendo combinazioni equivalenti come '*** +' e '*** +'). Aggiungo uno spazio finale per abbinare la lunghezza del vettore di input ai fini della concatenazione e quindi compongo le stringhe dell'operatore con le stringhe di input nelle colonne di una matrice. Quindi valuto le espressioni a colonne per ottenere risultati e trovare l'ordine degli operatori che corrispondono a quelle colonne con risultati che corrispondono al nostro input r.

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

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

Se dovessi prendere una matrice di valori di doppia precisione, avrei bisogno x = num2str(x,'%d');per convertire le cifre in una stringa, aggiungendo 21 (20 senza il ;) al mio punteggio. * I byte extra erano punti e virgola che ho lasciato solo in modo che chiunque esegua questo codice non vedrà il loro prompt dei comandi esplodere con lunghe matrici. Dato che la mia modifica produce comunque una gigantesca pila di avvertimenti su logici e operandi di due punti, ho rimosso i punti e virgola nella nuova versione.

Modifica 2: dimenticato di sostituire un 2*n+2con k.

Vecchia risposta:

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,[])'

2

JavaScript (ES6), 88 byte

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

Ha aggiunto un po 'di casualità al mix. Molto più facile che ripetere sistematicamente le combinazioni.

Test Suite

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))


1

PHP, 108 byte

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

accetta l'input dagli argomenti della riga di comando in ordine inverso. Corri con -r.

abbattersi

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.