Tablice układania

11

Mam kilka desek, które muszę układać na możliwie najmniejszej przestrzeni. Niestety plansze przewracają się, jeśli ułożę je w stosy o więcej niż 10. Potrzebuję programu, który powie mi, jak układać deski w stosy, aby zajmować jak najmniej przestrzeni poziomej, bez układania desek w stosy o wysokości większej niż dziesięć lub bez zawieszania desek nad pustą przestrzenią.

Twoje zadanie:

Napisz program lub funkcję, która, gdy otrzyma tablicę zawierającą długości desek, generuje w formacie ASCII sposób układania desek w stos, aby zaoszczędzić jak najwięcej przestrzeni poziomej, bez układania desek w stos powyżej 10 lub bez jakiejkolwiek części dowolnej tablica wisząca nad pustą przestrzenią. Twoja grafika ASCII powinna pokazywać konfigurację plansz, przy czym każda z nich ma inną postać. Będzie maksymalnie 20 plansz. Na przykład, jeśli dane wejściowe to [2,2,4,2,2,4,4,4], możliwe dane wyjściowe to:

dhh
dgg
dff
dee
abc
abc
abc
abc

która jest stabilną konfiguracją (chociaż w rzeczywistości spadłaby w ciągu ~ 0,1 sekundy).

Wejście:

Tablica zawierająca do 20 liczb całkowitych, pokazująca długości płyt.

Wynik:

Grafika ASCII przedstawiająca konfiguracje płyt, jak opisano powyżej.

Przypadki testowe:

Zauważ, że mogą być inne rozwiązania dla przypadków testowych, a znaki pokazane dla każdej planszy mogą być inne.

[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

Punktacja:

To jest , najniższy wynik w bajtach wygrywa

Gryf
źródło

Odpowiedzi:

3

Python 3 , 513 512 511 509 499 497 485 465 459 458 444 bajtów

Niesamowicie zły czas działania, w pewnym momencie zakończy się

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]

Wypróbuj online!

Edycja: - 2 -8 bajty dzięki @Mr. Xcoder Edit: -8 bajtów dzięki @notjagan

Wyjaśnienie

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 bajtów

Właściwie działający na TIO dla niektórych przypadków testowych

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]

Wypróbuj online!

Oba rozwiązania można by prawdopodobnie trochę pograć w golfa.

Halvard Hummel
źródło
483 bajty
Mr. Xcoder,
583 bajtów na drugi
Mr. Xcoder,
Panie Xcoder, drugi można zmniejszyć o prawie 50 bajtów, po prostu nie zastosowałem zmian dla pierwszego do drugiego
Halvard Hummel
Wiem, że na drugim można dużo grać w golfa, ale zmiany w pierwszym powinny być pomocne.
Pan Xcoder,
1
Zasłużyłem na moją opinię, za świetny kod ze wspaniałym wyjaśnieniem, który pokazuje wiele wysiłku i przemyślenia. Gratulacje i witamy w PPCG!
Pan Xcoder,