Trouvez les opérations nécessaires pour obtenir le résultat

10

La tâche est donc simple, étant donné le tableau de nombres et le résultat, vous devez trouver les opérations que vous devez utiliser sur les nombres du tableau, pour obtenir le résultat demandé.

Rendons-le simple pour le démarrage et n'autorisons que les opérations de base telles que: addition, soustraction, multiplication et division.

Exemple:

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

Pour donner un certain avantage à des langages comme Java, la demande consiste à implémenter la fonction, pas le programme entier, et le résultat peut être renvoyé via un paramètre ou imprimé sur la console.

Le code est noté en fonction du nombre d'octets, et comme c'est un défi de code de golf, le score le plus bas gagne.

Une autre exigence est que vous pouvez obtenir -10 points supplémentaires si le tableau ne contient que des chiffres, des solutions de support où vous pourriez construire des nombres à partir des chiffres suivants. C'est à dire

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

Notez que, à condition que les extrants soient des extrants proposés, certains cas peuvent avoir plusieurs solutions. C'est à vous de proposer une ou plusieurs solutions pour une tâche donnée.

EDIT: Le résultat doit être valide du point de vue mathématique, donc la division est une division rationnelle, pas un entier, et la priorité de l'opération est la même qu'en mathématiques classiques (d'abord multiplication et division puis addition et soustraction).

user902383
la source
4
Est *- ce et a- t- il la /préséance sur +et -? Vos deux exemples se contredisent.
Leaky Nun
1
Veuillez, à l'avenir, vous assurer de créer des primes basées sur un pourcentage, pour une langue, comme java, -10 octets n'est pas aussi bon que pour la gelée
Bálint
7
Ou même éviter complètement les bonus
Luis Mendo
4
Les numéros doivent-ils être utilisés dans l'ordre? De plus, pour les défis à venir, je recommande vivement d'utiliser le Sandbox où ces types de problèmes peuvent être résolus avant d'être publiés sur Main.
AdmBorkBork
2
@ mbomb007 ce n'est pas un double de ceux-là. Ce sont des entrées numériques arbitraires, et seules les opérations mathématiques de base sont autorisées, elles ne sont pas censées produire des programmes réels.
Patrick Roberts

Réponses:

4

Oracle SQL 11.2, 322 304 270 octets

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 est la liste des chiffres
: 2 est le résultat recherché

Non golfé:

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
la source
4

TSQL (sqlserver 2016) 310 294 280 octets

Quelle merveilleuse occasion d'écrire du code laid:

Golfé:

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)

Essayez-le en ligne

Lisible: (l'insertion du point décimal (.) Et sa suppression sont nécessaires pour que sql accepte que 4/5 n'est pas 0 - la suppression est pour les personnes qui la testent)

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)

Cette solution peut également gérer ces types d'entrée:

Entrée: [1,2,3,4,5] 0 Sortie: 12-3-4-5

t-clausen.dk
la source
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`))

Imbriqué eval... charmant.

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

Créez un générateur avec toutes les commandes possibles des opérateurs, combinez cela avec les nombres, puis évaluez jusqu'à ce que nous obtenions la réponse.

https://repl.it/C2F5

atlasologue
la source
2
Vous pouvez enregistrer quelques caractères en les remplaçant ['+','-','*','/']par '+-*/'; puisque strings sont itératives, elle sera traitée comme un arraychaque élément étant chaque caractère dans le string- il agira comme vous l' avez fourni avec le tableau que vous avez actuellement.
nasonfish
2

Python, 195 186 octets

Voici une façon atroce de le faire.

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 fonction xaccepte un argument de a listet a result- x([1,2,3,4,5], 15)par exemple.

Le programme commence une boucle où nous commençons à sélectionner au hasard si nous devons ajouter "+", "-", "*", or "/"entre chaque nombre, ou si nous devons les concaténer ensemble. Cela semblait être une option plus concise que de passer par des permutations et d'essayer chaque combinaison pour trouver chaque résultat, et bien que cela prenne plus de temps et soit beaucoup moins efficace. (Heureusement, ce n'est pas un problème dans ce contexte!)

Il ajoute également "." à chaque nombre pour éviter de faire des opérations arrondies entières comme 6/4 = 1. Il evals ensuite notre expression et détermine si le résultat est égal à ce que nous attendons, et si oui, sort l'expression.

Ce programme ne se termine jamais - il continuera à produire des résultats en continu jusqu'à sa mort.

EDIT 1 : Supprimez les sauts de ligne inutiles où les ifinstructions d' une ligne peuvent être utilisées.

nasonfish
la source
mise en œuvre vraiment drôle. mais facile d'économiser quelques octets supplémentaires Essayez-le en ligne! (176 octets)
bobrobbob
2

Matlab, 234 238 258 octets

Je suppose sur la base des limitations des autres réponses que l'ordre numérique du tableau d'entrée est maintenu par 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,[])'

Ce code prend une chaîne de nombres x, par exemple x = '12345'et un résultat r, disons r = 15et retourne toutes les chaînes d'expressions vous pouvez évaluer pour obtenir rde l' xaide des quatre opérateurs.

J'ai utilisé deux façons différentes, équivalentes en longueur, d'éviter d'utiliser des expressions ones(length())-type ou repmat(length())-type: ~~p(1,:)qui renvoie des valeurs not-not dans p(c'est- à -dire une liste de 1s la même longueur comme première dimension de p) et 0|p(:,1)qui renvoie 0 ou is-there -a-value-in p(c'est -à- dire une liste de 1s de même longueur que la deuxième dimension de p).

Matlab n'a pas nchoosek de méthode avec remplacement , j'ai donc dupliqué les opérateurs le nombre correct de fois, calculé tout l'espace nchoosekpour cette plus grande sélection d'opérateurs, puis utilisé un uniqueappel pour réduire le résultat à ce qu'il devrait être. (en supprimant les combinaisons équivalentes comme «*** +» et «*** +»). J'ajoute un espace de fin pour correspondre à la longueur du vecteur d'entrée à des fins de concaténation, puis je compose les chaînes d'opérateur avec les chaînes d'entrée dans les colonnes d'une matrice. J'évalue ensuite les expressions colonne par colonne pour obtenir des résultats et trouver l'ordre des opérateurs qui correspond à ces colonnes avec des résultats qui correspondent à notre entrée r.

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

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

Si je devais prendre un tableau de valeurs de double précision, j'aurais besoin x = num2str(x,'%d');pour convertir les chiffres en une chaîne, en ajoutant 21 (20 sans le ;) à mon score. * Les octets supplémentaires étaient des points-virgules que j'ai laissés uniquement afin que toute personne exécutant ce code ne voit pas son invite de commande exploser avec de longs tableaux. Étant donné que ma modification produit maintenant une pile géante d'avertissements sur les logiques et les opérandes deux-points, j'ai supprimé les points-virgules dans la nouvelle version.

Edit 2: J'ai oublié de remplacer un 2*n+2par k.

Ancienne réponse:

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
la source
2

JavaScript (ES6), 88 octets

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

Jeté un peu au hasard dans le mélange. Beaucoup plus facile que d'itérer systématiquement à travers les combinaisons.

Suite de tests

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
la source
1

PHP, 108 octets

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

prend les entrées des arguments de ligne de commande dans l'ordre inverse. Courez avec -r.

panne

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
la source