Bạn có thể gấp một hexomino thành một khối không?


24

Một trong những đồ chơi yêu thích của con tôi là một bộ như thế này . Trên thực tế, đây là một trong những đồ chơi yêu thích của tôi - Tôi đã chơi với nó và nó đã cho tôi một số ý tưởng thử thách PPCG. Đây là một:

Viết chương trình hoặc hàm lấy bản vẽ dòng ASCII làm đầu vào và quyết định xem nó có gập lại thành một khối hay không.

Đầu vào

Đầu vào sẽ bao gồm chính xác một hexomino được xây dựng từ các hình vuông như thế này:

+-+
| |
+-+

Ví dụ, heximino đầu vào hợp lệ là:

+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
  | |
  +-+

Đầu ra

  • Một giá trị trung thực nếu hexomino có thể được gấp lại thành một khối, hoặc
  • Một giá trị falsey khác.

Để tiết kiệm cho chúng tôi một chút công việc, wikipedia có đồ họa đẹp:

  • Tất cả 35 hình lục giác:

  • Tất cả 11 hình lục giác gấp thành hình khối:

Ghi chú

  • Các hình lục giác đầu vào có thể có bất kỳ phép quay hoặc phản xạ nào, không chỉ các hình lục giác được hiển thị trong hình trên
  • Các hình lục giác đầu vào có thể có không gian hàng đầu, nhưng sẽ được căn chỉnh chính xác theo chính chúng
  • Các hình lục giác đầu vào có thể có dấu cách ở cuối dòng và dấu dòng mới ở cuối đầu vào

1
Bạn có thể giải thích tại sao có một thẻ xử lý hình ảnh ở đây? Không phải câu hỏi, cũng không phải câu trả lời sẽ phải thực hiện bất kỳ loại xử lý hình ảnh nào để giải quyết thách thức.
Tối ưu hóa

Làm rõ về không gian hàng đầu / dấu: có phải là không gian hàng đầu / dấu không cần thiết trên mỗi hàng và các dòng mới không cần thiết được phép trong đầu vào không? Tôi có thể quản lý hơn 1000 ký tự đầu vào không?
edc65

@ edc65 có bạn nên mong đợi khoảng trắng không cần thiết bạn mô tả. Kích thước đầu vào tối đa 1000 ký tự có vẻ hợp lý - Tôi sẽ chỉnh sửa trong
Chấn thương kỹ thuật số

Hừm. Tôi tự hỏi có bao nhiêu hình lục giác có thể được ép, ghép lại, trên một trang in?
luser droog

Câu trả lời:


7

PMA / Ốc , 130

.!(z\ |o{c..!(z\ }3){w=(..!(z\ )|b..!(z\ )o{..!(z\ }2|c{..!(z\ }1,2w..!(z\ )|w{..!(z\ }1,2c..!(z\ }4o..!(z\ )(..!(z\ )|n..!(z\ )`2

hoặc "dễ đọc" hơn,

?
.!(z\  | o{c..!(z\ }3  )
{w =( ..!(z\ ) | b ..!(z\ ) o {..!(z\ }2  | c {..!(z\ }1,2w..!(z\ ) | w {..!(z\ }1,2c..!(z\  }4
o  ..!(z\ ) ( ..!(z\ ) | n ..!(z\ ) `2

Bất thường, một vấn đề xuất hiện có thể được xử lý bởi số lượng tính năng hạn chế được triển khai cho đến nay. Các !(z\ )mô hình xác định rằng vị trí hiện tại là không gian ở giữa một hình vuông bằng một sự khẳng định tiêu cực rằng có một không gian trong một số "octilinear" hướng. Ý tưởng chung là kiểm tra một mẫu đặt một hình vuông tại mỗi trong số 5 vị trí cần thiết so với hình vuông mà trận đấu bắt đầu. Ngoài ra, nó cần kiểm tra xem nó không nằm trong một khối vuông 2x2. Trước khi chương trình hoạt động, tôi đã phải sửa một lỗi với phân tích cú pháp dấu ngoặc đơn.

Nếu hexomino không ánh xạ một khối, 0được in. Nếu có, một số nguyên dương được in (số lượng trùng khớp).

Tôi đã điều chỉnh trình tạo polyomino này để tạo ra tất cả các trường hợp thử nghiệm có thể:

n=input()
r=range
T=lambda P:set(p-min(p.real for p in P)-min(p.imag for p in P)*1j for p in P)
A=[]
for i in r(1<<18):
 P=[k%3+k/3*1j for k in r(18)if i>>k&1]
 C=set(P[:1])
 for x in P:[any(p+1j**k in C for k in r(4))and C.add(p)for p in P]
 P=T(P)
 if not(C^P or P in A or len(P)-n):
  #for y in r(4):print''.join(' *'[y+x*1j in P] for x in r(6))
  o = [ [' ']*13 for _ in r(9)]
  for y in r(4):
   for x in r(6):
    if y+x*1j in P: X=2*x;Y=2*y; o[Y][X]=o[Y+2][X]=o[Y][X+2]=o[Y+2][X+2]='+'; o[Y][X+1]=o[Y+2][X+1]='-';o[Y+1][X+2]=o[Y+1][X]='|'
  print '\n'.join(map(''.join,o))
  A+=[T([p*1j**k for p in P])for k in r(4)]

hahahahahahahah "dễ đọc" hơn
Trình tối ưu hóa

5

Ruby, 173 148 145 143 byte

h=->b,c{[c.count(c.max),c.count(c.min),3].max*2<b.max-b.min}
->s{x=[];y=[];i=j=0
s.bytes{|e|e==43&&x<<i|y<<j;i=e<32?0*j+=1:i+1}
h[x,y]||h[y,x]}

Thay đổi mới nhất: /2ở bên phải <thay thế bằng *2bên trái. Cho phép loại bỏ một bộ()

Giải trình

Mã này gồm hai phần: một hàm không tên chính thực hiện phân tích cú pháp và một hàm không tên phụ được gán cho biến hthực hiện kiểm tra.

Hàm chính quét quét qua chuỗi, thêm tọa độ x và y i,jcủa tất cả các +ký hiệu được tìm thấy x[]y[]. Sau đó, nó gọi hhai lần. Lần đầu tiên nó giả sử hexomino là ngang ( x[]chứa chiều dài và y[]chiều rộng) và lần thứ hai nó giả định nó là dọc.

Hàm hlấy tọa độ dọc trong mảng bsau đó tọa độ chiều rộng trong mảng c. Nó tính toán độ dài (tính theo bình phương) theo biểu thức (b.max.b.min)/2. Nếu giá trị này nhỏ hơn hoặc bằng 3, hexomino sẽ được đánh giá theo hướng khác để htrả về false.

Kiểm tra các hexominos sẽ cho thấy rằng nếu độ dài là 4, thì các hexominos đó sẽ gấp lại thành một khối có không quá 2 hình vuông (3 +ký hiệu) ở hàng đầu tiên và cuối cùng . Hầu hết các hình vuông được tập trung ở hàng giữa, sẽ trở thành đường xích đạo của khối lập phương. Điều kiện này hóa ra là cần thiết và đủ cho một hexomino có chiều dài 4 sẽ gấp lại thành một khối.

Chỉ có một hexomino có chiều dài 5 sẽ gấp lại thành một khối. Nó có 3 hình vuông (4 +ký hiệu) ở hàng đầu tiên và cuối cùng. Tất cả các hexominos khác có độ dài 5 có 5 hoặc nhiều +biểu tượng ở hàng đầu tiên hoặc hàng cuối cùng.

Chỉ có một hexomino có chiều dài 6. Nó có 7 +biểu tượng trên mỗi hàng.

Đặt tất cả những thứ này lại với nhau, đủ để kiểm tra xem độ dài của hexomino lớn hơn 3 và số lượng +ký hiệu trên hàng đầu tiên và cuối cùng (tùy theo giá trị nào cao hơn) nhỏ hơn chiều dài.

Ungolfed trong chương trình thử nghiệm

#checking function as explained in text
h=->b,c{[c.count(c.max),c.count(c.min),3].max<(b.max-b.min)/2}

#main function for parsing
f=->s{
  x=[]                 #separate assignments required, 
  y=[]                 #otherwise we get 2 pointers to the same array
  i=j=0                #start coordinates 0,0
  s.bytes{|e|          #scan string bytewise
    e==43&&x<<i|y<<j     #if byte is a + symbol (ascii 43) add the coordinates to arrays x and y
    i=e<32?0*j+=1:i+1    #if byte is before ascii 32 assume newline, increment j and zero i. Otherwise increment i
  }
  h[x,y]||h[y,x]       #call h twice, with x and y in each possible order
}



#VALID INPUTS
puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
| |
+-+"]

puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
  | |
  +-+"]

puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
    | |
    +-+"]
puts f["
+-+
| |
+-+-+-+
| | | |
+-+-+-+-+
    | | |
    +-+-+"]

puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
      | |
      +-+"]

puts f["
    +-+
    | |
+-+-+-+-+
| | | | |
+-+-+-+-+
    | |
    +-+"]
puts f["
    +-+
    | |
+-+-+-+
| | | |
+-+-+-+-+
    | | |
    +-+-+"]


puts f["
  +-+
  | |
+-+-+-+-+
| | | | |
+-+-+-+-+
    | |
    +-+"]
puts f["
  +-+
  | |
+-+-+-+
| | | |
+-+-+-+-+
    | | |
    +-+-+"]  
puts f["
+-+-+
| | |
+-+-+-+
  | | |
  +-+-+-+
    | | |
    +-+-+"]

puts f["
  +-+-+-+
  | | | |
  +-+-+-+-+-+
      | | | |
      +-+-+-+
"]


#INVALID INPUTS

puts f["
  +-+-+-+
  | | | |
  +-+-+-+
  | | | |
  +-+-+-+
"]


puts f["
  +-+-+-+-+-+-+
  | | | | | | |
  +-+-+-+-+-+-+

"]


puts f["
  +-+-+
  | | |
  +-+-+
  | |
  +-+
  | |
  +-+
  | |
  +-+
  | |
  +-+
"]

puts f["
  +-+-+-+-+-+
  | | | | | |
  +-+-+-+-+-+
    | |
    +-+
"]

puts f["
      +-+
      | |
  +-+-+-+-+-+
  | | | | | |
  +-+-+-+-+-+
"]

puts f["
  +-+-+-+-+
  | | | | |
  +-+-+-+-+-+
        | | |
        +-+-+"]

puts f["
  +-+-+-+-+
  | | | | |
  +-+-+-+-+
      | | |
      +-+-+
"] 


puts f["
  +-+-+-+-+
  | | | | |
  +-+-+-+-+
  | | | |
  +-+ +-+
"]

puts f["
 +-+   +-+
 | |   | |
 +-+-+-+-+
 | | | | |
 +-+-+-+-+
"]

puts f["
   +-+-+
   | | |
 +-+-+-+-+
 | | | | |
 +-+-+-+-+
"]

puts f["
  +-+
  | |
  +-+
  | |
  +-+-+-+-+
  | | | | |
  +-+-+-+-+
"]

puts f["
  +-+
  | |
  +-+-+-+
  | | | |
  +-+-+-+
  | |
  +-+
  | |
  +-+
"]

puts f["
  +-+
  | |
+-+-+-+
| | | |
+-+-+-+
| |
+-+
| |
+-+"]

puts f["
  +-+-+
  | | |
  +-+-+
  | |
  +-+-+
  | | |
  +-+-+
    | |
    +-+
"]

puts f["
  +-+-+-+
  | | | |
  +-+-+-+-+
    | | | |
    +-+-+-+
"]

puts f["
  +-+-+-+
  | | | |
  +-+-+-+
      | |
      +-+-+
      | | |
      +-+-+
"]


puts f["
  +-+-+-+
  | | | |
  +-+-+-+-+
      | | |
      +-+-+
        | |
        +-+
"]

pentonimo → hexonimo trong văn bản của bạn?
Paulo Ebermann

3

JavaScript (ES6), 443 431

Chỉnh sửa sửa lỗi, sự cố trong quá trình phân tích cú pháp đầu vào, xóa các cột trống

F=t=>(a=b=c=d=e=f=g=h=0,M=Math.min,
t=t.split('\n').filter(r=>r.trim()>''),
t=t.map(r=>r.slice(M(...t.map(r=>r.search(/\S/))))),
t.map((r,i)=>i&1&&[...r].map((_,j)=>j&1&&r[j-1]==r[j+1]&t[i-1][j]==t[i+1][j]&r[j-1]=='|'
&&(y=i>>1,x=j>>1,z=y*5,w=x*5,a|=1<<(z+x),e|=1<<(w+y),b|=1<<(4+z-x),f|=1<<(4+w-y),c|=1<<(20-z+x),g|=1<<(20-w+y),d|=1<<(24-z-x),h|=1<<(24-w-y)
))),~[1505,2530,3024,4578,252,6552,2529,4577,2499,4547,7056].indexOf(M(a,b,c,d,e,f,g,h)))

Điều đó rất dài và thậm chí lâu hơn khi phân tích cú pháp đầu vào là một phần lớn của nhiệm vụ.

Những gì tôi làm là xác minh nếu đầu vào đã cho là một trong 11 hình lục giác có thể gập lại.

Mỗi hexomino có thể gập lại có thể được ánh xạ tới một số bitmap 5x5 (tối đa 8 khác nhau, với tính tương tự và xoay). Lấy bitmap là số 25 bit, tôi đã tìm thấy các giá trị tối thiểu cho 11 hình lục giác được ghi chú, sử dụng mã sau (với định dạng đầu vào rất đơn giản)

h=[ // Foldable hexominoes
'o\noooo\no', ' o\noooo\n o', // pink
'o\noooo\n   o', ' o\noooo\n  o', 'ooo\n  ooo', 'oo\n oo\n  oo', //blue
'o\noooo\n o', 'o\noooo\n  o', 'oo\n ooo\n o', 'oo\n ooo\n  o', 'o\nooo\n  oo' // gray
]
n=[]
h.forEach(t=>(
  a=[],
  t.split('\n')
    .map((r,y)=>[...r]
      .map((s,x)=>s>' '&&(
         a[0]|=1<<(y*5+x),a[1]|=1<<(x*5+y),  
         a[2]|=1<<(y*5+4-x),a[3]|=1<<(x*5+4-y),  
         a[4]|=1<<(20-y*5+x),a[5]|=1<<(20-x*5+y),  
         a[6]|=1<<(24-y*5-x),a[7]|=1<<(24-x*5-y))
     )
  ),
n.push(Math.min(...a))
))

Điều đó mang lại [1505,2530,3024,4578,252,6552,2529,4577,2499,4547,7056]

Vì vậy, với chuỗi đầu vào, tôi phải làm tương tự để tìm bitmap tối thiểu, sau đó trả về true nếu số này có trong danh sách prealc của tôi.

// Not so golfed 

F=t=>(  
  a=b=c=d=e=f=g=h=0,M=Math.min,
  t=t.split('\n').filter(r=>r.trim()>''), // remove blank lines
  t=t.map(r=>r.slice(M(...t.map(r=>r.search(/\S/))))), // remove blank colums to the left
  t.map((r,i)=>i&1&&[...r] // only odd rows
   .map((_,j)=>j&1&& // only odd columns
      r[j-1]==r[j+1]&t[i-1][j]==t[i+1][j]&r[j-1]=='|' // found a cell
         &&(y=i>>1,x=j>>1,z=y*5,w=x*5, // find bitmaps for 8 rotations/simmetries
            a|=1<<(z+x),e|=1<<(w+y),  
            b|=1<<(4+z-x),f|=1<<(4+w-y),  
            c|=1<<(20-z+x),g|=1<<(20-w+y),  
            d|=1<<(24-z-x),h|=1<<(24-w-y)  
    ))),
   ~[1505,2530,3024,4578,252,6552,2529,4577,2499,4547,7056].indexOf(Math.min(a,b,c,d,e,f,g,h)) // look for min
)

Chạy đoạn mã để kiểm tra trong Firefox


Hãy tha thứ cho tôi nếu tôi đang thiếu thứ gì đó, nhưng bạn không thể ,\nt=ttừ cuối dòng thứ hai / đầu dòng thứ ba phải không?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ xem xét sáu tháng sau, mã phân tích có thể được thực hiện ngắn hơn 10 ... 15 byte. Như là, tôi cần gán cho t ở dòng 2 và một lần nữa ở dòng 3 vì ở dòng 3, nó được sử dụng để tìm số lượng ký tự trống để cắt ở bên trái.
edc65
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.