İstif Panoları


11

Mümkün olduğunca küçük bir alanda biriktirmem gereken bir sürü tahta var. Ne yazık ki, tahtaları 10'dan fazla yükseğe yığarsam düşer. Panoları ondan fazla yüksek istiflemeden veya panoları boş alan üzerine asmadan olabildiğince az yatay alan alacak şekilde nasıl istifleyeceğimi söyleyecek bir programa ihtiyacım var.

Senin görevin:

Pano uzunluklarını içeren bir dizi verildiğinde, ASCII sanatı olarak çıktıları, panoları 10'dan fazla istiflemeden veya herhangi bir parçasına sahip olmadan mümkün olduğunca fazla yatay alandan tasarruf etmek için panoları istifleme yolunun çıktısını veren bir program veya işlev yazın. tahta üzerinde boş yer dışarı asılı. ASCII resminiz, her biri farklı bir karakter kullanılarak gösterilen panoların yapılandırmasını göstermelidir. En fazla 20 pano olacaktır. Örneğin, girdi [2,2,4,2,2,4,4,4] ise, olası bir çıktı:

dhh
dgg
dff
dee
abc
abc
abc
abc

bu kararlı bir konfigürasyon (bu gerçek hayatta ~ 0.1 saniye içinde düşmesine rağmen).

Giriş:

Kartların uzunluklarını gösteren en fazla 20 tamsayı içeren bir dizi.

Çıktı:

Yukarıda ana hatlarıyla gösterildiği gibi panoların konfigürasyonlarını gösteren ASCII sanatı.

Test Durumları:

Test senaryoları için başka çözümler olabileceğini ve her kart için gösterilen karakterlerin farklı olabileceğini unutmayın.

[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

puanlama:

Bu , bayt kazanır en düşük puan

Yanıtlar:


3

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

İnanılmaz derecede kötü çalışma süresi, bir noktada bitecek

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]

Çevrimiçi deneyin!

Düzenleme: - @ MR sayesinde 2 -8 bayt . Xcoder Edit: @notjagan sayesinde -8 bayt

açıklama

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 bayt

Aslında bazı test senaryoları için TIO'da çalıştırılabilir

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]

Çevrimiçi deneyin!

Her iki çözüm de muhtemelen biraz golf olabilir.




Bay Xcoder, ikincisi yaklaşık 50 bayt azaltılabilir, sadece birincisi için ikincisine değişiklik
yapmadım

İkincisinin çok golf oynayabileceğini biliyorum, ama birincisinde yapılan değişiklikler faydalı olmalı.
Bay Xcoder

1
Benim oyumu kazandın, harika bir açıklama ile harika bir kod için, çok çaba ve düşünce gösteriyor. Tebrikler ve PPCG'ye hoş geldiniz!
Bay Xcoder
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.