Papan Stackin

11

Saya memiliki banyak papan yang saya butuhkan untuk menumpuk di ruang sekecil mungkin. Sayangnya, papan jatuh jika saya menumpuk lebih dari 10 tinggi. Saya membutuhkan program untuk memberi tahu saya cara menumpuk papan untuk mengambil ruang horizontal sesedikit mungkin, tanpa menumpuk papan lebih dari sepuluh tinggi, atau meminta papan menggantung di ruang kosong.

Tugas Anda:

Tulis sebuah program atau fungsi, yang ketika diberi larik yang berisi panjang papan, menghasilkan ASCII sebagai cara untuk menumpuk papan untuk menghemat ruang horizontal sebanyak mungkin, tanpa menumpuk papan lebih dari 10 tinggi atau memiliki bagian apa pun dari setiap papan. papan nongkrong di ruang kosong. Seni ASCII Anda harus menunjukkan konfigurasi papan, dengan masing-masing ditampilkan menggunakan karakter yang berbeda. Akan ada maksimal 20 papan. Misalnya, jika inputnya [2,2,4,2,2,4,4,4], kemungkinan output adalah:

dhh
dgg
dff
dee
abc
abc
abc
abc

yang merupakan konfigurasi yang stabil (meskipun ini akan jatuh dalam ~ 0,1 detik dalam kehidupan nyata).

Memasukkan:

Array berisi hingga 20 bilangan bulat, yang menunjukkan panjang papan.

Keluaran:

Seni ASCII menunjukkan konfigurasi papan, seperti diuraikan di atas.

Kasus uji:

Perhatikan bahwa mungkin ada solusi lain untuk kasus uji, dan karakter yang ditunjukkan untuk setiap papan mungkin berbeda.

[12,2,2,2,3,4,4,8,8]        -> ffgghhiii
                               ddddeeeeeeee
                               bbbbbbbbcccc
                               aaaaaaaaaaaa

[4,4,4,4,4,4,4,4,4,4,4,4]   -> llll
                               aaaa
                               cfghk
                               cfghk
                               cfghk
                               cfghk
                               debij
                               debij
                               debij
                               debij

[4,4,4,4,4,4,3,3,3,2,2,2,1] -> jjml
                               iiil
                               hhhk
                               gggk
                               ffff
                               eeee
                               dddd
                               cccc
                               bbbb
                               aaaa

Mencetak:

Ini adalah , skor terendah dalam byte yang menang

Gryphon
sumber

Jawaban:

3

Python 3 , 513 512 511 509 499 497 485 465 459 458 444 byte

Runtime yang sangat buruk, akan selesai di beberapa titik

e,j,c=enumerate,len,range
def f(n,p=[],o=97):
    r,l,m=lambda x:min(b,f(n[:i]+n[i+1:],x,o+1),key=j),chr(o),j(p)
    b=[p,l*(sum(n)*2+m)][n>[]]
    for i,a in e(n):
        for h,d in e(p):
            if a<11-j(d):b=r([p[f]+l*a*(f==h)for f in c(m)])
            if(j(d)<10)*all(j(x)==j(d)for x in p[h:h+a])*(a<=m-h):b=r([p[f]+l*(h<=f<h+a)for f in c(m)])
        if a<11:b=r(p+[l*a])
        b=r(p+[l]*a)
    return["\n".join("".join(9-u<j(x)and x[9-u]or" "for x in b)for u in c(10)),b][o>97]

Cobalah online!

Sunting: - 2 -8 byte berkat @Mr. Edit Xcoder : -8 bytes berkat @notjagan

Penjelasan

e,j,c=enumerate,len,range      
         # These built-ins are used a lot
def f(n,p=[],o=97):
         # n is the remaining blocks
         # p is the current stack
         # o is the ASCI code for the next letter to use
    r,l,m=lambda x:min(b,f(n[:i]+n[i+1:],x,o+1),key=j),chr(o),j(p)
         # r is the recursive call, that also selects the smallest stack found
         # l is the letter to use next
         # m is the length of the current stack
    b=[p,l*(sum(n)*2+m)][n>[]]
         # Sets the current best, if there are no remaining blocks, select the found stack, else we set it to be worse than the possible worst case
    for i,a in e(n):
         # Loop through all the remaining blocks
        for h,d in e(p):
         # Loop through all the columns in the current stack
            if a<11-j(d):b=r([p[f]+l*a*(f==h)for f in c(m)])
         # If we can place the current block vertically in the current column, try it
            if(j(d)<10)*all(j(x)==j(d)for x in p[h:h+a])*(a<=m-h):b=r([p[f]+l*(h<=f<h+a)for f in c(m)])
         # If we can place the current block horizontally starting in the current column, try it
        if a<11:b=r(p+[l*a])
         # If the current block is lower than 10, try place it vertically to the right of the current stack
        b=r(p+[l]*a)
         # Try to place the current horizontally to the right of the current stack
    return["\n".join("".join(9-u<j(x)and x[9-u]or" "for x in b)for u in c(10)),b][o>97]
         # Return the best choice if we aren't in the first call to the function, that is the next letter is a. Else return the found best option formatted as a string

Python 3 , 587 byte

Sebenarnya bisa dijalankan pada TIO untuk beberapa kasus uji

e,j,c=enumerate,len,range
def f(n,p=[],o=97,b=[]):
    if(not n):return p
    if not b:b="a"*sum(n)*2
    r,q,s,l,m=lambda x:q(f(n[:i]+n[i+1:],x,o+1,b)),lambda x:[b,x][j(b)>j(x)],b,chr(o),j(p)
    if j(b)<=m:return b
    for i,a in e(n):
        for h,d in e(p):
            if a<11-j(d):b=r([p[f]+l*a*(f==h)for f in c(m)])
            if j(d)<10 and a<=m-h and all(map(lambda x:j(x)==j(d),p[h:h+a])):b=r([p[f]+l*(h<=f<h+a)for f in c(m)])
        if s==b:
            if a<11and m+1<j(b):b=r(p[:]+[l*a])
            if m+a<j(b):b=r(p[:]+[l for r in c(a)])
    return["\n".join("".join(map(lambda x:" "if u>=j(x)else x[u],b))for u in c(9,-1,-1)),b][o>97]

Cobalah online!

Kedua solusi itu mungkin bisa sedikit golf.

Halvard Hummel
sumber
483 bytes
Mr. Xcoder
Tn. Xcoder, yang kedua dapat dikurangi hingga hampir 50 byte, saya baru saja tidak menerapkan perubahan untuk yang pertama ke yang kedua
Halvard Hummel
Saya tahu yang kedua bisa banyak bermain golf, tetapi perubahan yang pertama harus membantu.
Tn. Xcoder
1
Anda mendapatkan upvote saya, untuk beberapa kode hebat dengan penjelasan yang luar biasa, yang menunjukkan banyak usaha dan pemikiran. Selamat dan selamat datang di PPCG!
Tn. Xcoder