Membagi array dan program menjadi dua

10

pengantar

Anda telah ditugaskan untuk menulis sebuah program yang membagi array integer persegi panjang menjadi dua (untuk alasan apa pun). Tugas ini intensif secara komputasi, tetapi untungnya Anda memiliki mesin dual-core untuk melakukan perhitungan. Untuk memaksimalkan manfaat paralelisme, Anda memutuskan untuk membagi program secara merata menjadi dua dan membiarkan setiap inti menjalankan salah satu bagian secara terpisah.

Masukan dan keluaran

Input Anda adalah array 2D persegi panjang dari bilangan bulat negatif dengan ukuran minimal 1 × 1 , yang diambil dalam format apa pun yang masuk akal. Sebuah membelah dari array tersebut diperoleh dengan memisahkan setiap baris horisontal menjadi awalan dan akhiran (baik dari yang mungkin kosong). Agar pemisahan dapat valid, dua baris yang berdekatan harus dipisah pada indeks yang sama atau indeks yang berdekatan. Sebagai contoh, pertimbangkan array

2 4 5 5 6 3
9 7 1 7 7 0
0 0 3 6 7 8
1 2 4 7 6 1
6 6 8 2 0 0

Ini adalah pemisahan yang valid:

 2;4 5 5 6 3
;9 7 1 7 7 0
;0 0 3 6 7 8
 1;2 4 7 6 1
 6 6;8 2 0 0

Ini juga pemisahan yang valid:

2 4 5 5 6 3;
9 7 1 7 7;0
0 0 3 6 7;8
1 2 4 7;6 1
6 6 8;2 0 0

Ini bukan pemisahan yang valid:

2 4;5 5 6 3
9 7 1;7 7 0
0;0 3 6 7 8
1 2;4 7 6 1
6 6;8 2 0 0

Output Anda akan menjadi nilai minimum

abs(sum_of_prefixes - sum_of_suffixes)

atas semua pemisahan input yang valid.

Aturan dan penilaian

Anda harus menulis dua program (baik program lengkap atau fungsi) dalam bahasa yang sama, yang tidak boleh memiliki kode bersama di antara mereka. Sebut saja P1 dan P2 . Program P1 mengambil array input, dan mengeluarkan sesuatu . Program P2 mengambil sesuatu sebagai input, dan mengeluarkan jawaban dari tugas di atas untuk array input.

Skor Anda adalah jumlah byte P1 dan P2 maksimum , skor yang lebih rendah lebih baik.

Beberapa klarifikasi:

  • Anda dapat menulis dua prorgam penuh, satu fungsi dan satu program penuh, atau dua fungsi.
  • Dalam kasus dua program penuh, seluruh output P1 diumpankan ke P2 sebagai input, seperti dalam pipa Unix P1 | P2. Program harus berfungsi dengan benar jika dikompilasi / ditafsirkan dari dua file sumber terpisah.
  • Jika salah satu program adalah fungsi, itu dikonversi ke program penuh dengan menambahkan kode boilerplate yang diperlukan, dan aturan di atas diterapkan padanya. Secara khusus, dua fungsi tidak dapat menggunakan fungsi bantu bersama, pernyataan impor bersama, atau variabel global bersama.

Uji kasus

[[1]] -> 1
[[4,5],[8,3]] -> 4
[[8],[11],[8],[10],[4]] -> 1
[[5,7,0,9,11,2,1]] -> 7
[[146,194,71,49],[233,163,172,21],[121,173,14,302],[259,169,26,5],[164,30,108,37],[88,55,15,2]] -> 3
[[138,2,37,2],[168,382,33,77],[31,199,7,15],[192,113,129,15],[172,88,78,169],[28,6,97,197]] -> 7
[[34,173,9,39,91],[169,23,56,74,5],[40,153,80,60,28],[8,34,102,60,32],[103,88,277,4,2]] -> 0
[[65,124,184,141],[71,235,82,51],[78,1,151,201],[12,24,32,278],[38,13,10,128],[9,174,237,113]] -> 2
[[164,187,17,0,277],[108,96,121,263,211],[166,6,57,49,73],[90,186,26,82,138],[173,60,171,265,96]] -> 8
Zgarb
sumber
Untuk sesaat, saya pikir ini adalah pertanyaan multi-threading . Saya sudah menantikan lebih dari itu.
Adám

Jawaban:

2

Haskell, 102 byte

Fungsi 1 (102 byte):

l=length
[]#i=[[]]
(r:s)#i=id=<<[(splitAt j r:)<$>s#j|j<-[i-1..i+1],j>=0,j<l r]
f r=(r#)=<<[0..l$r!!0]

Fungsi 2 (90 byte):

g::[[([Int],[Int])]]->Int 
g a=minimum$map(\(x,y)->abs$sum(sum<$>x)-sum(sum<$>y))$unzip<$>a

Hilang boilerplate untuk F1 untuk menjadikannya program penuh, termasuk array integer hardcoded untuk memeriksa:

main = print $ f [[164,187,17,0,277],[108,96,121,263,211],[166,6,57,49,73],[90,186,26,82,138],[173,60,171,265,96]]

dan untuk F2:

main = print . g . read =<< getContents

Sekarang Anda dapat memanggil runhaskell f1.hs | runhaskell f2.hsoutput mana 8.

Cara kerjanya: fmengambil daftar daftar bilangan bulat.

f r = (r#)=<<[0..l$r!!0]          -- for each index [0 .. length r] call # with
                                  -- the first parameter being r and
                                  -- collect the results in a single list

[]#i=[[]]                         -- base case. If the list of lists is empty, stop
(r:s)#i                           -- else let r be the first list, s all others
           j<-[i-1..i+1],         -- foreach possible index j for the next line
                 j>=0,j<l r       --    (skipping out of range indices)
     (splitAt j r:)<$>            -- split the current line at j into a pair of
                                  -- lists and prepend it to every element of
                      s#j         -- a recursive call with s and j
id=<<                             -- flatten into a single list

Sekarang kita memiliki daftar semua kemungkinan perpecahan, misalnya yang pertama dan yang acak dari tengah

[([],[164,187,17,0,277]),                  [([164,187],[17,0,277]),
 ([],[108,96,121,263,211]),                 ([108,96],[121,263,211]),
 ([],[166,6,57,49,73]),                     ([166],[6,57,49,73]),
 ([],[90,186,26,82,138]),                   ([90,186],[26,82,138]),
 ([],[173,60,171,265,96])]                  ([173,60,171],[265,96])]

Fungsi gmengambil daftar seperti itu dan

                    unzip<$>a       -- turn every pair of lists into a list of pairs
  map(\(x,y)->                      -- foreach such pair     
      abs$sum(sum<$>x)-sum(sum<$>y) -- calculate the score
minimum                             -- and find the minimum

Catatan: fungsi kedua dapat di-golf sedikit lebih, tetapi tidak mengubah skor.

nimi
sumber