Sommes d'échange de signes

24

Étant donné une liste non vide d'entiers positifs , votre travail consiste à déterminer le nombre de valeurs uniques de± x ± y ± z ± (X,y,z,)±x±y±z±

Par exemple, considérez la liste . Il existe huit façons possibles de créer des sommes:(1,2,2)

  • +1+2+2+5
  • +1+22+1
  • +12+2+1
  • +1223
  • 1+2+2+3
  • -1+2-2-1
  • -1-2+2-1
  • -1-2-2-5

Il y a six sommes uniques , donc la réponse est .6{5,-5,1,-1,3,-3}6

Cas de test

[1, 2] => 4
[1, 2, 2] => 6
[s]*n => n+1
[1, 2, 27] => 8
[1, 2, 3, 4, 5, 6, 7] => 29
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] => 45
[1, 7, 2, 8, 3, 1, 6, 8, 10, 9] => 56
[93, 28, 92, 100, 43, 66, 2, 98, 2, 52, 57, 75, 39, 77, 45, 15, 13, 82, 81, 20, 68, 14, 5, 3, 72, 56, 57, 1, 23, 25, 76, 59, 60, 71, 71, 24, 1, 3, 72, 84, 72, 28, 83, 62, 66, 45, 21, 28, 49, 57, 70, 3, 44, 47, 1, 54, 53, 56, 36, 20, 99, 9, 89, 74, 1, 14, 68, 47, 99, 61, 46, 26, 69, 21, 20, 82, 23, 39, 50, 58, 24, 22, 48, 32, 30, 11, 11, 48, 90, 44, 47, 90, 61, 86, 72, 20, 56, 6, 55, 59] => 4728

Solution de référence (optimise la vitesse et non la taille).

Si vous ne pouvez pas gérer le dernier cas parce que vous utilisez une méthode de force brute ou similaire, ça va.

Notation

Il s'agit de , donc la solution valide la plus courte (mesurée en octets) l'emporte.

Esolanging Fruit
la source
Faut-il gérer le cas où l'entrée est le tableau vide?
Chas Brown
@ChasBrown, l'entrée n'est pas vide, selon le message.
JungHwan Min
Hm, je ne comprends pas comment fonctionne le troisième cas de test, veuillez expliquer s'il vous plaît?
Erik the Outgolfer
@EriktheOutgolfer C'est effectivement dire que si votre tableau est tous des nombres identiques (par exemple [2,2,2,2,...]) la réponse doit être la longueur du tableau + 1. C'est parce que dans ce cas, la position des signes n'est pas pertinente et que le nombre de chaque matière
reffu
@reffu C'est plus une blague, on dirait qu'elle a été incluse là par erreur.
Erik the Outgolfer

Réponses:

13

Wolfram Language (Mathematica) , 27 octets

Tr[1^Fold[#⋃+##&,{0},#]]&

Essayez-le en ligne!

Trouver le nombre de sommes d'échange de signes uniques équivaut à trouver le nombre de sommes de sous-ensembles uniques.

Une preuve impliquerait d'ajouter la somme de l'entrée à chacune des sommes d'échange de signes et de la diviser par deux. Ensuite, il y a une bijection évidente.

Explication

Fold[#⋃+##&,{0},#]

Parcourez l'entrée, la valeur initiale étant {0}: prenez l'union entre <current value>et <current value> + input element(mappe sur des listes).

Tr[1^ ... ]

Version Golfy de la Lengthfonction.

JungHwan Min
la source
8

Gelée , 6 octets

ŒPS€QL

Essayez-le en ligne!

Contexte

Soit L la liste d'entrée et {P, N} une partition en sommets algébriques avec des signes positifs et négatifs. La spécification de défi nécessite de calculer s {P, N} = somme (P) - somme (N) .

Cependant, puisque somme (P) + somme (N) = somme (L) et somme (L) ne dépend pas de la partition, nous avons s {P, N} = somme (P) - somme (N) = somme ( P) - (somme (L) - somme (P)) = 2 somme (P) - somme (L) .

Ainsi, chaque valeur unique de somme (P) correspond à une valeur unique de s {P, N} .

Comment ça marche

ŒPS€QL  Main link. Argument: A (array)

ŒP      Powerset; generate all subarrays of A.
  S€    Take the sum of each.
    Q   Unique; deduplicate the sums.
     L  Take the length.
Dennis
la source
7

MATL , 11 10 octets

nW:qBGY*un

Essayez-le en ligne! Ceci est un portage de la réponse Octave / MATLAB de Luis Mendo . J'essaie toujours d'apprendre MATL, et j'ai pensé que je le posterais, avec une explication, puisque MATL est la langue du mois.

Explication:

Voici une lecture pour tous ceux qui ne connaissent pas la programmation basée sur la pile en général, et MATL en particulier.

Le vecteur d'entrée est implicitement placé sur la pile. Notez que lorsqu'une opération est effectuée sur un élément de la pile, cet élément est supprimé de la pile.

                % Stack:
                % [1, 2, 2]
n               % Counts the number of elements of the vector on the top of the stack.
                % Stack:
                % [3]
 W              % Raise 2^x, where x is the number above it in the stack
                % Stack:
                % [8]
  :             % Range from 1...x, where x is the number above it in the stack.                    % Stack:
                % [1, 2, 3, 4, 5, 6, 7, 8]
   q            % Decrement. Stack:
                % [0, 1, 2, 3, 4, 5, 6, 7]
    B           % Convert to binary. Stack:
                % [0,0,0; 0,0,1; 0,1,0; 0,1,1; 1,0,0; 1,0,1; 1,1,0; 1,1,1] 
     G          % Push input again. Stack:           
                % [0,0,0; 0,0,1; 0,1,0; 0,1,1; 1,0,0; 1,0,1; 1,1,0; 1,1,1], [1; 2; 2]
      Y*        % Matrix multiplication of the two elements on the stack.
                % Stack:
                % [0; 2; 2; 4; 1; 3; 3; 5]
        u       % Keep only unique elements. Stack:
                % [0; 2; 4; 1; 3; 5]
         n      % Number of elements in the vector. Stack:
                % [6]

Et puis il renvoie implicitement le dernier élément de la pile.

Stewie Griffin
la source
1
Belle explication!
Luis Mendo
6

Python 2 , 52 octets

k=1
for n in input():k|=k<<n
print bin(k).count('1')

Essayez-le en ligne!

Utilise la représentation binaire d'un nombre pour stocker les sommes des sous-ensembles accessibles.

xnor
la source
1
Pourriez-vous expliquer comment cela fonctionne? L'avez-vous inventé vous-même ou s'agit-il d'un résultat connu?
sundar
1
@sundar Ce n'est pas si compliqué. Cette réponse calcule les sommes uniques (pas l'échange de signes) comme beaucoup d'autres réponses. Chaque bit en k correspond à une somme. k<<najoute n à chaque somme. Oring avec kstocke ces nouvelles sommes ktout en conservant toutes les précédentes, et les Sims dupliqués ne sont pas enregistrés
H.PWiz
Ah, la piste des miettes de pain nous ramène à l'idée de bijection de JungHwan Min , qui était la principale idée qui me manquait. Ici, chaque somme de sous-ensemble est représentée par un 1 à cette position dans la chaîne binaire (avec le 1 initial dans le LSB représentant la somme 0 pour le sous-ensemble vide). Ce n'est pas quelque chose que j'appellerais "pas si compliqué", mais c'est peut-être simplement mon inexpérience à parler. :)
sundar
5

Haskell, 46 octets

import Data.List
length.nub.map sum.mapM(:[0])

Essayez-le en ligne!

Au lieu de sommer les sous-ensembles de la liste d'entrée, nous faisons toutes les combinaisons soit en conservant un nombre, soit en le remplaçant par 0, par exemple

mapM(:[0])[1,2,3] -> [[1,2,3],[1,2,0],[1,0,3],[1,0,0],[0,2,3],[0,2,0],[0,0,3],[0,0,0]]

C'est deux octets de moins que subsequences.

nimi
la source
Bonne réponse! J'espérais que quelque chose comme ça f x=sum[1|i<-[0..sum x],elem i$sum<$>mapM(:[0])x]serait plus court que l'importation, mais apparemment, ce n'est pas le cas.
Lynn
Sympa, encore plus court que la traduction de Mathematica, bien que je pense que c'est plus joli:import Data.List;length.foldr((<*>)union.map.(+))[0]
Jon Purdy
5

R, 83 75 octets

-8 octets grâce à JayCe et Giuseppe

Crée une matrice de toutes les combinaisons possibles de (1, -1) pour la taille du vecteur d'entrée, multiplie cela par le vecteur d'origine pour obtenir les sommes. Ensuite, unique et trouvez la longueur du résultat.

function(v)nrow(unique(t(t(expand.grid(rep(list(c(1,-1)),sum(v|1)))))%*%v))


la version précédente:

f=function(v)nrow(unique(as.matrix(expand.grid(rep(list(c(1,-1)),length(v))))%*%v))

Non golfé avec des commentaires:

f=function(vector){

  List=rep(list(c(1,-1)),length(vector))   ## Create a list with length(vector) elements, all (1,-1)

  Combinations=expand.grid(Length)    ## get all combinations of the elements of the list, e.g, 1,-1,1,1,-1,1

  Matrix=as.matrix(Combinations)   ## convert to matrix

  Results=Matrix%*%vector   ## multiply the matrix original vector to get a Nx1 matrix

  Unique_results=unique(Results)   ## unique the results

  nrow(Unique_results)   ## length = number of rows of unique values
  }
Andrew Haynes
la source
Économisez quelques octets avec t: TIO
JayCe
et sum(v|1)est un octet plus court quelength(v)
Giuseppe
4

Octave / MATLAB, 45 41 40 octets

@(x)nnz(unique(dec2bin(0:2^nnz(x)-1)*x))

L'entrée est un vecteur de colonne (utilisé ;comme séparateur).

Les erreurs de code pour le dernier cas de test en raison de restrictions de mémoire.

Cela utilise une idée de la réponse de JungHwan Min (sous-ensembles au lieu de signes alternés) pour économiser quelques octets.

Essayez-le en ligne!

Luis Mendo
la source
4

Pari / GP , 39 octets

a->#[1|n<-Vec(prod(i=1,#a,1+x^a[i])),n]

jeune(1+Xje)une

Essayez-le en ligne!

alephalpha
la source
C'est une façon cool de le faire!
JungHwan Min
3

Python 3 , 61 octets

f=lambda a,s={0}:a and f(a[1:],s|{u+a[0]for u in s})or len(s)

Essayez-le en ligne!

Approche récursive, gardant une trace des sommes de sous-ensembles uniques.

Le vrai plaisir est que cela bat itertoolspar une grande marge:

76 octets

lambda a:len({*map(sum,product(*([0,x]for x in a)))})
from itertools import*

Essayez-le en ligne!

Bubbler
la source
3

Attaché , 29 octets

{#Unique[Flat!±_]}@Fold[`±]

Essayez-le en ligne!

Cela fonctionne en repliant l' ±opérateur sur la liste d'entrée, puis en prenant ±cette liste, puis en comptant les atomes uniques du tableau.

Voici quelques exemples du fonctionnement du pliage:

Fold[`±][ [1,2] ] == 1 ± 2
                  == [1 + 2, 1 - 2]
                  == [3, -1]
Fold[`±][ [1,2,2] ] == (1 ± 2) ± 2
                    == [3, -1] ± 2
                    == [[3 + 2, 3 - 2], [-1 + 2, -1 - 2]]
                    == [[5, 1], [1, -3]]
                    == [5, 1, 1, -3]
Fold[`±][ [4,4,4,4] ] == (4 ± 4) ± 4 ± 4
                      == [8, 0] ± 4 ± 4
                      == [[12, 4], [4, -4]] ± 4
                      == [[[16, 8], [8, 0]], [[8, 0], [0, -8]]]
                      == [16, 8, 8, 0, 8, 0, 0, -8]
                      == [16, 8, 0, -8]

Ensuite, nous générons toutes les permutations du signe final en appliquant à nouveau PlusMinus.

Une version plus efficace, 31 octets

`#@(q:=Unique@Flat@`±)@Fold[q]

Essayez-le en ligne! Cela n'expire pas sur le cas de test final, car il ne génère pas de combinaisons inutiles.

Conor O'Brien
la source
3

R , 62 octets

function(V)sum(unique(c(V%*%combn(rep(0:1,L),L<-sum(V|1))))|1)

Essayez-le en ligne!

Algorithme de Ports Dennis. Il est le plus proche des réponses Octave / MATL car il utilise un produit bitmap et matrice similaire pour l'inclusion / exclusion de termes.

Giuseppe
la source
2

Husk , 5 octets

LumΣṖ

Essayez-le en ligne!

Réponse de Jelly du port de Dennis.

Explication

LumΣṖ                     [1,2,2]
    Ṗ  Powerset           [[],[1],[2],[1,2],[2],[1,2],[2,2],[1,2,2]]
  mΣ   Sum each           [0,1,2,3,2,3,4,5]
 u     Remove duplicates  [0,1,2,3,4,5]
L      Length             6
Fyr
la source
Équivalent à la réponse Pyth , essentiellement caractère pour caractère.
isaacg
2

Utilitaires Bash + GNU, 49 octets

eval echo "{,-}${@//,/{+,-\}}\;"|bc|sort -u|wc -l

Essayez-le en ligne!

Entrée donnée sous forme de liste séparée par des virgules sur la ligne de commande.

Explication

               ${@//,/{+,-\}}                      # Replace commas with {+,-}
          "{,-}${@//,/{+,-\}}\;"                   # Build a brace expansion with {+,-} before every number and ; at the end
eval echo "{,-}${@//,/{+,-\}}\;"                   # Expand to give every combination expression, separated by ;
                                |bc                # Arithmetically evaluate each line
                                   |sort -u        # Remove duplicates
                                            wc -l  # Count
Traumatisme numérique
la source
2

Langage machine x86_64 pour Linux, 31 29 octets

 0:   31 d2                   xor    %edx,%edx
 2:   6a 01                   pushq  $0x1
 4:   58                      pop    %rax
 5:   8b 0c 97                mov    (%rdi,%rdx,4),%ecx
 8:   48 89 c3                mov    %rax,%rbx
 b:   ff c2                   inc    %edx
 d:   48 d3 e3                shl    %cl,%rbx
10:   48 09 d8                or     %rbx,%rax
13:   39 d6                   cmp    %ese,%edx
15:   7c ee                   jle    5 <+0x5>
17:   f3 48 0f b8 c0          popcnt %rax,%rax
1c:   c3                      retq

Essayez-le en ligne!

Inspiré par la réponse de @ xnor. Nécessite une machine avec l' POPCNTinstruction.

plafond
la source
2

C (gcc) , 74 69 octets

f(a,b)int*a;{long k=1;for(;b--;k|=k<<a[b]);a=__builtin_popcountl(k);}

Essayez-le en ligne!

Port C de la réponse de @ xnor

plafond
la source
1

APL (Dyalog Classic) , 34 33 32 octets

{≢∪⍵+.×⍨↑{,⍵∘.,U}⍣(≢1↓⍵)⊢U←¯1 1}

Essayez-le en ligne!

Merci à @ngn pour -1 octet!

Zacharý
la source
1-⍨≢⍵->≢1↓⍵
ngn
+.×⍨->+.×
ngn
Ce dernier ne fonctionne pas, je le crains.
Zacharý
oups, je ne sais pas pourquoi je pensais que vous appliquez +. × sur les vecteurs ... désolé
ngn
1

Nettoyer , 82 octets

import StdEnv
f[]=length
f[h:t]=f t o foldr(\e l=removeDup[e+h,e-h:l])[]
?l=f l[0]

Essayez-le en ligne!

Définit la fonction en ? :: [Int] -> Intutilisant f :: [Int] -> ([Int] -> Int)comme aide pour réduire chaque somme possible après un ajout ou une soustraction.

Οurous
la source
Voici une version golfée de la solution de référence à Haskell; Je ne sais pas combien il peut être transféré à Clean, mais vous pourriez en retirer quelque chose.
Esolanging Fruit
@EsolangingFruit Merci, mais il utilise déjà la même approche et je ne trouve pas de moyen de le raccourcir même avec la solution de référence golfée.
ousurous
1

APL (Dyalog Classic) , 21 octets

⍴∘∪⊢+.×1-2×2(⍴⍨⊤∘⍳*)⍴

Essayez-le en ligne!

Explication

2(⍴⍨⊤∘⍳*)⍴

Un train de fonctions équivalent à {((⍴⍵)⍴2)⊤⍳(⍴⍵)}, qui génère une matrice qui a les représentations binaires de 0 à la longueur de l'entrée sous forme de colonnes

1-2×

Mappe 1s à -1s et 0s à 1s

⊢+.×

Multiplication matricielle avec l'entrée, qui donne un tableau de toutes les sommes possibles

⍴∘∪

Supprimer les doublons, puis compter

TwiNight
la source
1

Java 8, 207 83 44 octets

s->Long.bitCount(s.reduce(1L,(r,c)->r|r<<c))

Port de @ xnor réponse Python 2 .
-39 octets grâce à @Jakob .

Essayez-le en ligne .

s->               // Method with Long-Stream parameter and long return-type
  Long.bitCount(  //  Return the amount of 1s in the binary representation of:
    s.reduce(1L,  //   Result-Long, starting at 1
     (r,c)->      //   Loop pair-wise (result,current):
      r|          //    Bitwise-OR the result `r` with:
        r<<c))    //    result `r` bitwise left-shifted by the current `c`
Kevin Cruijssen
la source
2
44 octets, c'est tout ce dont nous avons besoin! Prendre un flux de Long: s->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e)).
Jakob
@Jakob Merci! J'oublie toujours .reduce(et .bitCountaussi je pourrais ajouter ..>.>) -39 octets juste là! :)
Kevin Cruijssen
1
De plus, je viens de faire une version à précision arbitraire . Il semble que la façon la moins chère de le faire soit toujours avec un bitmap plutôt qu'avec des ensembles.
Jakob
1

Java 8, 85 octets

Un autre port Java de xnor réponse de . Comme la réponse d'origine, cela utilise un bitmap de précision arbitraire afin qu'il n'y ait pas de limite supérieure sur la taille d'une somme de sous-ensemble.

C'est un lambda d'un séquentiel java.util.stream.Stream<Integer>à int.

s->s.reduce(java.math.BigInteger.ONE,(a,e)->a.or(a.shiftLeft(e)),(u,v)->u).bitCount()

Essayez-le en ligne

Notez que le combineur (le troisième argument de reduce) n'est pas utilisé car le flux est séquentiel. La fonction que j'ai choisie est arbitraire.

Jakob
la source
1

Julia 0,6 , 54 52 octets

V->(~W=W==[]?0:∪([n=W[] -n].+~W[2:end]))(V)|>endof

Essayez-le en ligne!

( -2 octets en remplaçant ¬par ~, merci à Jo King )

Fonctionne pour tous les cas de test. Utilise la diffusion pour collecter toutes les sommes possibles, puis les compte.

Explication:

function g_(V)
  function inner(W)  #named ~ in golf version to save bytes
    W == [] ? 0 :    #return 0 when input empty (base case)
    ∪(               #unique elements of
      [n=W[] -n]     #take the first element and its negation
      .+             #broadcast-add that to each element of
      inner([2:end]) #sign-swapping sums of the rest of the array
     )
  end                #returns the list of unique elements out of those sums
  return endof(inner(V)) #return the length of that list
end

Solution plus ancienne:

Julia 0,6 , 64 octets

N->endof(∪([2(i&2^~-j>0)-1 for i=0:~-2^(l=endof(N)),j=1:l]*N))

Essayez-le en ligne!

Fonctionne pour les tableaux d'entrée avec une longueur jusqu'à 63 (donc ne fonctionne pas pour le dernier cas de test, ce qui est bien selon OP).

Explication:

function f_(N)
  endof(                            #length of
        ∪(                          #unique elements of
          [
           (i & 2^(j-1) > 0)        #check j'th bit (from right) of i
           * 2 - 1                  #convert bit value from (0,1)=>(-1,1)
           for i = 0:2^endof(N)-1,  #where i is numbers 0 to 2^length(N)-1
           j = 1:endof(N)           #and j is 1 to length(N) (i.e. the bits in i)
          ]                         #so we have a matrix [-1 -1 -1;1 -1 -1;1 -1 1;...]
          *                         #matrix multiply that with the input array, 
          N                         #thus calculating different combinations of 
         ))                         #sign-swapping sums
end
Sundar - Rétablir Monica
la source
0

JavaScript (nœud Babel) , 64 octets

F=([f,...r],s=[0])=>f?F(r,s.flatMap(x=>[x+f,x])):new Set(s).size

Essayez-le en ligne!

Cela ne fonctionnera pas pour le dernier test.


Solution plus efficace (fonctionne sur le dernier testcase):

JavaScript (Babel Node) , 71 octets

F=([f,...r],s=[0])=>f?F(r,[...new Set(s.flatMap(x=>[x+f,x]))]):s.length

Essayez-le en ligne!


Cela ne fonctionnera pas dans un vrai navigateur à cause de Array#smoosh.

Merci à Bubbler, [x+f,x-f]-> [x+f,x]enregistre 2 octets.

tsh
la source
Vous pouvez utiliser [x+f,x]à la place de [x+f,x-f]( preuve par JungHwan Min ).
Bubbler
+2 octets pour la version ES6:F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size
Neil
@Neil, et ... [...s,...s.map(x=>x+f)], s.concat(s.map(x=>x+f))et, s,s.map(x=>s.push(x+f))part même longueur ...
tsh
0

Rouge , 73 octets

func[b][s:[0]foreach n b[foreach m s[s: union s reduce[m + n]]]length? s]

Réponse de Python 2 du port de Dennis. Ne gère pas le dernier cas de test.

Essayez-le en ligne!

Galen Ivanov
la source