Regangkan sebuah array

13

Sebelumnya saya mendefinisikan proses penghancuran array

Dalam naksir kita membaca array kiri ke kanan. Jika pada suatu titik kita menemukan dua elemen yang sama dalam satu baris, kita menghapus yang pertama dan menggandakan yang kedua.

Sebagai contoh di sini adalah proses menghancurkan array berikut

[5,2,2,4]
 ^
[5,2,2,4]
   ^
[5,2,2,4]
     ^
[5,4,4]
   ^
[5,4,4]
     ^
[5,8]
   ^

Perhatikan bahwa elemen yang sama dapat diciutkan beberapa kali. Dalam contoh 2,2,4itu runtuh menjadi 8dalam satu pass.

Sekarang menghancurkan array itu mudah, yang sulit adalah menghancurkannya. Tugas Anda adalah mengambil array bilangan bulat positif sebagai input dan output array terbesar yang dapat membentuk input ketika dihancurkan berulang kali. Misalnya array [4]dibentuk dengan menghancurkan [2,2]yang pada gilirannya dibentuk oleh menghancurkan [1,1,1,1]. Karena kita tidak dapat memiliki nilai [1,1,1,1]- nilai non integer tidak dapat dihapus lebih lanjut dan dengan demikian adalah jawaban kami.

Anda tidak akan pernah menerima 0dalam array input Anda karena array tersebut dapat diperluas tanpa batas waktu. Anda juga tidak akan pernah menerima kasing dengan dua nomor ganjil yang sama di sebelah satu sama lain, kasing seperti itu tidak bisa merupakan hasil penghancuran.

Ini adalah sehingga jawaban akan dinilai dengan ukuran sumbernya yang diukur dalam byte dengan lebih sedikit byte yang lebih baik.

Sebelum Anda mulai menjawab, saya hanya ingin mengatakan bahwa tantangan ini jauh lebih sulit daripada yang terlihat. Periksa intuisi Anda saat Anda melanjutkan dan pastikan jawaban Anda melewati semua kasus uji.

Uji Kasus

[] -> []
[5] -> [5]
[6] -> [3,3]
[8] -> [1,1,1,1,1,1,1,1]
[4,8] -> [1,1,1,1,1,1,1,1,1,1,2]
[2,8] -> [1, 1, 1, 1, 2, 1, 1, 1, 1]
[4,4] -> [1,1,1,1,1,1,1,1]
Posting Rock Garf Hunter
sumber
1
Maaf tapi saya masih belum mengerti aturannya. mengapa [1,1,1,1,1,1,1,1,1,1,2]menghasilkan [4, 8]bukan [8, 4]? hal ini harus [1,>1,1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,>2,1,1,1,1,1,1,2], [4,1,>1,1,1,1,1,2], [4,2,1,>1,1,1,2], [4,2,>2,1,1,2], [4,>4,1,1,2], [8,1,>1,2], [8,2,>2], [8,4]?
tsh
2
@ tsh Saya pikir Anda memiliki kesalahpahaman tentang cara penghancuran bekerja. Berikut adalah jalur yang dibutuhkan lulus pertama: [1,>1,1,1,1,1,1,1,1,1,2], [2,>1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,2,>1,1,1,1,1,1,2], [2,2,1,>1,1,1,1,1,2], [2,2,2,>1,1,1,1,2], [2,2,2,1,>1,1,1,2], [2,2,2,2,>1,1,2], [2,2,2,2,1,>1,2], [2,2,2,2,2,>2], [2,2,2,2,4>], kedua pass: [2,>2,2,2,4], [4,>2,2,4], [4,2,>2,4], [4,4,>4], [4,8>]. Semoga itu jelas. Jika Anda ingin beberapa kode untuk melihat pertanyaan sebelumnya memiliki jawaban yang mengimplementasikan fungsi penghancuran.
Posting Rock Garf Hunter
Apakah boleh jika saya menampilkan angka, masing-masing dipisahkan oleh baris baru?
scottinet
@ skottinet Itu adalah cara yang masuk akal untuk menampilkan daftar. Lanjutkan.
Posting Rock Garf Hunter
Kasing uji [4, 4]harus dilepas, karena kita tidak akan pernah mendapatkan array setelah urutan stretch => crush, karena ini akan berakhir dengan[8]
Kasing scottinet

Jawaban:

2

JavaScript (Node.js) , 237 221 213 186 byte

f=a=>a.map(b=>{for(i=1;~b%2;b/=2)i*=2;return Array(i).fill(b)}).reduce((t,c,i,s)=>{b=c.slice();if(i)r=2*s[--i].length,b.length>=r&&b[0]==s[i][0]?b[r-2]+=b.pop():b;return t.concat(b)},[])

Cobalah online!

Algoritma ini menghitung susunan regangan optimal, dengan merentangkan setiap angka ke max, dan kemudian, jika perlu, itu meremukkan kembali sepasang angka di tempat yang tepat, secara efektif menciptakan "penghancur blokir", mengganggu urutan naksir dari angka sebelumnya.

Contohnya:

[1, 1, 1, 1, 1, 1]memberi [4,2]setelah dihancurkan, tetapi [1, 1, 1, 1, 2]menghasilkan[2, 4]

Tantangannya adalah menentukan di mana tepatnya penghancur blokir harus ditempatkan sehingga penghancuran array yang dihasilkan memberikan hasil yang tepat:

  • Penghambat penghancur perlu ditempatkan hanya jika nomor yang diregangkan sebelumnya sama dengan nomor saat ini, dan jika urutan yang diregangkan saat ini lebih besar daripada yang sebelumnya. Misalnya, [2, 4]membutuhkan penghancur blokir (angka yang diregangkan adalah 1, diulang, dan[1, 1] lebih pendek dari [1,1,1,1]), tetapi [4, 2]dan [2, 6]tidak memerlukan satu
  • jika kita memanggil nurutan sebelumnya, dan jika kondisi di atas diverifikasi, maka urutan saat ini adalah pengulangan nurutan. Untuk menghentikan urutan himpitan angka sebelumnya, kita perlu menempatkan penghancur blokir di akhir nurutan kedua dari angka saat ini untuk meregangkan. Contoh:, [2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]atau[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]
scottinet
sumber
1

Jelly , 42 byte

ṪḤ,⁼?⁹⁸;µ/Ḋ$¹L’$?ÐĿċ³
ṗЀ⁸ẎS⁼¥Ðfµ€ŒpẎ€ÇÐfṪ

Cobalah online!

Program lengkap. Sangat tidak efisien, tetapi berhasil.

Erik the Outgolfer
sumber
1

Python 2 , 230 228 226 byte

Bekerja dengan mengulangi semua daftar yang mungkin dengan jumlah yang sama dengan yang dimasukkan. Menghapus yang tidak sama dengan array input dalam keadaan hancur, memilih yang terpanjang.

Edit: -2 byte dengan menghapusif fungsi utama

Edit: -2 byte dengan menghapus dua tanda kurung yang tidak perlu

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]
def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)
b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

Cobalah online!

Penjelasan

Fungsi utama, bertanggung jawab untuk menemukan semua solusi yang mungkin dan memilih yang terpanjang

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]

Fungsi hancurkan, yang memeriksa apakah y sama dengan salah satu crush.

def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)

Hasilkan semua kemungkinan permutasi dengan jumlah yang diberikan

b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]
Halvard Hummel
sumber
0

05AB1E , 41 37 byte

vy[DÉ#2÷]DYQX©NoDU‹&sDV¸X∍sić·®·Íǝ}»,

Cobalah online!

Port solusi Javascript saya.

Penjelasan:

vy                   for each member of the list
[DÉ#2÷]              divide by 2 until odd: stack = stretched value, N = iterations
DYQ                  stetched value equal to the previous one?
X©NoDU‹              previous size < current one? (+store the new size in X)
&                    AND on the 2 previous tests
sDV¸X∍s              build a list of the new stretched value repeated X times
                      (+store the new stetched value in Y)
ić·®·Íǝ}             if the previous tests are true:
                       reduce the result list size by 1
                       multiply by 2 the number at the crush block position
»,                   join by newline + print the list
scottinet
sumber