สร้างกำแพงอิฐที่มั่นคง


39

กำแพงอิฐเป็นรูปสี่เหลี่ยมผืนผ้าที่ทำจากอิฐเรียงต่อกันในแนวตั้ง นี่คือกำแพงที่มีความสูง 4 และความกว้าง 8 โดยมีขนาดอิฐที่แสดงทางด้านขวา

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

กำแพงนี้ไม่มั่นคงเนื่องจากมีข้อผิดพลาดสถานที่ที่รอยร้าวแนวตั้งสองแนวระหว่างอิฐเรียงกันดังที่แสดงด้านล่างด้วย parens ในอิฐล้อมรอบ

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

แต่รอยแตกที่ล้อมรอบด้วยก้อนอิฐขนาด 1 ด้านขวาไม่ก่อให้เกิดความผิดพลาดเพราะมันถูกคั่นด้วยแถว

เขียนโค้ดที่ค้นหาและแสดงกำแพงที่สร้างขึ้นจากอิฐในขนาดที่กำหนด ไบต์ที่น้อยที่สุดจะเป็นผู้ชนะ

อินพุต

รายการขนาดอิฐที่ไม่ว่างเปล่า (ตัวเลขบวก) และความสูงอย่างน้อย 2 รายการนี้อาจเรียงลำดับได้หากคุณต้องการ คุณอาจเลือกที่จะนับอิฐแต่ละขนาด

เอาท์พุต

รูปภาพของกำแพงสี่เหลี่ยมที่มีความสูงที่ต้องการซึ่งใช้อิฐทั้งหมดที่ระบุ พิมพ์หรือส่งคืนเป็นสตริงที่มีบรรทัดใหม่

วาดก้อนอิฐขนาด n เป็นอักขระ 2n ขีดล่างล้อมรอบด้วยวงเล็บ

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
[][__][__]
[__][__][]
[][__][__]
[__][__][]
[][__][__]

ทำไมคุณถึงเลือกที่จะสร้างตัวละครแบบอิฐกว้าง 2n แทนที่จะเป็นความกว้าง 1>
Sparr

2
@Sparr 1 บล็อกตัวละคร 2 ตัวมีลักษณะเป็นสี่เหลี่ยม ฉันพยายามกำหนดn>1และไม่ชอบว่ามัน จำกัด กรณีทดสอบอย่างไร นอกจากนี้ยังเห็นได้ชัดว่ามีแบบอย่าง
xnor

ฉันไม่ได้หมายถึง 2n กับ n> 1 ฉันหมายถึง n กับ n> 1
Sparr

คำตอบ:


20

Perl, 166 170 194

งานที่สมบูรณ์แบบสำหรับภาษาที่สร้างโดย Larry Wall

#!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

กำลังดุร้าย แต่ค่อนข้างรวดเร็วในกรณีทดสอบ (<1s) การใช้งาน:

$ 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 ไบต์

นี่คือรุ่น 92 ไบต์ รุ่น 82 ไบต์มีดังนี้

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

พาร์ติชั่นนี้แบ่งอิฐไปในทุกวิถีทางเท่าที่จะเป็นไปได้ แรงเดรัจฉานกำลังสวยตอนนี้ แต่ยังคงรันเคสทดสอบล่าสุดในประมาณ 10 วินาทีบนJava Interpreterบนเครื่องของฉัน

คำอธิบาย :

รหัสแบ่งออกเป็น 5 ส่วน:

1) กำหนดความยาวของอาร์เรย์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

หลังจากนี้เรามีวิธีที่เป็นไปได้ทั้งหมดในการแยกอาร์เรย์อินพุตของเราเป็นชั้นอิฐ H

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

หลังจากนี้เรามีเลย์เอาต์ที่เป็นไปได้ทั้งหมดของอิฐอินพุทเข้าไปในHกำแพงอิฐเลเยอร์

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}/

นี่เกือบจะคล้ายกับเวอร์ชัน 92 ไบต์ยกเว้นว่ามันมีการสุ่มเลือก หากคุณอ่านคำอธิบายสำหรับเวอร์ชัน 92 ไบต์จากนั้นในเวอร์ชัน 82 ไบต์ส่วนที่ 3, 4 และ 5 จะเหมือนกันทุกประการในขณะที่แทนที่จะวนซ้ำพีชคณิตทั้งหมดจากส่วนที่ 1 และ 2 รุ่นนี้จะสุ่มสร้างหนึ่งใน การเปลี่ยนรูปในแต่ละครั้งทดสอบโดยใช้ส่วนที่ 3 และ 4 แล้วเริ่มกระบวนการใหม่หากการทดสอบส่วนที่ 3 และ 4 ล้มเหลว

สิ่งนี้จะพิมพ์ผลลัพธ์อย่างรวดเร็วสำหรับ 3 กรณีทดสอบแรก กรณีทดสอบ height = 5 ยังไม่ได้ให้ผลลัพธ์ในคอมพิวเตอร์ของฉัน

คำอธิบายของความแตกต่าง

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

ความคิดสำหรับรุ่นนี้ได้รับจาก randomra (Get it?)

ลองสิ่งนี้ทางออนไลน์


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[0]".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))

b(brick_sizes, height)เรื่องนี้ต้องมีการส่งออกในลำดับที่เรียงลำดับและจะเรียกว่าผ่าน

กรณีทดสอบ:

>>> 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
คุณอาจปล่อยcontinueจากใกล้ถึงจุดสิ้นสุด ยังreturn(N,N)ไม่จำเป็นต้องใช้วงเล็บ
PurkkaKoodari

การโทรที่ดี - นั่นcontinueเป็นของที่ระลึกจากรุ่นก่อนหน้า
sirpercival

1
ไม่สามารถให้มันทำงานคุณมีวงเล็บนอกWและTรับอาร์กิวเมนต์พิเศษ
crazyhatfish

โอ้โหขอบคุณ! แก้ไขแล้ว.
sirpercival

5

Haskell, 262 ไบต์

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)
l#n=unlines$map(>>=(\b->'[':replicate(2*b-2)'_'++"]"))$head$filter v$c.(n%)=<<permutations l

ตัวอย่างการใช้งาน:

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

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

วิธีการทำงาน: ฟังก์ชั่นหลัก#ใช้รายการl(รายการอิฐ) และตัวเลขh(ความสูง) และแยกการเรียงลำดับทั้งหมดของlเป็นhรายการย่อยที่ตำแหน่งที่เป็นไปได้ทั้งหมด (ผ่านฟังก์ชั่น%เช่น2%[1,2,3,4]-> [ [[1],[2,3]] , [[1,2],[3]] , [[1,2,3],[]] ]) มันช่วยให้ผู้ที่องค์ประกอบสองลำดับติดต่อกันมีผลรวมเท่ากัน (เช่นความยาวเท่ากันในก้อนอิฐ) และรายการของผลรวมย่อยไม่มีองค์ประกอบทั่วไป (เช่นรอยแตกไม่เรียงกันฟังก์ชันv) ใช้รายการแรกที่เหมาะสมและสร้างสตริงของอิฐ


4

Python 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)][0]".translate({64:u"lambda ",35:u" for ",63:u" in "})

aเป็นหน้าที่หลัก:

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

คุณสามารถบันทึก 4 ไบต์โดยเปลี่ยนการนำเข้าfrom itertools import*และนำออกitertools.จากการpermutationsโทร นอกจากนี้ifs ในท้ายที่สุดสามารถเปลี่ยนเป็นif all(x==w[0] for x in w)and~-f(o):return... เพื่อบันทึก 13 ไบต์
PurkkaKoodari

นอกจากนี้จะไม่fส่งคืนในการทำซ้ำครั้งแรกเสมอไปหรือไม่ นั่นดูแปลก ๆ มันอาจเป็นข้อผิดพลาดหรือโอกาสในการเล่นกอล์ฟที่ยิ่งใหญ่
PurkkaKoodari

คุณมีช่องว่างภายนอกจำนวนมากที่สามารถลบออกได้ - ก่อนหรือหลังเครื่องหมายคำพูด / วงเล็บ / ล้อมรอบตัวดำเนินการ ฯลฯ นอกจากนี้คุณยังได้รับมอบหมายt=0สองครั้งr(); คุณสามารถทำให้ฟังก์ชั่นนั้นmap(sum,[x[:i] for i in range(len(x))])เป็นแบบซับเดียว (เหมาะสำหรับแลมบ์ดาหากต้องการ) การใช้ isdisjoint และการตั้งค่าในf()จะลดลงอย่างมีนัยสำคัญ ( f()ในปัจจุบันกลับมาหลังจากการทดสอบเพียงครั้งเดียวไม่ว่าจะพบข้อผิดพลาดหรือไม่) ส่วนตัวผมจะเขียนf()เป็นreturn not all(map(isdisjoint,map(set,map(r,w[:-1])),map(set,map(r,w[1:]))))หรือสิ่งที่คล้ายกัน
sirpercival

@ Pietu1998 โอ้ใช่พลาดช่องว่าง ขอบคุณสำหรับเคล็ดลับพวกฉันประหลาดใจที่คุณสามารถเห็นสิ่งเหล่านี้
crazyhatfish

หัวเราะแย่เกินไปฉันเกลียดรหัสแบบนั้นซึ่ง "จักรวาลอาจสิ้นสุดก่อนที่จะได้รับผล" แต่นี่เป็นไบต์ที่สั้นที่สุดที่จะทำอะไรได้อีก xD
Abr001am

3

JavaScript (ES6) 222 232 265 279 319

ยังคงที่จะกอล์ฟ อันนี้หาวิธีแก้ปัญหาทั้งหมดออกเพิ่งพบครั้งล่าสุดและมันค่อนข้างเร็ว

เรียกใช้ส่วนย่อยใน Firefox เพื่อทดสอบ

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>

Ungolfedและอธิบาย

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[1]=3,b[4]=2,b[5]=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[0]) 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()

วิธีการที่นี่คือคุณย้ายตารางและมองหา[[หรือ]]ที่ใดก็ได้ในคอลัมน์ คุณทดสอบด้วยว่าก้อนอิฐทั้งหมดที่อยู่ทางด้านซ้ายและด้านขวาของแนวกำแพง: สิ่งที่น่ารักที่นี่คือการทดสอบว่าองค์ประกอบทั้งหมดของสตริงเหมือนกัน:'[[[[[['.strip('[')==''


มินิเวอร์ชั่นด้านบน:

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[0].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

สิ่งนี้สามารถทำได้ง่ายกว่าในภาษาที่ใช้เมทริกซ์

... หรือการละเมิด regexes ซึ่งช่วยให้เราสามารถรวมเงื่อนไข "บล็อกการจัดตำแหน่งบนปลาย" กับเงื่อนไข "ไม่มีรอยแตก":

บอกว่าความกว้างของกำแพงคือ w = 6 ตำแหน่งของสตริงย่อย "[..... [", และ "] ..... ]" จะต้องตรงกับชุด {0, w-1, w, 2w-1,2w, 3w-1, .. } การไม่มีอยู่จริง ณ จุดเหล่านี้หมายถึง 'เสื่อน้ำมันก้อนอิฐ' เช่น:

       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)))

แนวคิดที่น่าสนใจทำงานกับภาพผนังโดยตรงเพื่อตรวจสอบความผิดพลาด x,h=input()คุณจำเป็นต้องมีสายที่จะใช้การป้อนข้อมูลเช่น
xnor

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

อินพุต

เวกเตอร์ของจำนวนเต็มตัวอย่าง: p ([1 1 2 2 3])

เอาท์พุต

แบบแผนของตัวอย่างผนัง:

[____]

[__][]

[][__]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.