스태킹 보드


11

가능한 한 작은 공간에 쌓아야 할 보드가 많이 있습니다. 불행히도, 보드를 10 높이 이상 쌓으면 보드가 넘어집니다. 보드를 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

파이썬 (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

파이썬 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 씨, 두 번째 바이트는 거의 50 바이트까지 줄일 수 있습니다. 첫 번째 코드의 변경 사항을 두 번째 코드에 적용하지 않았습니다.
Halvard Hummel

나는 두 번째 골프를 많이 할 수 있다는 것을 알고 있지만 첫 번째 골프의 변화가 도움이 될 것입니다.
Mr. Xcoder

1
많은 노력과 생각을 보여주는 훌륭한 설명과 함께 훌륭한 코드로 저의 공감대를 얻었습니다. 축하하고 PPCG에 오신 것을 환영합니다!
Mr. Xcoder
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.