Tabela Değiştirme Toplamları


24

Olumsuz tamsayıların boş bir listesi göz önüne alındığında , işiniz benzersiz değerlerinin sayısını belirlemektir.± x ± y ± z ± (x,y,z,...)±x±y±z±...

Örneğin, listeyi düşünün . Toplamları oluşturmanın sekiz olası yolu vardır:(1,2,2)

  • +1+2+2+5
  • +1+2-2+1
  • +1-2+2+1
  • +1-2-2-3
  • -1+2+2+3
  • -1+2-2-1
  • -1-2+2-1
  • -1-2-2-5

Altı benzersiz toplam vardır: , bu yüzden cevap .6{5,-5,1,-1,3,-3}6

Test Kılıfları

[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

Referans çözümü (hız için değil boyut için optimize edilmiştir).

Son davayı kaldıramazsanız, kaba kuvvet metodu veya benzeri bir yöntem kullandığınızdan, sorun değil.

puanlama

Bu , yani en kısa geçerli çözüm (bayt olarak ölçülen) kazanır.


Girişin boş dizi olduğu durumu ele almalı mıyız?
Chas Brown

@ChasBrown, yazıya göre giriş boş değildir.
JungHwan Min 10:18

Üçüncü test davasının nasıl çalıştığını anlamıyorum, lütfen açıklamak ister misiniz?
Outgolfer Erik,

@EriktheOutgolfer Bu etkili (örneğin diziniz tüm özdeş numaralar ise diyor [2,2,2,2,...]cevap dizisinin + 1. Bu, bu durumda işaretlerin pozisyonu her maddenin tek sayı alakasız ve çünkü uzunluğu olmalıdır)
reffu

@reffu Bir şakaydı, oraya yanlışlıkla dahil edilmiş gibi görünüyor.
Outgolfer Erik,

Yanıtlar:


13

Wolfram Dili (Mathematica) , 27 bayt

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

Çevrimiçi deneyin!

Eşsiz işaret takımlı toplamların sayısını bulmak, benzersiz alt kümelerin toplamlarının sayısını bulmakla eşdeğerdir.

Bir kanıt, girişin toplamını, her bir kayıt-değişim toplamına eklemeyi ve ikiye bölmeyi içerecektir. O zaman bariz bir önyargı var.

açıklama

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

İlk değer şu şekilde girdide yineleyin {0}: <current value>ve arasındaki ilişkiyi alın <current value> + input element(listelerde haritalar).

Tr[1^ ... ]

LengthFonksiyonun Golfy versiyonu .


8

Jöle , 6 bayt

ŒPS€QL

Çevrimiçi deneyin!

Arka fon

Let L giriş listesi ve olmak {P, N} , pozitif ve negatif belirtileri ile cebirsel summands içine bir bölüm. Meydan okuma özelliği s {P, N} = toplamı (P) - toplamı (N) hesaplamayı gerektirir .

Ancak, toplam (P) + toplam (N) = toplam (L) ve toplam (L) bölüme bağlı olmadığından, s {P, N} = toplam (P) - toplam (N) = toplam ( P) - (toplam (L) - toplam (P)) = 2sum (P) - toplam (L) .

Böylece, her bir toplam (P) değeri, s {P, N} ' in bir benzersiz değerine karşılık gelir .

Nasıl çalışır

Œ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.

7

Matl , 11 10 bayt

nW:qBGY*un

Çevrimiçi deneyin! Bu Luis Mendo'nun Octave / MATLAB cevabının limanı . Hala MATL öğrenmeye çalışıyorum ve MATL ayın dili olduğu için bir açıklama ile birlikte göndereceğimi düşündüm.

Açıklama:

İşte genel olarak yığın tabanlı programlamayı ve özellikle MATL'ı bilmeyenler için bir okuma.

Giriş vektörü örtük olarak yığına yerleştirilir. Bir işlem yığındaki bir öğe üzerinde gerçekleştirildiğinde, o öğenin yığından kaldırıldığını unutmayın.

                % 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]

Ve sonra son elemanı istif üzerinde örtük olarak çıkarır.


1
Güzel açıklama!
Luis Mendo


6

Python 2 , 52 bayt

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

Çevrimiçi deneyin!

Ulaşılabilir alt küme toplamlarını depolamak için bir sayının ikili gösterimini kullanır.


1
Bunun nasıl çalıştığını açıklayabilir misiniz? Kendin mi buldun, yoksa bilinen bir sonuç mu?
sundar - Reinstate Monica,

1
@ sundar O kadar karmaşık değil. Bu cevap, diğer birçok cevap gibi, benzersiz toplamları (işaret değiştirmeyi değil) hesaplar. K içindeki her bit bir toplama karşılık gelir. k<<nher toplama n ekler. Önceki ile aynı tutarken ve kyeni kopyalar saklanırken, bu yeni toplamları mağazalarla birlikte kullanmak k, çoğaltılmış
Sims'ler

Ah, molaların izleri JungHwan Min'in itiraz fikrine geri döndü , bu benim özlediğim ana fikirdi . Burada, her bir alt küme toplamı bitstring'deki o konumda bir 1 ile temsil edilir (LSB'deki ilk 1 ile boş alt küme için toplamı 0 temsil eder). Yine de "o kadar da karmaşık değil" dediğim bir şey değil, ama bu benim deneyimsizlik konuşmam olabilir. :)
sundar - Reinstate Monica,


5

Haskell, 46 bayt

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

Çevrimiçi deneyin!

Giriş listesinin alt kümelerini toplamak yerine, bir sayı tutmanın ya da 0örneğin

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

Bu, iki bayttan daha kısa subsequences.


Güzel cevap! Bunun gibi bir şeyin f x=sum[1|i<-[0..sum x],elem i$sum<$>mapM(:[0])x]ithalattan daha kısa olacağını umuyordum , ama görünüşe göre öyle değil.
Lynn,

Güzel, Mathematica'nın çevirisinden bile daha kısa olsa da, daha güzel olduğunu düşünüyorum:import Data.List;length.foldr((<*>)union.map.(+))[0]
Jon Purdy

5

R, 83 75 bayt

JayCe ve Giuseppe sayesinde -8 bayt

Girdi vektörünün büyüklüğü için olası tüm (1, -1) kombinasyonlarının bir matrisini oluşturur, bunu toplamları elde etmek için bunu orijinal vektör ile çarpar. Sonra benzersiz ve sonucun uzunluğunu bulun.

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


önceki versiyon:

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

Yorumsuz Ungolfed:

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
  }


ve sum(v|1)bir bayt daha kısadırlength(v)
Giuseppe

4

Octave / MATLAB, 45 41 40 bayt

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

Giriş bir sütun vektörüdür ( ;ayırıcı olarak kullanılır ).

Bellek kısıtlamaları nedeniyle son sınama durumu için kod hataları.

Bu, birkaç bayttan tasarruf etmek için JungHwan Min'in yanıtından (alternatif işaretler yerine altkümeler) bir fikir kullanır .

Çevrimiçi deneyin!



3

Python 3 , 61 bayt

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

Çevrimiçi deneyin!

Özyinelemeli yaklaşım, benzersiz alt küme toplamlarının kaydını tutar.

Asıl eğlence, bunun itertoolsbüyük bir farkla atması:

76 bayt

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

Çevrimiçi deneyin!



3

Ataşesi , 29 bayt

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

Çevrimiçi deneyin!

Bu, ±işleci giriş listesi üzerinde katlayarak , ardından ±o listeyi alarak , dizinin benzersiz atomlarını sayarak çalışır.

İşte katlamanın nasıl çalıştığına dair bazı örnekler:

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]

Sonra, bir kez daha PlusMinus uygulayarak son işaretin tüm permütasyonlarını üretiyoruz.

Daha verimli bir sürüm, 31 bayt

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

Çevrimiçi deneyin! Gereksiz kombinasyonlar üretmediği için bu son testte zaman aşımına uğramaz.


3

R , 62 bayt

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

Çevrimiçi deneyin!

Limanlar Dennis'in algoritması. Terimlerin dahil edilmesi / hariç tutulması için benzer bir bitmap ve matris ürünü kullandığından Octave / MATL cevaplarına en yakın olanıdır.







2

Bash + GNU yardımcı programları, 49 bayt

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

Çevrimiçi deneyin!

Komut satırında virgülle ayrılmış liste olarak verilen giriş.

açıklama

               ${@//,/{+,-\}}                      # 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

2

Linux için x86_64 makine dili, 31 29 bayt

 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

Çevrimiçi deneyin!

@ Xnor'ın cevabından ilham alındı. POPCNTTalimatı ile bir makine gerektirir .




1

Temiz , 82 bayt

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

Çevrimiçi deneyin!

Fonksiyonu tanımlar ? :: [Int] -> Intkullanılarak f :: [Int] -> ([Int] -> Int)bir ekleme ya da çıkarma sonra her bir olası bir miktar fazla azaltmak için bir yardımcı olarak.


İşte Haskell'deki referans çözümünün golf versiyonu; Temiz'e ne kadar taşıyabileceğinden emin değilim, ancak bundan bir şey çıkarabilirsiniz.
Esolanging Fruit

@EsolangingFruit Teşekkürler, ama zaten aynı yaklaşımı kullanıyor ve referans çözüm golf ile bile onu kısaltmanın bir yolunu bulamıyorum.
Büyük

1

APL (Dyalog Klasik) , 21 bayt

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

Çevrimiçi deneyin!

açıklama

2(⍴⍨⊤∘⍳*)⍴

{((⍴⍵)⍴2)⊤⍳(⍴⍵)}Girdiyi sütun olarak 0 ile ikili olarak temsil eden bir matris üreten eşdeğer bir fonksiyon treni

1-2×

S'den 1s'ye -1s ve 0s'den 1s'ye eşler

⊢+.×

Tüm olası toplamların bir dizisini veren girişli matris çarpımı

⍴∘∪

Kopyaları kaldırın, sonra sayın


1

Java 8, 207 83 44 bayt

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

@ Xnor'ın Python 2 cevabının limanı . @ Jakob
sayesinde -39 bayt .

Çevrimiçi deneyin .

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`

2
Tek ihtiyacımız olan 44 bayt! Bir akım alma Long: s->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e)).
Jakob

@ Jakob Teşekkürler! Ben her zaman unuturum .reduce(ve .bitCountben de ekleyebilirim ..>.>) -39 bayt orada! :)
Kevin Cruijssen

1
Ayrıca sadece hassas bir versiyonunu yaptım . Görünüşe göre en ucuz yol hala setlerden ziyade bir bitmap ile.
Jakob

1

Java 8, 85 bayt

Xnor'ın cevabının başka bir Java portu . Orijinal cevap gibi, bu da isteğe bağlı olarak hassas bir bitmap kullanır, böylece alt küme toplamının boyutunda üst sınır yoktur.

Bir sıralı bir lambda var java.util.stream.Stream<Integer>etmek int.

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

Çevrimiçi Deneyin

reduceAkış sıralı olduğundan birleştiricinin (üçüncü argüman ) kullanılmadığına dikkat edin. Seçtiğim işlev keyfi.


1

Julia 0.6 , 54 52 bayt

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

Çevrimiçi deneyin!

( -2 değiştirerek bayt ¬ile ~size, Jo Kral )

Tüm test durumları için çalışır. Mümkün olan tüm meblağları toplamak için yayını kullanır, sonra sayar

Açıklama:

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

Eski çözüm:

Julia 0.6 , 64 bayt

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

Çevrimiçi deneyin!

63'e kadar uzunluktaki giriş dizileri için çalışır (dolayısıyla OP'ye göre iyi olan son test durumu için çalışmaz).

Açıklama:

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

0

JavaScript (Babel Düğümü) , 64 bayt

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

Çevrimiçi deneyin!

Bu son test için işe yaramaz.


Daha etkili bir çözüm (son test çantasında çalışır):

JavaScript (Babel Düğümü) , 71 bayt

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

Çevrimiçi deneyin!


Bu nedeniyle gerçek bir tarayıcıda çalışmaz Array#smoosh.

Bubbler sayesinde, [x+f,x-f]-> [x+f,x]2 bayt kaydeder.


Sen kullanabilirsiniz [x+f,x]yerine [x+f,x-f]( Junghwan Min tarafından ispat ).
Bubbler

ES6 sürümü için +2 bayt:F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size
Neil

@Neil, ve ... [...s,...s.map(x=>x+f)], s.concat(s.map(x=>x+f))ve, s,s.map(x=>s.push(x+f))aynı uzunluğu paylaşırlar ...
tsh

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.