Znajdź operacje wymagane do uzyskania wyniku

10

Zadanie jest więc proste, biorąc pod uwagę tablicę liczb i wyników, musisz znaleźć operacje, których należy użyć na liczbach z tablicy, aby uzyskać żądany wynik.

Uprośćmy to na początek i zezwalajmy tylko na podstawowe operacje, takie jak: dodawanie, odejmowanie, mnożenie i dzielenie.

Przykład:

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

Aby dać przewagę takim językom jak Java, żądanie polega na implementacji funkcji, a nie całego programu, a wynik może zostać zwrócony poprzez parametr lub wydruk na konsolę.

Kod jest oceniany na podstawie ilości bajtów, a ponieważ jest wyzwaniem dla kodu golfowego, wygrywa najniższy wynik.

Kolejnym wymaganiem jest to, że można uzyskać dodatkowe -10 punktów, jeśli tablica zawiera tylko cyfry, obsługuje rozwiązania, w których można konstruować liczby na podstawie kolejnych cyfr. To znaczy

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

Należy pamiętać, że pod warunkiem, że wyniki są proponowanymi wynikami, niektóre przypadki mogą mieć więcej niż jedno rozwiązanie. Od Ciebie zależy, czy dostarczysz jedno lub więcej rozwiązań dla danego zadania.

EDYCJA: Wynik musi być poprawny z matematycznego punktu widzenia, stąd podział jest podziałem racjonalnym, a nie liczbą całkowitą, a pierwszeństwo operacji jest takie samo jak w matematyce klasycznej (najpierw mnożenie i dzielenie, a następnie dodawanie i odejmowanie).

użytkownik902383
źródło
4
Czy *i /ma pierwszeństwo przed +i -? Dwa przykłady są ze sobą sprzeczne.
Leaky Nun
1
W przyszłości upewnij się, że tworzysz nagrody procentowe, dla języka takiego jak Java, 10 bajtów nie jest tak dobre jak dla galaretki
Bálint
7
Lub nawet całkowicie unikaj bonusów
Luis Mendo
4
Czy liczby muszą być używane po kolei? Ponadto w przypadku przyszłych wyzwań gorąco polecam korzystanie z piaskownicy, w której tego rodzaju problemy można rozwiązać przed wysłaniem do Main.
AdmBorkBork
2
@ mbomb007 nie jest to duplikat żadnego z nich. Są to dowolne dane liczbowe i dozwolone są tylko podstawowe operacje matematyczne, nie powinny one generować rzeczywistych programów.
Patrick Roberts,

Odpowiedzi:

4

Oracle SQL 11.2, 322 304 270 bajtów

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 to lista cyfr
: 2 to szukany wynik

Bez golfa:

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
źródło
4

TSQL (sqlserver 2016) 310 294 280 bajtów

Cóż za wspaniała okazja do napisania brzydkiego kodu:

Gra w golfa:

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)

Wypróbuj online

Czytelny: (wstawienie przecinka dziesiętnego (.) I usunięcie go jest konieczne, aby SQL mógł zaakceptować, że 4/5 nie jest równe 0 - usunięcie studni jest dla osób testujących)

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)

To rozwiązanie może również obsługiwać następujące typy danych wejściowych:

Wejście: [1,2,3,4,5] 0 Wyjście: 12-3-4-5

t-clausen.dk
źródło
3

JavaScript (ES6), 165 147 bajtów

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

Zagnieżdżone eval... cudownie.

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
źródło
3

Python 3, 170 155 bajtów

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

Utwórz generator ze wszystkimi możliwymi zamówieniami operatorów, połącz to z liczbami, a następnie ewaluuj, aż otrzymamy odpowiedź.

https://repl.it/C2F5

atlasolog
źródło
2
Można zaoszczędzić kilka znaków zastępując ['+','-','*','/']z '+-*/'; ponieważ strings są iterowalne, potraktuje to tak, jakby arraykażdy element był każdą postacią w string- więc będzie działał tak, jakbyś dostarczył go z tablicą, którą aktualnie masz.
nasonfish
2

Python, 195 186 bajtów

Oto okropny sposób na zrobienie tego.

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

Funkcja xprzyjmuje na przykład argument listai a result- x([1,2,3,4,5], 15).

Program rozpoczyna pętlę, w której zaczynamy losowo wybierać, czy należy dołączyć "+", "-", "*", or "/"między każdą liczbą, czy też połączyć je razem. Wydawało się to bardziej zwięzłą opcją niż faktyczne przechodzenie przez permutacje i wypróbowywanie każdej kombinacji w celu znalezienia każdego wyniku, i chociaż trwa dłużej i jest znacznie mniej wydajne. (Na szczęście nie jest to problemem w tym kontekście!)

Dołącza także „.” do każdej liczby, aby uniknąć wykonywania operacji zaokrąglonych do liczb całkowitych, takich jak 6/4 = 1. Następnie evaljest naszym wyrażeniem i określa, czy wynik jest równy oczekiwanemu, a jeśli tak, generuje wyrażenie.

Ten program nigdy nie wychodzi - będzie nieprzerwanie wyświetlał wyniki aż do zabicia.

EDYCJA 1 : Usuń niepotrzebne znaki nowej linii, w których ifmożna użyć instrukcji jednowierszowych.

nasonfish
źródło
naprawdę zabawne wdrożenie. ale łatwo zapisać więcej bajtów Wypróbuj online! (176 bajtów)
bobrobbob
2

Matlab, 234 238 258 bajty

Zakładam, w oparciu o ograniczenia innych odpowiedzi, że porządek liczb w tablicy wejściowej jest utrzymywany przez 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,[])'

Ten kod pobiera ciąg liczb x, powiedzmy x = '12345', a wynik r, powiedzmy r = 15i powroty wszystkich ciągów wyrażeń można ocenić uzyskać rz xpomocą czterech operatorów.

Użyłem dwóch różnych równoważnych długości sposobów unikania używania wyrażeń ones(length())-type lub repmat(length())-type: ~~p(1,:)które zwracają wartości nie-nie w p(tj. Listę 1s długości dla pierwszego wymiaru p) i 0|p(:,1)która zwraca 0 lub jest tam -a-wartość-w p(tj. lista 1s tej samej długości co drugi wymiar p).

Matlab nie ma metody nchoosek zastępczej , więc zduplikowałem operatory poprawną liczbę razy, obliczyłem całą przestrzeń nchoosekdla tego większego wyboru operatorów, a następnie użyłem uniquewywołania, aby zmniejszyć wynik do tego, co powinno być (usuwanie równoważnych kombinacji, takich jak „*** +” i „*** +”). Dodaję spację końcową, aby dopasować długość wektora wejściowego do celów konkatenacji, a następnie układam ciągi operatora z ciągami wejściowymi w kolumnach macierzy. Następnie oceniam wyrażenia według kolumn, aby uzyskać wyniki i znaleźć kolejność operatorów, która odpowiada tym kolumnom, z wynikami zgodnymi z naszymi danymi wejściowymi r.

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

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

Gdybym musiał wziąć tablicę wartości podwójnej precyzji, musiałbym x = num2str(x,'%d');przekonwertować cyfry na ciąg, dodając 21 (20 bez tego ;) do mojego wyniku. * Dodatkowymi bajtami były średniki, które pozostawiłem w czystej postaci, aby każdy, kto uruchomił ten kod, nie zobaczył, że jego wiersz polecenia wysadza długie tablice. Ponieważ moja edycja generuje teraz ogromną stertę ostrzeżeń o logice i operandzie na dwukropku, usunąłem średniki w nowej wersji.

Edit 2: Zapomniałem wymienić 2*n+2z k.

Stara odpowiedź:

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
źródło
2

JavaScript (ES6), 88 bajtów

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

Wrzucił trochę losowości do miksu. Znacznie łatwiejsze niż systematyczne powtarzanie kombinacji.

Pakiet testowy

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
źródło
1

PHP, 108 bajtów

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

pobiera dane wejściowe z argumentów wiersza poleceń w odwrotnej kolejności. Biegnij z-r .

awaria

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
Tytus
źródło
1

Perl 5 z -pa, 46 bajtów

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

Wypróbuj online!

Dom Hastings
źródło