Đếm các mẫu Game of Life phổ biến


21

Nhiệm vụ ở đây là đọc từ .rletệp Golly hoặc plaintext (lựa chọn của bạn) có tên tệp được cung cấp (trên STDIN hoặc dưới dạng đối số dòng lệnh) và xác định và đếm các mẫu phổ biến trong lưới được mã hóa trong đó.

Ngoài ra, bạn có thể chọn để có nội dung của tệp được cung cấp trực tiếp qua STDIN.

Chương trình của bạn sẽ có thể xác định và phân biệt ít nhất mười lăm cuộc sống nghiêm ngặt phổ biến nhấtnăm dao động phổ biến nhất , cộng với tàu lượn .

Tất cả các pha của các bộ dao động này phải được nhận ra, cũng như tất cả bốn pha của tàu lượn.

Nó sẽ xuất ra một danh sách chứa số đếm cuối cùng của mỗi mẫu, với tên và số lượng của mỗi mẫu trên một dòng riêng biệt. Chương trình của bạn có thể bao gồm trong danh sách ouput tất cả các mẫu này hoặc chỉ những mẫu có ít nhất một mẫu được tìm thấy.

Các mẫu là một phần của các mẫu khác đang được tính không nên được tính. (ví dụ, pha 8 ô của đèn hiệu cũng không nên được tính là hai khối và không nên tính một chiếc cà vạt tàu là hai tàu)

Bạn có thể cho rằng đầu vào đã ổn định và không chứa các mẫu không có trong bộ đã nói ở trên. Bạn cũng có thể giả định rằng lưới đầu vào sẽ nằm trong hộp 1024x1024.

Đây là , vì vậy chương trình ngắn nhất sẽ thắng.

Mô tả định dạng tệp RLE

Tệp RLE chứa lưới tuổi thọ được mã hóa theo chiều dài. Tất cả các dòng bắt đầu với #là ý kiến ​​và nên được bỏ qua.

Dòng không trống, không bình luận đầu tiên có dạng x=<width>,y=<height>,rule=<rule>. Đối với các mục đích của nhiệm vụ này, quy tắc sẽ luôn luôn là B3/S23. Nó có thể chứa các khoảng trắng cần được loại bỏ trước khi xử lý dòng này (tất nhiên, không cần thiết phải xử lý dòng này.)

Các dòng không bình luận sau lần đầu tiên nên được coi là một chuỗi đơn. Điều này sẽ chỉ gồm các chữ số thập phân, các nhân vật $, bo, và ngắt dòng và sẽ không kết thúc bằng một chữ số. Ngắt dòng sẽ bị bỏ qua, nhưng bạn có thể cho rằng ngắt dòng sẽ không làm gián đoạn chuỗi chữ số.

Điều này có thể được chấm dứt bởi một !.

bđại diện cho một tế bào chết, ođại diện cho một tế bào sống và $đại diện cho sự kết thúc của một hàng. Bất kỳ số thập phân nào chỉ ra rằng ký hiệu sau sẽ được coi là lặp lại nhiều lần.

Mã hóa mẫu văn bản

Tùy chọn khác là đọc mẫu ở định dạng văn bản gốc khác được mô tả ở đây. Trong mã hóa này, các ô tắt được biểu thị bằng dấu gạch nối và trên các ô được biểu thị bằng chữ hoa Os, với các dòng mới ngăn cách các hàng.

Bạn có thể cho rằng tất cả các dòng không bình luận sẽ được đệm với chiều dài bằng với dấu gạch nối.

Các dòng bắt đầu bằng !các bình luận và được bỏ qua.

Một số trường hợp thử nghiệm

RLE:

#This is a comment
x = 35, y = 16, rule = B3/S23
bo$2o$obo5$22bo$22bo$22bo2$18b3o3b3o2$22bo$22bo10b2o$22bo10b2o!

Văn bản thô:

!This is a comment
-O---------------------------------
OO---------------------------------
O-O--------------------------------
-----------------------------------
-----------------------------------
-----------------------------------
-----------------------------------
----------------------O------------
----------------------O------------
----------------------O------------
-----------------------------------
------------------OOO---OOO--------
-----------------------------------
----------------------O------------
----------------------O----------OO
----------------------O----------OO

Các kết quả:

Glider 1
Blinker 4
Block 1

RLE:

x = 27, y = 15, rule = B3/S23
5b2o$5b2o9$11bo$o9bobo$o9bobo$o10bo12b3o!
#Here's a comment at the end

Văn bản thô:

-----OO--------------------
-----OO--------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
-----------O---------------
O---------O-O--------------
O---------O-O--------------
O----------O------------OOO
!Here's a comment at the end

Các kết quả:

Block 1
Blinker 2
Beehive 1

RLE:

#You may have multiple comments
#As shown here
x = 13, y = 11, rule = B3/S23
2o$2o2$12bo$12bo$12bo$2b2o$2b2o4b2o$7bo2bo$7bobo$8bo!

Văn bản thô:

!You may have multiple comments
!As shown here
OO-----------
OO-----------
-------------
------------O
------------O
------------O
--OO---------
--OO----OO---
-------O--O--
-------O-O---
--------O----

Các kết quả:

Block 2
Blinker 1
Loaf 1

RLE:

# Pentadecathlon
# Discovered by John Conway
# www.conwaylife.com/wiki/index.php?title=Pentadecathlon
x = 10, y = 3, rule = B3/S23
2bo4bo2b$2ob4ob2o$2bo4bo!

Văn bản thô:

! Pentadecathlon
! Discovered by John Conway
! www.conwaylife.com/wiki/index.php?title=Pentadecathlon
--O----O--
OO-OOOO-OO
--O----O--

Các kết quả:

Pentadecathlon 1

Tiền thưởng

Nếu bạn hỗ trợ cả hai định dạng đầu vào (sử dụng phần mở rộng tệp [ .rlecho tệp rle và .cellscho bản rõ - cách đọc các phần mở rộng khác không được xác định] hoặc cờ dòng lệnh để phân biệt giữa chúng), bạn có thể trừ 5% khỏi điểm số của mình.


Còn vềOOO.OO\n....OO
Akangka

@ChristianIrwan Chà, đó không phải là một mô hình ổn định nên dù sao bạn cũng sẽ không được đưa nó làm đầu vào.
SuperJedi224

Câu trả lời:


13

Haskell, 2417 byte

Điều này mất khá nhiều thời gian và vẫn còn một vài lỗi, nhưng tôi có một vài thủ thuật hoạt động nên nó đáng giá.

Ghi chú:

  • Nó chỉ chấp nhận định dạng văn bản gốc, được chuyển đến STDIN
  • Phải mất một thời gian như O (n ^ 20)
  • Tôi giả định rằng số lượng ký tự trong các dòng không bình luận là không đổi (trong một đầu vào cụ thể), vì đó là cách nó nằm trong các ví dụ
  • Thủ thuật điên rồ nhất là làm thế nào các mẫu được giải nén, trích xuất các phần tử tại vị trí (số cột) modulo (độ dài của đầu ra) để xây dựng mảng.

Nó kết hợp một vài ý chính:

  • mô hình và đối xứng có thể được tính toán trước
  • một mẫu duy nhất có thể được đóng gói thành một số nguyên, với các kích thước đã biết
  • tìm tất cả các mô hình con là dễ dàng
  • đếm bình đẳng là dễ dàng

Đây là mã:

r=[1..20]
a!0=a!!0
a!x=tail a!(x-1)
u[_,x,y,l]=[[odd$div l$2^i|i<-[0..y],mod i x==j]|j<-[0..x-1]]
main=interact(\s->let q=[map(=='O')l|l<-lines s,l!0/='!']in let g=[i|i<-[[[0,3,11,3339,0,4,11,924,0,4,11,3219,0,3,11,1638,1,4,15,19026,1,4,15,9636,2,3,11,1386,2,4,11,1686,3,7,48,143505703994502,3,7,48,26700311308320,3,7,48,213590917399170,3,7,48,8970354435120,4,2,3,15,5,3,8,171,5,3,8,174,5,3,8,426,5,3,8,234,6,4,15,36371,6,4,15,12972,6,4,15,51313,6,4,15,13644,6,4,15,50259,6,4,15,12776,6,4,15,51747,6,4,15,6028,7,4,15,26962,7,4,15,9622,7,4,15,19094,7,4,15,27044,8,5,24,9054370,8,5,24,2271880,9,4,15,51794,9,4,15,13732,9,4,15,19027,9,4,15,9644,10,4,19,305490,10,5,19,206412,10,5,19,411942,10,4,19,154020,11,3,8,427,11,3,8,238,12,6,35,52217012547,12,6,35,3306785328,13,3,8,170,14,3,8,428,14,3,8,458,14,3,8,107,14,3,8,167,14,3,8,482,14,3,8,302,14,3,8,143,14,3,8,233,14,3,8,241,14,3,8,157,14,3,8,286,14,3,8,370,14,3,8,181,14,3,8,115,14,3,8,346,14,3,8,412,15,4,15,51219,15,4,15,12684,15,4,15,52275,15,4,15,13260,16,1,2,7,16,3,2,7,17,3,29,313075026,17,10,29,139324548,17,3,23,16252911,17,8,23,16760319,17,5,49,152335562622276,17,10,49,277354493774076,17,7,69,75835515713922895368,17,10,69,138634868908666122360,17,9,89,135722011765098439128942648,17,10,89,58184575467336340020006960,17,5,59,160968502306438596,17,12,59,145347113669124612,17,5,59,524156984170595886,17,12,59,434193401052698118,17,5,69,164495599269019571652,17,14,69,222245969722444385292,17,5,69,517140479305239282702,17,14,69,222262922122170485772,17,3,47,83020951028178,17,16,47,39740928107556,17,3,35,62664969879,17,12,35,40432499049,17,3,41,1581499314234,17,14,41,1293532058322,17,3,41,4349006881983,17,14,41,3376910168355,17,3,47,92426891685930,17,16,47,83780021865522,17,3,47,79346167206930,17,16,47,11342241794640,18,13,168,166245817041425752669390138490014048702557312780060,18,15,224,1711376967527965679922107419525530922835414769336784993839766570000,18,13,168,141409121010242927634239017227763246261766273041932,19,2,7,126,19,4,7,231,19,4,7,126,19,2,7,189,19,4,15,24966,19,4,15,18834,19,4,15,10644,19,4,15,26646]!p|p<-[h..h+3]]|h<-[0,4..424]],j<-[[[q!y!x|x<-[a..a+c]]|y<-[b..b+d]]|c<-r,d<-r,a<-[0..(length$q!0)-c-1],b<-[0..length q-d-1]],u i==j]in show[(words"aircraftcarrier barge beehive biloaf1 block boat eater1 loaf longbarge longboat mango ship shiptie tub glider beacon blinker pentadecathlon pulsar toad"!(e!0),sum[1|f<-g,e!0==f!0])|e<-g])

Đây là mã Mathicala được sử dụng để đóng gói một mảng 0,1 thành định dạng được giải nén sau đó bởi chương trình haskell:

rotate[m_]:=Transpose[Map[Reverse,m]]
findInversePermutation[m_]:=Block[{y=Length[First[m]], x=Length[m]}, InversePermutation[FindPermutation[Flatten[m], Flatten[Table[Table[Flatten[m][[i+1]], {i, Select[Range[0, x * y - 1], Mod[#, x]==j&]}], {j, 0, x - 1}]]]]]
enumShape[m_]:=Partition[Range[1, Length[Flatten[m]]], Length[m[[1]]]]
pack[m_]:={Length[rotate[rotate[m]]], Length[Flatten[rotate[rotate[m]]]], FromDigits[Permute[Flatten[rotate[rotate[m]]], findInversePermutation[enumShape[rotate[rotate[m]]]]], 2]}

Đây là một mã không hoàn chỉnh hơn nhiều của mã:

range = [1..16]          -- all of the patterns fall within this range

list ! 0        = list !! 0           -- this is a simple generic (!!)
list ! position = (tail list) ! (position - 1)

unpack [_, unpackedLength, unpackedSize, packed] = [ [odd $ div packed (2^i) | i <- [0..unpackedSize], (mod i unpackedLength) == j] | j <- [0..unpackedLength - 1]]

main=interact doer

doer input = show $ tallyByFirst (words nameString) foundPatterns -- this counts equalities between the list of patterns and the submatrices of the input
  where
    parsed = parse input -- this selects the non-comment lines and converts to an array of Bool's
    foundPatterns = countOccurrences partitioned subArrays
    subArrays     = allSubArrays parsed
    partitioned   = modPartition compressed 428 4 -- this partitions the compressed patterns into the form [name number, x length, x length * y length, packed integer]

countOccurrences patterns subArrays = [pattern | pattern <- patterns, subArray <- allSubArrays q, unpack pattern == subArray]

subArray m offsetX subSizeX offsetY subSizeY = [[m ! y ! x | x <- [offsetX..offsetX + subSizeX]] | y <- [offsetY..offsetY + subSizeY]]

allSubArrays m = [subArray m offsetX subSizeX offsetY subSizeY | subSizeX <- range, subSizeY <- range, offsetX <- [0.. (length $ head m) - subSizeX - 1], offsetY <- [0..(length m) - subSizeY - 1]]

tallyByFirst names list = [ (names ! (a ! 0), sum [1 | a <- list, (head a) == (head b)]) | b <- list]

parse string = [map (=='O') line | line <- lines string, head line /= '!']

modPartition list chunksize = [ [list ! position | position <- [offset..offset + chunksize - 1]] | offset <- [0, chunksize..(length list) - chunksize]]

Chào mừng đến với PPCG! Tôi chưa thử điều này nhưng nó chắc chắn trông rất ấn tượng. +1!
một spaghetto

Điều này còn hơn cả ấn tượng, +1!
mèo
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.