# 建造稳定的砖墙

39

``````[______][______]    4 4
[__][____][__][]    2 3 2 1
[][______][____]    1 4 3
[____][______][]    3 4 1
``````

``````[______][______]
[__][____)(__][]
[][______)(____]
[____][______][]
``````

``````1: []
2: [__]
3: [____]
4: [______]
...
``````

``````>> [1, 1, 2, 2], 2
[][__]
[__][]

>> [1, 1, 1, 2, 2, 2, 2, 3], 2
[__][____][__]
[][__][][__][]

>> [1, 1, 2, 2, 3, 3, 3, 3], 3
[][__][____]
[__][____][]
[____][____]

>> [1, 2, 3, 4, 5, 6, 7, 8, 9], 5
[][______________]
[__][____________]
[________________]
[____][__________]
[______][________]

>> [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], 5
[][__][__]
[__][__][]
[][__][__]
[__][__][]
[][__][__]
``````

Sparr

2
@Sparr 1 x 2个字符块看起来大致是正方形。我曾尝试过要求`n>1`，但不喜欢它如何限制测试用例。另外，显然有先例
xnor 2015年

Sparr

20

# Perl，166170194

``````#!perl -pa
\$_=(1x(\$x=2/(\$y=pop@F)*map{1..\$_}@F)."
")x\$y;sub
f{my\$l=\$_;\$-|=!@_;for\$=(@_){\$Z=__
x~-\$=;\$f=0;s/(11){\$=}/[\$Z]/&!/\]..{\$x}\[/s&&f(grep\$=ne\$_||\$f++,@_);\$-or\$_=\$l}}f@F
``````

``````\$ perl ~/wall.pl <<<"1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 5"
[][__][__]
[__][__][]
[][__][__]
[__][__][]
[][__][__]
``````

9

crazyhatfish

12

# CJam，94 92 82字节

``````l~1\$,:L,:)m*{1bL=},\e!\m*{~W<{/(\e_}%}%{::+)-!},{{_,,\f<1fb}%2ew{:&,(},!}={{(2*'_*'[\']}/N}/
``````

1）给定一个length数组，`L`我们如何将其划分为多个`H`部分。

``````l~1\$,:L,:)m*{1bL=},
l~                     e# Read the input as string and evaluate it.
`\$,:L                e# Copy the array and take its length. Store that in L
,:)             e# Get an array of 1 to L
m*           e# Cartesian power of array 1 to L of size H (height of wall)
{1bL=},    e# Take only those parts whose sum is L
``````

2）获取输入数组的所有排列，然后进一步获取所有排列的所有分区

``````\e!\m*{~W<{/(\e_}%}%
\e!                    e# Put the input array on top of stack and get all its permutations
\m*                 e# Put the all possible partition array on top and to cartesian
e# product of the two permutations. At this point, every
e# permutation of the input array is linked up with every
e# permutation of splitting L sized array into H parts
{           }%   e# Run each permutation pair through this
~W<             e# Unwrap and remove the last part from the partition permutation
{     }%     e# For each part of parts permutation array
/           e# Split the input array permutation into size of that part
(\         e# Take out the first part and put the rest of the parts on top
e_       e# Flatten the rest of the parts so that in next loop, they can be
e# split into next part length
``````

3）仅过滤出砖长相同的那些布局

``````{::+)-!},
{      },              e# Filter all brick layouts on this condition
::+                   e# Add up brick sizes in each layer
)-!                e# This checks if the array contains all same lengths.
``````

4）取出符合稳定性标准的第一个砖块布局

``````{{_,,\f<1fb}%2ew{:&,(},!}=
{                       }=   e# Choose the first array element that leaves truthy on stack
{         }%                e# For each brick layer
_,,                        e# Create an array of 0 to layer length - 1
\f<                     e# Get all sublists starting at 0 and ending at 0
e# through length - 1
1fb                  e# Get sum of each sub list. This gives us the cumulative
e# length of each brick crack except for the last one
2ew               e# Pair up crack lengths for every adjacent layer
{    },        e# Filter layer pairs
:&            e# See if any cumulative crack length is same in any two
e# adjacent layers. This means that the layout is unstable
,(          e# make sure that length of union'd crack lengths is greater
e# than 1. 1 because 0 will always be there.
!       e# If any layer is filtered through this filter,
e# it means that the layer is unstable. Thus negation
``````

5）打印布局

``````{{(2*'_*'[\']}/N}/
{               }/           e# For each brick layer
{           }/              e# For each brick
(2*'_*                     e# Get the (brick size - 1) * 2 underscores
'[\']                e# Surround with []
N             e# Newline after each layer
``````

# 82字节

``````l~:H;{e_mrH({H-X\$,+(mr)/(\e_}%_::+)-X\${_,,\f<1fb}%2ew{:&,(},+,}g{{(2*'_*'[\']}/N}/
``````

``````l~:H;{e_mrH({H-X\$,+(mr)/(\e_}%_::+)-X\${_,,\f<1fb}%2ew{:&,(},+,}g
l~:H;                           e# Eval the input and store the height in H
{   ...   }g               e# A do-while loop to iterate until a solution is found
e_mr                      e# Flatten the array and shuffle it.
H({               }%  e# This is the random partition generation loop
e# Run the loop height - 1 times to get height parts
H-X\$,+(            e# While generating a random size of this partition, we
e# have to make sure that the remaining parts get at least
e# 1 brick. Thus, this calculation
mr)         e# Get a random size. Make sure its at least 1
/(\e_    e# Similar to 92's part 2. Split, pop, swap and flatten

_::+)-                          e# 92's part 3. Copy and see if all elements are same
X\${_,,\f<1fb}%2ew{:&,(},  e# 92's part 4. Copy and see if layers are stable
+,                              e# Both part 3 and 4 return empty array if
e# the layout is desirable. join the two arrays and
e# take length. If length is 0, stop the do-while
``````

9

# Python 2中，680个670 660字节

``````M,L,R,N=map,len,range,None
exec"J=@:M(''.join,x);B=@:'['+'_'*2*~-x+']';K=@:M(B,x);W=@:J(M(K,x));C=@:set(M(sum,[x[:i]for i in R(L(x))]))-{0};T=@,w:w[x:]+w[:x]\ndef F(i):f=filter(@:i[x-1]&i[x],R(1,L(i)));return f and f".replace('@','lambda x')
def P(e,x,i,w,h):
for j in[-~_%h for _ in R(i-1,h+i-2)]:
for s in R(w):
if not e&C(T(s,x[j])):return j,s
return N,N
def b(l,h):
w,d=[[]for _ in R(h)],2*sum(l)/h
for _ in l[::-1]:q=M(L,W(w));w[[q.index(i)for i in sorted(q)if i+L(B(_))<=d][-1]]+=_,
g=M(C,w);i=F(g)
while i:
e=g[i-1];j,s=P(e,w,i,d,h)
if j!=N:w[j]=T(s,w[j]);w[i],w[j]=w[j],w[i];g=M(C,w);i=F(g)
else:b(T(-1,l),h);return
print'\n'.join(W(w))
``````

``````>>> tests = [([1, 1, 2, 2], 2),([1, 1, 1, 2, 2, 2, 2, 3], 2), ([1, 1, 2, 2, 3, 3, 3, 3], 3), ([1, 2, 3, 4, 5, 6, 7, 8, 9], 5), ([1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], 5)]
>>> for t in tests:
...     b(*t); print
...
[__][]
[][__]

[____][__][__]
[][][__][__][]

[____][____]
[__][__][][]
[____][____]

[________________]
[______________][]
[____________][__]
[__________][____]
[________][______]

[__][__][]
[][__][__]
[__][__][]
[][__][__]
[__][__][]
``````

1. 将砖块（最长->最短）分配给层，尝试在移动到下一层之前填充每一层。
2. 每当相邻的层不稳定时，请尝试交换层并移动砖块，直到找到有用的为止。
3. 如果没有任何效果，请将最长的砖移到尺寸列表的前面并递归。

1

PurkkaKoodari

sirpercival

1

crazyhatfish

sirpercival，2015年

5

``````import Data.List
c=concat
n=init.scanl1(+)
1%l=[[[l]]]
n%l=[map(h:)(c\$(n-1)%t)|(h,t)<-map(`splitAt`l)[1..length l]]
v[x]=1<2
v(x:y:z)=sum x==sum y&&n x==n x\\n y&&v(y:z)
``````

``````*Main> putStr \$  [1, 2, 3, 4, 5, 6, 7, 8, 9] # 5
[______][________]
[__________][____]
[____________][__]
[][______________]
[________________]

*Main> putStr \$ [1, 1, 2, 2, 3, 3, 3, 3] # 3
[____][____]
[__][__][][]
[____][____]
``````

4

# 蟒蛇2，528，417，393，381

``exec u"from itertools import*;m=map;g=@w,n:([[w]],[[w[:i]]+s#i?range(1,len(w))#s?g(w[i:],n-1)])[n>1];r=@x:set(m(sum,[x[:i]#i?range(1,len(x))]));f=@w:1-all(m(@(x,y):not x&y,zip(m(r,w[:-1]),m(r,w[1:]))));a=@s,h:['\\n'.join([''.join(['[%s]'%(' '*(s-1)*2)#s?r])#r?o])#p?permutations(s)#o?g(p,h)if len(set([sum(r)#r?o]))<2 and~-f(o)]".translate({64:u"lambda ",35:u" for ",63:u" in "})``

a是主要功能：

``````>> a([1, 1, 2, 2], 2)
'[][  ]\n[  ][]'
``````

PurkkaKoodari

PurkkaKoodari'5

sirpercival，2015年

@ Pietu1998哦，是的，错过了一个空格。感谢您提供的提示，我很惊讶您可以发现这些东西。
crazyhatfish

Abr001am 2015年

3

# 的JavaScript（ES6）222 232 265 279 319

``````f=(n,h,b=[],s=0)=>
(R=(z,l,p,k,t)=>
z?b.map((v,a)=>
v&&k.indexOf(v=t+a)<0&v<=s&&(
--b[a],h=l+`[\${'__'.repeat(a-1)}]`,
v-s?R(z,h,[...p,v],k,v):R(z-1,h+'\n',[],p,0),
++b[a]
))
:n=l
)(h,'',[],[],0,n.map(n=>(b[n]=-~b[n],s+=n)),s/=h)&&n

// Test suite

out=x=>OUT.innerHTML=OUT.innerHTML+x+'\n'

;[
[[1, 1, 2, 2], 2], [[1, 1, 1, 2, 2, 2, 2, 3], 2], [[1, 1, 2, 2, 3, 3, 3, 3], 3]
,[[1, 2, 3, 4, 5, 6, 7, 8, 9], 5], [[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], 5]]
.forEach(([a,b])=>out(a+' '+b+'\n'+f(a,b)))``````
``<pre id=OUT></pre>``

``````function f(n, h) {
var b=[], s=0, result // in golfed version will re-use n for result variable
n.forEach(function (n) {
b[n] = -~b[n] // group equal input numbers in buckets
s+=n          // calc sum of input numbers
});
// example of buckets: input 1,1,4,1,5,4 -> b=3,b=2,b=1
s /= h // total sum / height => sum expected for each brick layer

// recursive scan function
function R(z, // layer count, from h downto 1
l, // output so far
p, // current layer partial sums array, mark intervals between bricks
k, // prev layer parial sums, checked to avoid faulds
t  // current partial sum
)
{
if (z > 0)
{ // still building
b.forEach( function (v,a) { // a:number from input list, v: repeat count
var w, m   // locals (in golfed version, reuse other variables avoid defining locals)
w = t + a; // increased running total for current layer
if (v != 0  // repeat count still > 0
&& k.indexOf(w) < 0 // running total not found on list in prev layer (no fault)
&& w <= s) // current layer length not exceeded
{
--b[a]; // decrease repeat count, number used one more time
m = l+"["+ '__'.repeat(a-1) + "]"; // new output with a brick added
// l is not changed, it will be used again in this loop
if (w == s)
{   // layer complete, go to next (if any)
// recurse, new layer, add newline to output, p goes in k, and t start at 0 again
R(z-1, m+'\n', [], p, 0);
}
else
{   // layer still to complete
// recurse, same layer, m goes in l, add current sum to array p
R(z, m, [...p,w], k, w);
}
++b[a]; // restore value of repeat count for current loop
}
})
}
else
{ // z == 0, all layers Ok, solution found, save in result and go on to next
result = l;
}
}

R(h,'',[],[],0);
return result; // this is the last solution found
}``````

2

## Python 2，网格方法（290个字符）

``````x,h=input()
from itertools import *
w = sum(x)*2/h
for p in permutations(x):
bricks = ''.join('[' + '_'*(2*n-2) + ']' for n in p)
cols = map(''.join,zip(*zip(*[iter(bricks)]*w)))
if all(c=='[' for c in cols) and all(c==']' for c in cols[-1]) and not any(']]' in col or '[[' in col for col in cols[1:-1]):
print('\n'.join(map(''.join,zip(*cols))))
print()
``````

``````x,h=input()
from itertools import*
w=sum(x)*2/h
z=zip
j=''.join
for p in permutations(x):
C=map(j,z(*z(*[iter(j('['+'_'*(2*n-2)+']'for n in p))]*w)))
if C.strip('[')==''and C[-1].strip(']')==''and not any(']]'in c or '[['in c for c in C[1:-1]):
print('\n'.join(map(j,z(*C))))
break
``````

...或滥用正则表达式，这使我们可以将“块对齐对齐”条件与“无裂纹”条件结合使用：

``````       v
[][__][_
___][__]
^
``````

``````     vv
[][__][]
[    ][]
^^
``````

``````# assume input is x and height is h

from itertools import *
import re
w=sum(x)*2/h

STACKED_BRACKET_RE = r'(?=\[.{%i}\[|\].{%i}\])'%(w-1,w-1)  # ]....] or [....[
STRING_CHUNK_RE = '.{%i}'%w  # chunk a string with a regex!
bracketGoal = set().union(*[(x*w,x*w+w-1) for x in range(h-1)])  # expected match locations

for p in permutations(x):
string = ''.join('['+'_'*(2*n-2)+']'for n in p)
bracketPositions = {m.start() for m in re.finditer(STACKED_BRACKET_RE,string)}
print(string, bracketPositions, bracketGoal, STACKED_BRACKET_RE) #debug
if bracketPositions==bracketGoal:
break

print('\n'.join(re.findall(STRING_CHUNK_RE,string)))
``````

## Python，regexp方法（304个字符）：

``````from itertools import*
import re
x,h=input()
w=sum(x)*2/h
for p in permutations(x):
s=''.join('['+'_'*(2*n-2)+']'for n in p)
if {m.start()for m in re.finditer(r'(?=\[.{%i}\[|\].{%i}\])'%(w-1,w-1),s)}==set().union(*[(x*w,x*w+w-1) for x in range(h-1)]):
break

print('\n'.join(re.findall('.{%i}'%w,s)))
``````

xnor 2015年

0

## Matlab（359）

``````function p(V),L=perms(V);x=sum(V);D=find(rem(x./(1:x),1)==0);for z= 2:numel(D-1)for y=1:numel(L),x=L(y,:);i=D(z);b=x;l=numel(x);for j=1:l,for k=j-1:-1:2,m=sum(x(1:k));if mod(m,i),if mod(m,i)<mod(sum(x(1:k-1)),i)||sum(x(1:j))-m==i,b=0;,end,end,end,end,if b,for j=1:l,fprintf('[%.*s]%c',(b(j)-2)+b(j),ones(9)*'_',(mod(sum(x(1:j)),i)<1)*10);end,return,end;end,end
``````

## 输出量

``````[____]

[__][]

[][__]
``````