Bretter stapeln

11

Ich habe ein paar Bretter, die ich auf kleinstem Raum stapeln muss. Leider fallen die Bretter um, wenn ich sie mehr als 10 hoch staple. Ich brauche ein Programm, das mir sagt, wie man die Bretter stapelt, um so wenig horizontalen Platz wie möglich einzunehmen, ohne Bretter mit einer Höhe von mehr als zehn zu stapeln oder Bretter über dem leeren Raum hängen zu lassen.

Deine Aufgabe:

Schreiben Sie ein Programm oder eine Funktion, die bei einem Array mit den Längen der Karten die ASCII-Kunst ausgibt, um die Karten zu stapeln, um so viel horizontalen Platz wie möglich zu sparen, ohne die Karten mehr als 10 hoch zu stapeln oder einen Teil davon zu haben Brett hängt über leerem Raum. Ihre ASCII-Grafik sollte die Konfiguration der Karten zeigen, wobei jede mit einem anderen Zeichen dargestellt wird. Es gibt maximal 20 Boards. Wenn die Eingabe beispielsweise [2,2,4,2,2,4,4,4] war, ist eine mögliche Ausgabe:

dhh
dgg
dff
dee
abc
abc
abc
abc

Dies ist eine stabile Konfiguration (obwohl dies im wirklichen Leben in ~ 0,1 Sekunden umfallen würde).

Eingang:

Ein Array mit bis zu 20 Ganzzahlen, das die Länge der Karten anzeigt.

Ausgabe:

ASCII-Grafik zeigt die oben beschriebenen Konfigurationen der Karten.

Testfälle:

Beachten Sie, dass es möglicherweise andere Lösungen für die Testfälle gibt und die für jede Karte angezeigten Zeichen unterschiedlich sein können.

[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

Wertung:

Dies ist , niedrigste Punktzahl in Bytes gewinnt

Greif
quelle

Antworten:

3

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

Unglaublich schlechte Laufzeit, wird irgendwann enden

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]

Probieren Sie es online aus!

Bearbeiten: - 2 -8 Bytes dank @Mr. Xcoder Edit: -8 Bytes dank @notjagan

Erläuterung

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 Bytes

Für einige Testfälle tatsächlich auf TIO ausführbar

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]

Probieren Sie es online aus!

Beide Lösungen könnten wahrscheinlich ziemlich viel Golf spielen.

Halvard Hummel
quelle
483 Bytes
Mr. Xcoder
Mr. Xcoder, der zweite kann um fast 50 Bytes reduziert werden. Ich habe die Änderungen für den ersten nur nicht auf den zweiten angewendet
Halvard Hummel
Ich weiß, dass der zweite viel Golf spielen kann, aber die Änderungen am ersten sollten hilfreich sein.
Mr. Xcoder
1
Sie haben meine Gegenstimme für einen großartigen Code mit einer wunderbaren Erklärung verdient, der viel Mühe und Gedanken zeigt. Herzlichen Glückwunsch und willkommen bei PPCG!
Mr. Xcoder