スタッキンボード


11

できるだけ小さなスペースにスタックする必要があるボードがたくさんあります。残念ながら、10枚以上積み重ねるとボードは倒れます。ボードを積み重ねる方法を教えてくれるプログラムが必要です。10枚以上のボードを積み重ねたり、ボードを空のスペースにぶら下げたりせずに、できるだけ水平方向のスペースを少なくしてください。

あなたのタスク:

ボードの長さを含む配列が与えられたときに、ボードを積み重ねる方法をASCIIアートとして出力するプログラムまたは関数を作成します。空のスペースにぶら下がっているボード。ASCIIアートには、ボードの構成が表示され、それぞれ異なる文字を使用して表示されます。最大20のボードがあります。たとえば、入力が[2,2,4,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の3513 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]

オンラインでお試しください!

どちらのソリューションも、おそらくかなりの量のゴルフができるでしょう。




Xcoder氏、2番目は50バイト近く削減できますが、最初の変更を2番目の変更に適用しませんでした
Halvard Hummel

私は2番目のものがたくさんゴルフできることを知っていますが、最初のものへの変更は役に立つはずです。
氏Xcoder

1
素晴らしい説明と素晴らしいコードで、多くの努力と考えを示してくれた私の賛成票を獲得しました。おめでとうございます、PPCGへようこそ!
ミスターXcoder
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.