Jumlah Pertukaran Swap


24

Dengan diberikan daftar kosong bilangan bulat positif , tugas Anda adalah menentukan jumlah nilai unik ± x ± y ± z ± ...(x,y,z,...)±x±y±z±...

Sebagai contoh, perhatikan daftarnya . Ada delapan cara yang memungkinkan untuk membuat penjumlahan:(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

Ada enam jumlah unik , jadi jawabannya adalah 6 .{5,-5,1,-1,3,-3}6

Uji Kasus

[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

Solusi referensi (mengoptimalkan kecepatan dan bukan ukuran).

Jika Anda tidak dapat menangani kasus terakhir karena Anda menggunakan metode brute-force atau yang serupa, itu tidak masalah.

Mencetak gol

Ini adalah , sehingga solusi terpendek yang valid (diukur dalam byte) menang.


Apakah kita harus menangani case di mana inputnya adalah array kosong?
Chas Brown

@ChasBrown input tidak kosong, menurut posting.
JungHwan Min

Hm, saya tidak bisa mengerti cara kerja test case ketiga, tolong jelaskan?
Erik the Outgolfer

@EriktheOutgolfer Secara efektif mengatakan jika array Anda adalah semua angka yang identik (mis [2,2,2,2,...]. Jawabannya harus panjang array + 1. Ini karena dalam hal ini posisi tanda tidak relevan dan hanya jumlah setiap masalah
reffu

@reffu Ini lebih dari sebuah lelucon, sepertinya memang sudah ada kesalahan.
Erik the Outgolfer

Jawaban:


13

Bahasa Wolfram (Mathematica) , 27 byte

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

Cobalah online!

Menemukan jumlah jumlah sign-swapping yang unik sama dengan menemukan jumlah jumlah subset unik.

Suatu bukti akan melibatkan penambahan jumlah input ke masing-masing jumlah sign-swapping dan membaginya menjadi dua. Lalu, ada sebuah bujukan yang jelas.

Penjelasan

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

Iterasi melalui input, dengan nilai awal adalah {0}: bawa penyatuan antara <current value>dan <current value> + input element(peta ke daftar).

Tr[1^ ... ]

Versi Golfy dari Lengthfungsi.


8

Jelly , 6 byte

ŒPS€QL

Cobalah online!

Latar Belakang

Biarkan L menjadi daftar input dan {P, N} partisi ke dalam puncak aljabar dengan tanda-tanda positif dan negatif. Spec tantangan memerlukan penghitungan s {P, N} = jumlah (P) - jumlah (N) .

Namun, karena jumlah (P) + jumlah (N) = jumlah (L) dan jumlah (L) tidak bergantung pada partisi, kita memiliki s {P, N} = jumlah (P) - jumlah (N) = jumlah ( P) - (jumlah (L) - jumlah (P)) = 2sum (P) - jumlah (L) .

Dengan demikian, setiap nilai unik dari jumlah (P) sesuai dengan satu nilai unik s {P, N} .

Bagaimana itu bekerja

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

nW:qBGY*un

Cobalah online! Ini adalah port jawaban Oktaf / MATLAB Luis Mendo . Saya masih mencoba untuk belajar MATL, dan saya pikir saya akan mempostingnya, bersama dengan penjelasan, karena MATL adalah bahasa bulan ini.

Penjelasan:

Berikut adalah read-through untuk siapa pun yang tidak terbiasa dengan pemrograman berbasis stack pada umumnya, dan MATL pada khususnya.

Vektor input secara implisit ditempatkan pada stack. Perhatikan bahwa ketika operasi dilakukan pada elemen dalam tumpukan, maka elemen itu dihapus dari tumpukan.

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

Dan kemudian menampilkan elemen terakhir pada stack secara implisit.


1
Penjelasan yang bagus!
Luis Mendo


6

Python 2 , 52 byte

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

Cobalah online!

Menggunakan representasi biner dari angka untuk menyimpan jumlah subset yang dapat dijangkau.


1
Bisakah Anda menjelaskan cara kerjanya? Apakah Anda sendiri yang membuatnya, atau apakah itu hasil yang diketahui?
sundar - Reinstate Monica

1
@sundar Ini tidak rumit. Jawaban ini menghitung jumlah unik (tidak bertukar tanda) seperti banyak jawaban lainnya. Setiap bit dalam k sesuai dengan jumlah. k<<nmenambahkan n ke setiap jumlah. Oring dengan kmenyimpan jumlah baru ini ksementara menyimpan semua yang sebelumnya, dan
SIM yang

Ah, jejak breacrumbs mengarah kembali ke ide bijih JungHwan Min , itu adalah wawasan utama yang saya lewatkan. Di sini setiap jumlah himpunan bagian diwakili oleh 1 pada posisi tersebut di bitstring (dengan 1 awal dalam LSB mewakili jumlah 0 untuk himpunan bagian yang kosong). Masih bukan sesuatu yang saya sebut "tidak terlalu rumit", tapi itu mungkin hanya pengalaman saya yang kurang. :)
sundar - Reinstate Monica


5

Haskell, 46 byte

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

Cobalah online!

Alih-alih menjumlahkan himpunan bagian dari daftar input, kami membuat semua kombinasi baik menyimpan nomor atau menggantinya dengan 0, misalnya

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

Ini dua byte lebih pendek dari subsequences.


Jawaban bagus! Saya berharap sesuatu seperti f x=sum[1|i<-[0..sum x],elem i$sum<$>mapM(:[0])x]akan lebih pendek dari impor, tetapi ternyata tidak.
Lynn

Bagus, bahkan lebih pendek daripada terjemahan yang Mathematica, meskipun saya pikir ini lebih cantik:import Data.List;length.foldr((<*>)union.map.(+))[0]
Jon Purdy

5

R, 83 75 byte

-8 byte berkat JayCe dan Giuseppe

Membuat matriks dari semua kemungkinan kombinasi (1, -1) untuk ukuran vektor input, gandakan dengan vektor asli untuk mendapatkan jumlah. Kemudian unik dan temukan panjang hasilnya.

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


versi sebelumnya:

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

Tidak dikoleksi dengan komentar:

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
  }

Simpan beberapa byte dengan t: TIO
JayCe

dan sum(v|1)byte lebih pendek darilength(v)
Giuseppe

4

Oktaf / MATLAB, 45 41 40 byte

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

Input adalah vektor kolom (menggunakan ; sebagai pemisah).

Kode kesalahan untuk kasus uji terakhir karena pembatasan memori.

Ini menggunakan ide dari jawaban JungHwan Min (himpunan bagian alih-alih tanda bolak-balik) untuk menyimpan beberapa byte.

Cobalah online!



3

Python 3 , 61 byte

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

Cobalah online!

Pendekatan rekursif, melacak jumlah subset unik.

Asyiknya adalah ini berdetak itertoolsdengan margin besar:

76 byte

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

Cobalah online!



3

Attache , 29 byte

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

Cobalah online!

Ini berfungsi dengan melipat ±operator di atas daftar input, lalu mengambil± daftar itu, lalu menghitung atom unik array.

Berikut beberapa contoh cara kerja lipat:

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]

Lalu kami menghasilkan semua permutasi dari tanda akhir dengan menerapkan PlusMinus sekali lagi.

Versi yang lebih efisien, 31 byte

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

Cobalah online! Ini tidak habis waktu pada kasus uji akhir, karena tidak menghasilkan kombinasi yang tidak perlu.


3

R , 62 byte

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

Cobalah online!

Algoritma Ports Dennis. Ini paling dekat dengan jawaban Octave / MATL karena menggunakan produk bitmap dan matriks yang sama untuk inklusi / pengecualian istilah.







2

Utilitas Bash + GNU, 49 byte

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

Cobalah online!

Input diberikan sebagai daftar yang dipisahkan koma pada baris perintah.

Penjelasan

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

bahasa mesin x86_64 untuk Linux, 31 29 byte

 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

Cobalah online!

Terinspirasi oleh jawaban xnor. Membutuhkan mesin dengan POPCNTinstruksi.



1

APL (Dyalog Classic) , 34 33 32 byte

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

Cobalah online!

Terima kasih kepada @ngn untuk -1 byte!


1-⍨≢⍵->≢1↓⍵
ngn

+.×⍨->+.×
ngn

Yang terakhir tidak bekerja, saya khawatir.
Zacharý

oops, saya tidak tahu mengapa saya pikir Anda menerapkan +. × pada vektor ... maaf
ngn

1

Bersihkan , 82 byte

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

Cobalah online!

Menentukan fungsi yang ? :: [Int] -> Intdigunakan f :: [Int] -> ([Int] -> Int)sebagai penolong untuk mengurangi setiap jumlah yang mungkin setelah penambahan atau pengurangan.


Inilah versi referensi solusi referensi di Haskell; tidak yakin berapa banyak yang bisa terbawa ke Clean tetapi Anda mungkin bisa mendapatkan sesuatu darinya.
Buah Esolanging

@EsolangingFruit Terima kasih, tetapi sudah menggunakan pendekatan yang sama dan saya tidak dapat menemukan cara untuk mempersingkat bahkan dengan solusi referensi yang dip Golf.
Kamis

1

APL (Dyalog Classic) , 21 byte

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

Cobalah online!

Penjelasan

2(⍴⍨⊤∘⍳*)⍴

Fungsi kereta setara dengan {((⍴⍵)⍴2)⊤⍳(⍴⍵)} , yang menghasilkan matriks yang memiliki representasi biner dari 0 hingga panjang input sebagai kolom

1-2×

Peta 1s ke -1s dan 0s ke 1s

⊢+.×

Perkalian matriks dengan input, yang memberikan array dari semua jumlah yang mungkin

⍴∘∪

Hapus duplikat, lalu hitung


1

Java 8, 207 83 44 byte

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

Port of @ xnor's Python 2 menjawab .
-39 byte terima kasih kepada @Jakob .

Cobalah online .

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
44 byte adalah yang kita butuhkan! Mengambil aliran Long: s->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e)).
Jakob

@ Jakob Terima kasih! Saya selalu lupa tentang .reduce(dan .bitCountjuga saya bisa menambahkan ..>.>) -39 byte di sana! :)
Kevin Cruijssen

1
Saya juga baru saja membuat versi presisi sembarang . Sepertinya cara termurah untuk melakukannya masih dengan bitmap daripada set.
Jakob

1

Java 8, 85 byte

Port Java lain dari jawaban xnor . Seperti jawaban asli, ini menggunakan bitmap presisi sembarang sehingga tidak ada batas atas pada ukuran jumlah subset.

Ini lambda dari sekuensial java.util.stream.Stream<Integer>ke int.

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

Cobalah secara Online

Perhatikan bahwa penggabung (argumen ketiga ke reduce) tidak digunakan karena aliran berurutan. Fungsi yang saya pilih adalah arbitrer.


1

Julia 0,6 , 54 52 byte

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

Cobalah online!

( -2 byte dengan mengganti ¬dengan ~, terima kasih kepada Jo King )

Berfungsi untuk semua kasus uji. Manfaatkan siaran untuk mengumpulkan semua jumlah yang mungkin, lalu hitung.

Penjelasan:

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

Solusi yang lebih lama:

Julia 0,6 , 64 byte

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

Cobalah online!

Bekerja untuk array input dengan panjang hingga 63 (jadi tidak bekerja untuk kasus uji terakhir, yang baik-baik saja menurut OP).

Penjelasan:

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 Node) , 64 byte

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

Cobalah online!

Ini tidak akan berfungsi untuk testcase terakhir.


Solusi yang lebih efektif (bekerja pada testcase terakhir):

JavaScript (Babel Node) , 71 byte

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

Cobalah online!


Ini tidak akan berfungsi di browser yang sebenarnya karena Array#smoosh.

Terima kasih kepada Bubbler, [x+f,x-f]-> [x+f,x]menghemat 2 byte.


Anda dapat menggunakannya [x+f,x]sebagai pengganti [x+f,x-f]( bukti oleh JungHwan Min ).
Bubbler

+2 byte untuk versi ES6: F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size
Neil

@Neil, dan ... [...s,...s.map(x=>x+f)],, s.concat(s.map(x=>x+f))dan, s,s.map(x=>s.push(x+f))berbagi panjang yang sama ...
tsh

0

Merah , 73 byte

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

Port of Dennis 'Python 2 menjawab. Tidak menangani test case terakhir.

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.