บอร์ดของ Stackin


11

ฉันมีบอร์ดมากมายที่ฉันต้องการเพื่อให้มีพื้นที่น้อยที่สุดเท่าที่จะทำได้ น่าเสียดายที่กระดานล้มถ้าฉันสแต็คพวกเขามากกว่า 10 สูง ฉันต้องการโปรแกรมที่จะบอกวิธีกองซ้อนบอร์ดให้ใช้พื้นที่แนวนอนให้น้อยที่สุดเท่าที่จะทำได้โดยไม่ต้องวางบอร์ดซ้อนกันสูงกว่าสิบหรือมีกระดานแขวนอยู่เหนือพื้นที่ว่าง

งานของคุณ:

เขียนโปรแกรมหรือฟังก์ชั่นที่เมื่อกำหนดอาร์เรย์ที่มีความยาวของบอร์ดเอาต์พุตในรูปแบบ ASCII จะสามารถจัดวางบอร์ดเพื่อประหยัดพื้นที่แนวนอนได้มากที่สุดโดยไม่ต้องซ้อนบอร์ดสูงกว่า 10 หรือมีส่วนใด ๆ คณะแขวนอยู่เหนือพื้นที่ว่างเปล่า ASCII art ของคุณควรแสดงการกำหนดค่าของบอร์ดโดยแต่ละอันจะแสดงโดยใช้อักขระที่แตกต่างกัน จะมีบอร์ดได้สูงสุด 20 บอร์ด ตัวอย่างเช่นหากอินพุตเป็น [2,2,4,2,2,2,4,4,4] เอาต์พุตที่เป็นไปได้คือ:

dhh
dgg
dff
dee
abc
abc
abc
abc

ซึ่งเป็นการกำหนดค่าที่มั่นคง (แม้ว่าจะล้มลงใน ~ 0.1 วินาทีในชีวิตจริง)

การป้อนข้อมูล:

อาร์เรย์ที่มีจำนวนเต็มสูงสุด 20 รายการแสดงความยาวของกระดาน

เอาท์พุท:

ศิลปะ ASCII แสดงการกำหนดค่าของบอร์ดตามที่อธิบายไว้ข้างต้น

กรณีทดสอบ:

โปรดทราบว่าอาจมีวิธีแก้ไขปัญหาอื่น ๆ สำหรับกรณีทดสอบและอักขระที่แสดงสำหรับแต่ละบอร์ดอาจแตกต่างกัน

[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

เกณฑ์การให้คะแนน:

นี่คือคะแนนต่ำสุดเป็นไบต์ชนะ

คำตอบ:


3

Python 3 , 513 512 511 509 499 497 485 465 459 458 444 ไบต์

รันไทม์ไม่ดีอย่างไม่น่าเชื่อจะเสร็จในบางจุด

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]

ลองออนไลน์!

แก้ไข: - 2 -8 ไบต์ขอบคุณ@Mr Xcoder แก้ไข: -8 ไบต์ขอบคุณ@notjagan

คำอธิบาย

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 ไบต์

รันได้จริงบน TIO สำหรับบางกรณีทดสอบ

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]

ลองออนไลน์!

วิธีแก้ปัญหาทั้งสองอาจจะเล่นกอล์ฟได้เล็กน้อย




Mr. Xcoder คนที่สองสามารถลดลงได้เกือบ 50 ไบต์ฉันไม่ได้ใช้การเปลี่ยนแปลงสำหรับคนแรกกับคนที่สอง
Halvard Hummel

ฉันรู้ว่าตัวที่สองสามารถเล่นกอล์ฟได้มาก แต่การเปลี่ยนแปลงตัวแรกจะมีประโยชน์
Mr. Xcoder

1
คุณได้รับ upvote ของฉันสำหรับรหัสที่ยอดเยี่ยมพร้อมคำอธิบายที่ยอดเยี่ยมซึ่งแสดงให้เห็นถึงความพยายามและความคิดมากมาย ขอแสดงความยินดีและยินดีต้อนรับสู่ PPCG!
Mr. Xcoder
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.