Ortak Hayat Oyunu kalıplarını say


21

Buradaki görev .rle, dosya adı (STDIN'de veya bir komut satırı argümanı olarak) verilen bir Golly veya düz metin dosyasından (seçiminiz) okumak ve burada kodlanan ızgaradaki ortak kalıpları tanımlamak ve saymaktır.

Alternatif olarak, bunun yerine doğrudan STDIN üzerinden sağlanan dosyanın içeriğine sahip olmayı seçebilirsiniz.

Programınız en azından en yaygın onbeş katı durgun yaşamı ve en yaygın beş osilatörü ve planörleri tanımlayabilmeli ve ayırt edebilmelidir .

Bu osilatörlerin tüm aşamaları, planörün dört fazının da olduğu gibi tanınmalıdır.

Her bir kalıbın son sayısını içeren, her kalıbın adı ve miktarını ayrı bir satırda içeren bir liste çıkarmalıdır. Programınız, tüm bu kalıpları ya da yalnızca en az birinin bulunduğu kalıpları listeye dahil edebilir.

Sayılan diğer kalıpların bir parçası olan desenler sayılmamalıdır. (örneğin, bir işaretin 8 hücreli fazı iki blok olarak da sayılmamalı ve bir gemi bağı da iki gemi olarak sayılmamalıdır)

Girişin zaten stabilize olduğunu ve yukarıda belirtilen sette olmayan bir model içerdiğini varsayabilirsiniz. Giriş ızgarasının bir 1024x1024 kutuya sığacağını da varsayabilirsiniz.

Bu , bu yüzden en kısa program kazanır.

RLE dosya formatı açıklaması

Bir RLE dosyası, çalışma boyu kodlanmış bir yaşam ızgarası içeriyor. İle başlayan tüm satırlar yorumdur #ve dikkate alınmamalıdır.

Boş olmayan, yorum yapmayan ilk satır biçimdir x=<width>,y=<height>,rule=<rule>. Bu görevin amaçları için kural her zaman olacaktır B3/S23. Bu çizgiyi işlemeden önce sıyrılması gereken boşluklar içerebilir (tabii ki, bu çizginin hiç işlemesi gerekli değildir).

İlk satırdan sonraki yorum dışı satırlar tek bir dize olarak değerlendirilmelidir. Bu yalnızca ondalık basamak, karakterden oluşmalı $, bve o, ve satır sonları ve bir rakam ile sona ermez. Satır sonları dikkate alınmaz, ancak satır sonlarının rakam dizelerini engellemeyeceğini varsayabilirsiniz.

Bu, tek bir kişi tarafından sonlandırılabilir !.

bölü bir hücreyi otemsil eder, canlı bir hücreyi $temsil eder ve bir satırın sonunu temsil eder. Ondalık bir sayı, aşağıdaki sembolün, bunu birçok kez tekrar ediyormuş gibi ele alınması gerektiğini gösterir.

Düz metin desen kodlaması

Diğer seçenek, deseni burada açıklanan başka bir düz metin biçiminde okumaktır . Bu kodlamada, off hücreler tire ile temsil edilir ve hücreler üzerinde, satırları ayıran yeni çizgilerle büyük harf Os ile temsil edilir.

Yorum içermeyen tüm satırların kısa çizgi ile eşit uzunluğa getirileceğini varsayabilirsiniz.

İle başlayan satırlar yorumdur !ve dikkate alınmaz.

Bazı test durumları

RLE:

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

plaintext:

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

Sonuçlar:

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

plaintext:

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

Sonuçlar:

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!

plaintext:

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

Sonuçlar:

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!

plaintext:

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

Sonuçlar:

Pentadecathlon 1

Bonus

Her iki giriş biçimini de destekliyorsanız ([ .rlerle dosyaları ve .cellsdüz metin için dosya uzantısını kullanarak - diğer uzantıların nasıl okunacağını tanımlayın] veya bunlar arasında ayrım yapmak için bir komut satırı bayrağı kullanın) puanınızdan% 5 oranında bir puan alabilirsiniz.


Peki yaOOO.OO\n....OO
Akangka

@HristiyanIrvan Peki, bu istikrarlı bir kalıp değil, bu yüzden zaten girdi olarak verilmez.
SuperJedi224

Yanıtlar:


13

Haskell, 2417 bayt

Bu oldukça uzun sürdü ve hala birkaç hata var, ama işe yarayan birkaç numara buldum, buna değdi.

Notlar:

  • Yalnızca STDIN'ye iletilen düz metin biçimini kabul eder.
  • O (n ^ 20) zamanı gibi bir şey alır
  • Yorum dışı satırlardaki karakter sayısının (belirli bir girdi içinde) sabit olduğunu, örneklerde olduğu gibi olduğunu varsaydım.
  • En çılgın numara, dizilerin oluşturulması için kalıpların nasıl açıldığı, elemanların pozisyonlara (sütun numarası) modulo (çıktının uzunluğu) çekilmesiydi.

Birkaç temel fikri birleştiriyor:

  • desenler ve simetriler önceden hesaplanabilir
  • tek bir desen, boyutları bilinen bir tamsayıya paketlenebilir
  • tüm alt materyalleri bulmak kolaydır
  • eşitlikleri saymak kolaydır

İşte kod:

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

İşte daha sonra haskell programı tarafından açılmış olan formatta 0,1'lerin bir dizisini paketlemek için kullanılan Mathematica kodu:

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

İşte kodun daha eksiksiz bir şekilde çözülmesi:

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

PPCG'ye Hoşgeldiniz! Bunu henüz denemedim ama etkileyici görünüyor. 1!
bir

Bu çok etkileyici, +1!
kedi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.