스태킹 보드


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.