Pilih dari set bobot yang ada untuk membuat jumlah target

9

Saat melakukan angkat besi, saya ingin membuat berat tertentu dengan menempelkan beberapa piring ke bar.

Saya memiliki piring berikut:

  • 6 piring masing-masing 1 kg
  • 6 piring masing-masing 2,5 kg
  • 6 piring masing-masing 5 kg
  • 6 piring masing-masing 10 kg

Bar itu sendiri berbobot 10 kg.

Ini hanya diperbolehkan untuk menempelkan pelat secara berpasangan - mereka dipasang di setiap ujung bar, dan pengaturan di kedua ujungnya harus benar-benar simetris (mis. Melampirkan dua piring 5 kg di satu ujung, dan satu piring 10 kg di ujung lainnya dilarang karena alasan keamanan).

Buatlah program atau fungsi yang memberi tahu saya berapa banyak piring dari masing-masing jenis yang harus saya gunakan untuk mendapatkan berat total yang diberikan. Input bilangan bulat lebih besar dari 11; outputnya adalah daftar / array / string 4 angka. Jika tidak mungkin untuk menggabungkan pelat yang ada untuk mendapatkan bobot target, output array nol / kosong, string yang tidak valid, melempar pengecualian atau semacamnya.

Jika ada beberapa solusi, kode harus hanya menghasilkan satu (jangan membuat pengguna memilih - dia terlalu sibuk dengan hal-hal lain).

Kasus uji:

12 -> [2 0 0 0] - 2 plates of 1 kg plus the bar of 10 kg
13 -> [0 0 0 0] - a special-case output that means "impossible"
20 -> [0 0 2 0] - 2 plates of 5 kg + bar
20 -> [0 4 0 0] - a different acceptable solution for the above
21 -> [6 2 0 0] - 6 plates of 1 kg + 2 plates of 2.5 kg + bar
28 -> [0 0 0 0] - impossible
45 -> [0 2 6 0] - a solution for a random number in range
112 -> [2 4 6 6] - a solution for a random number in range
121 -> [6 6 6 6] - maximal weight for which a solution is possible

Jika kode Anda menampilkan angka-angka dalam urutan yang berlawanan (dari plat berat ke yang ringan), harap tentukan ini secara eksplisit untuk menghindari kebingungan.

anatolyg
sumber
1
Bukankah ini merupakan duplikat dari pertanyaan penghitungan koin minimum ? Saya tidak berpikir algoritma serakah yang sama gagal, kecuali dengan pembatasan 6 dari satu jenis pelat. Saya pikir itu mungkin bukan perbedaan yang cukup, tetapi saya tidak yakin.
FryAmTheEggman
1
Algoritma serakah tidak bekerja (bukan tanpa modifikasi, setidaknya) persis karena jumlahnya terbatas
anatolyg
Terkait , tetapi yang satu itu ASCII
AdmBorkBork
Ya, alasan saya memposting adalah karena saya tidak yakin bahwa modifikasi itu cukup signifikan. Saya memposting untuk mencoba mendapatkan umpan balik komunitas, dan saya akan menghapus komentar saya jika sepertinya komunitas tidak setuju dengan saya.
FryAmTheEggman
Bisakah kita mengeluarkan semua solusi, bukan hanya satu?
Luis Mendo

Jawaban:

5

Jelly , 22 byte

4ṗạµ×2,5,10,20S€+⁵iƓịḤ

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

4ṗạµ×2,5,10,20S€+⁵iƓịḤ  Main link. No arguments

4                       Set the left argument and initial return value to 4.
 ṗ                      Take the Cartesian power of [1, 2, 3, 4] and 4, i.e.,
                        generate all 4-tuples of integers between 1 and 4.
  ạ                     Take the absolute difference of all integers in the
                        4-tuples and the integer 4. This maps [1, 2, 3, 4] to
                        [3, 2, 1, 0] and places [0, 0, 0, 0] at index 0.
   µ                    Begin a new, monadic chain. Argument: A (list of 4-tuples)
     2,5,10,20          Yield [2, 5, 10, 20].
    ×                   Perform vectorized multiplication with each 4-tuple in A.
              S€        Sum each resulting 4-tuple.
                +⁵      Add 10 to each sum.
                   Ɠ    Read an integer from STDIN.
                  i     Find its first index in the array of sums (0 if not found).
                     Ḥ  Unhalve; yield the list A, with all integers doubled.
                    ị   Retrieve the 4-tuple at the proper index.
Dennis
sumber
6

MATL , 29 28 byte

4t:qEZ^!"[l2.5AX]@Y*10+G=?@.

Untuk input yang tidak memiliki solusi ini menghasilkan output kosong (tanpa kesalahan).

Cobalah online!

Penjelasan

4           % Push 4
t:q         % Duplicate 4 and transform into range [0 1 2 3]
E           % Multiply by 2: transform into [0 2 4 6]
Z^          % Cartesian power. Each row is a "combination" of the four numbers
!           % Transpose
"           % For each column
  [l2.5AX]  %   Push [1 2.5 5 10]
  @         %   Push current column
  Y*        %   Matrix multiply. Gives sum of products
  10+       %   Add 10
  G=        %   Compare with input: are they equal?
  ?         %   If so
    @       %     Push current column, to be displayed
    .       %     Break loop
            %   Implicit end
            % Implicit end
            % Implicit display
Luis Mendo
sumber
5

Mathematica, 70 byte

Select[FrobeniusSolve[{2,5,10,20},2#-20],AllTrue[EvenQ@#&&#<7&]][[1]]&

Fungsi anonim. Mengambil nomor sebagai input, dan mengeluarkan daftar atau kesalahan dan kembali {}[[1]]jika tidak ada solusi.

LegionMammal978
sumber
4

Jelly, 25 byte

×2,5,10,20S+⁵⁼³
4ṗ4’ÇÐfḢḤ

Coba di sini.

Lynn
sumber
2,5,10,20->2,5,⁵,20
Leaky Nun
sungguh ... bukan ,angka dua? Seluruh hidup saya bohong
Leaky Nun
@ LeakyNun ,adalah angka dua, tetapi juga dapat digunakan untuk literal. 2,5,⁵,20bukan literal ( 2,5dan 20, tapi ,, dan ,atom), jadi Anda perlu sesuatu untuk menggabungkan tautan.
Dennis
3

Python 3, 112 byte

lambda n:[i for i in[[i//4**j%4*2for j in range(4)]for i in range(256)]if i[0]+2.5*i[1]+5*i[2]+10*i[3]+10==n][0]

Fungsi anonim yang mengambil input, melalui argumen, dari massa target dan mengembalikan jumlah setiap lempeng sebagai daftar. Jika tidak ada solusi, kesalahan akan terjadi. Ini adalah kekuatan kasar murni.

Bagaimana itu bekerja

lambda n                                   Anonymous function with input target mass n
...for i in range(256)                     Loop for all possible arrangement indices i
[i//4**j%4*2for j in range(4)]             Create a base-4 representation of the index i,
                                           and multiply each digit by 2 to map from
                                           (0,1,2,3) to (0,2,4,6)
[...]                                      Package all possible arrangements in a list
...for i in...                             Loop for all possible arrangements i
i...if i[0]+2.5*i[1]+5*i[2]+10*i[3]+10==n  Return i if it gives the target mass
[...]                                      Package all solutions in a list
:...[0]                                    Return the first list element. This removes any
                                           multiple solutions, and throws an error if there
                                           being no solutions results in an empty list

Cobalah di Ideone

TheBikingViking
sumber
2

Brachylog , 50 byte

,L##l4,L:{.~e[0:3]}a:[2:5:10:20]*+:10+?,L:{:2*.}a.

Kembali falseketika tidak memungkinkan.

Fatalisasi
sumber
1

Pyth, 34 31 25 byte

h + fqQ +; s * VT [1 2.5 5;) yMM ^ U4 4] * 4] 0 
yMh + fqQ +; s * VT [2 5; y;) ^ U4 4] * 4] 0
yMhfqQ +; s * VT [2 5; y;) ^ U4 4

Suite uji.

Kesalahan dalam ketidakmungkinan.

Ini pada dasarnya adalah kekuatan kasar.

Ini cukup cepat, karena hanya ada 256 pengaturan yang memungkinkan.

Biarawati Bocor
sumber
1

Scala, 202 byte

Memutuskan Scala tidak mendapatkan banyak cinta di sini, jadi saya menyajikan solusi (mungkin tidak optimal) di Scala.

def w(i:Int){var w=Map(20->0,10->0,5->0,2->0);var x=i-10;while(x>0){
var d=false;for(a<-w.keys)if(a<=x & w(a)<6 & !d){x=x-a;w=w.updated(a,w(a)+2);d=true;}
if(!d){println(0);return;}}
println(w.values);}

Output program dalam urutan terbalik dan dengan sampah tambahan dibandingkan dengan solusi dalam posting. Ketika solusi tidak ditemukan, cetak 0.

Catatan: Saya tidak dapat menghapus baris atau spasi baru karena Scala bodoh, jadi saya pikir untuk mengurangi ukuran, metode harus diulang kecuali saya melewatkan sesuatu yang jelas.

ejaszewski
sumber
1

APL, 40 byte

{2×(4⍴4)⊤⍵⍳⍨10+2×,⊃∘.+/↓1 2.5 5 10∘.×⍳4}

Dalam ⎕IO ← 0. Dalam Bahasa Inggris:

  1. 10+2×,∘.+⌿1 2.5 5 10∘.×⍳4: membangun array dari semua bobot yang mungkin, dengan menghitung jumlah luar 4D dari berat per jenis berat;
  2. ⍵⍳⍨: cari indeks yang diberikan. Jika tidak ditemukan indeksnya adalah 1 + jumlah array pada langkah 1;
  3. (4⍴4)⊤: mewakili indeks pada basis 4, yaitu, menghitung koordinat bobot yang diberikan dalam ruang 4D;
  4. : membawa hasilnya ke ruang masalah, di mana koordinat harus ditafsirkan sebagai setengah dari jumlah pelat.

Contoh: {2 × (4⍴4) ⊤⍵⍳⍨10 + 2 ×, ⊃∘. + / ↓ 1 2.5 5 10∘. × ⍳4} 112 2 4 6 6

Bonus : karena APL adalah bahasa array, beberapa bobot dapat diuji sekaligus. Dalam hal ini hasilnya dialihkan:

      {2×(4⍴4)⊤⍵⍳⍨10+2×,⊃∘.+/↓1 2.5 5 10∘.×⍳4}12 13 20 21 28 45 112 121
2 0 0 6 0 0 2 6
0 0 0 2 0 2 4 6
0 0 2 0 0 2 6 6
0 0 0 0 0 2 6 6
lstefano
sumber
1

JavaScript (ES6), 109 byte

n=>`000${[...Array(256)].findIndex((_,i)=>i+(i&48)*9+(i&12)*79+(i&3)*639+320==n*32).toString(4)*2}`.slice(-4)

Pengembalian 00-2kesalahan. Solusi alternatif yang mengembalikan undefinedkesalahan, juga 109 byte:

n=>[...Array(256)].map((_,i)=>`000${i.toString(4)*2}`.slice(-4)).find(s=>+s[0]+s[1]*2.5+s[2]*5+s[3]*10+10==n)
Neil
sumber