Golf Paterson'ın Solucanları


11

Paterson'ın solucanları , sonsuz bir üçgen ızgarada bulunan bir tür hücresel otomattır ve her adımda bir yönde dönerler ve bir birimi hareket ettirirler. Tanımlayıcı özellikleri, asla aynı noktayı iki kez geçememeleri ve aynı çevreyle her karşılaştıklarında aynı kararı vermeleridir. Bir solucan, kuyruğu 3'te ve başı bu altıgenin merkezinde bulunan her zaman kendi bakış açısıyla "görür":

Vikipedi'den görüntü

Örneğin, solucanı kurallarla düşünün:

  1. 0, 1, 2, 4 ve 5'in tümü boşsa, 2. yönde hareket edin
  2. 0, 1, 4 ve 5 boşsa ve 2 doluysa, 0 yönünde hareket edin
  3. 0, 1 ve 5 boşsa ve 2 ve 4 doldurulmuşsa, 0 yönünde hareket edin

Bu, aşağıdaki yolla sonuçlanır (Wikipedia'dan):

Solucan yolu

Solucan kendini tüm çevrenin dolu olduğu bir durumda bulursa, sona erer.

Giriş

Bir sayı listesi. N'inci sayı, solucanın karar vermesi gereken yeni durum hakkında hangi kararı vermesi gerektiğini belirtir. Çevresinden biri hariç tümü doldurulursa, boş olan tek yönde hareket etmesi gerektiğini unutmayın. Bu bir "karar" olarak sayılmaz ve bir sayı tüketmez. Yukarıda gösterilen örnek solucanı oluşturmak için girdi olacaktır [2, 0, 0]. Girdinin, yolunu sonlandıran ve geri çekmeyen bir solucan üreteceği garanti edilir ve girdi asla çok kısa olmaz.

Çıktı

Solucanın başının nerede olduğunu gösteren koordinatların bir listesini çıktılar (1, 0). Yukarı ve sağa hareket etmeyi sadece y-değerinde bir azalma, ama yukarı ve sola hareket etmeyi x-değerinde bir azalma ve y-değerinde bir azalma olarak değerlendireceğiz. Örneğin, örnek giriş için yolun çıktısı

(1, 0), (1, 1), (0, 0), (-1, -1), (0, -1), (0, 0), (0, 1), (-1, 0), (0, 0)

Test senaryoları

Testleri çalıştırmak için javascript snippet'ini de kullanabilirsiniz.

[2,0,0]: (1,0),(1,1),(0,0),(-1,-1),(0,-1),(0,0),(0,1),(-1,0),(0,0)
[1,0,4,0,1,5]: (1,0),(2,1),(2,2),(1,2),(0,1),(0,0),(0,-1),(1,-1),(2,0),(2,1),(3,1),(4,2),(4,3),(3,3),(2,2),(1,1),(1,0),(2,0),(3,1),(3,0),(4,0),(5,1),(5,2),(4,2),(3,2),(2,1),(1,1),(0,0),(-1,0),(-2,-1),(-2,-2),(-1,-2),(0,-1),(1,0),(1,-1),(2,-1),(3,0),(4,1),(4,2),(5,3),(5,4),(4,4),(3,3),(3,4),(2,4),(1,3),(1,2),(1,1),(0,1),(-1,0),(-1,1),(-2,1),(-3,0),(-3,-1),(-2,-1),(-1,-1),(0,0)
[1,0,5,1]: (1,0),(2,1),(2,2),(1,2),(0,1),(0,0),(0,-1),(1,-1),(2,0),(2,1),(3,2),(3,3),(2,3),(1,2),(0,2),(-1,1),(-1,0),(0,0),(1,1),(1,2),(1,3),(0,3),(-1,2),(-1,1),(-2,0),(-2,-1),(-1,-1),(0,0)
[2,0,1,0]: (1,0),(1,1),(0,0),(-1,-1),(0,-1),(0,0),(-1,0),(-1,-1),(-1,-2),(0,-1),(1,0),(2,1),(1,1),(0,1),(0,0)

Aşağıdaki aceleyle monte edilmiş (muhtemelen buggy) program solucanları gösterecektir:


2
Önerilen test örneği : p (Bu [1,0,4,2,0,1,5].)
Arnauld

Girişi ters sırayla alabilir miyiz?
Arnauld

1
@Olum emin görünüyor emin
soktinpk

Yanıtlar:


4

JavaScript (ES6),  261, 250  249 bayt

Giriş listesini ters sırayla alır. çiftlerinin bir listesini döndürür .[x,y]

a=>(G=[[[x=1]]],v=[0,1,1,0,-1,-1],F=y=>[[x,y],...v.every((_,i)=>k^=g(o+i)[q%3]<<i,k=63,g=o=>(r=G[Y=y-o%2*v[q=(o+3)%6]]=G[Y]||[])[X=x-o%2*v[-~q%6]]=r[X]||[])?F(y+v[g(o+=F[k]|=1/F[k]?0:k&~-k?a.pop():31-Math.clz32(k))[q%3]=1,o%6],x+=v[-~o%6]):[]])(o=0)

Çevrimiçi deneyin!

Bu aslında demo snippet'inin bir limanıdır.


4

K (ngn / k) , 115 bayt

D,:-D:2\6 3;f:{d::0;m::2/=6;X::(!6),x;{m::?m,p:2/^(+':x)?(2*h:*|x)+/:D 6!d+!6;$[(~p)|^c:X m?p;x;x,,h+D 6!d+:c]}/,1 0}

(işlev adlandırma bölümünü saymamak, f:)

Çevrimiçi deneyin!

D,:-D:2\6 3 altı kardinal yönü oluşturur (1 0;1 1;0 1;-1 0;-1 -1;0 -1)

d::0 mevcut yön, bir indeks modu 6 olarak kullanılan D

m::2/=6ilk solucan hafızasını oluşturur 32 16 8 4 2 1. her sayının bitleri çevreyi kodlar (0 = ziyaret edilen segment; 1 = ziyaret edilmemiş). başlangıçta myalnızca belirsiz ortamlar içerir - tek bir çıkışın olduğu ortamlar.

X::(!6),xsolucanın kurallarıdır. biz 0 1 2 3 4 5intial açık belirsiz çevresi maç için tercih m.

{... içeren 1 elemanlı bir listeyle başlayan }/,1 0fonksiyon yakınsama kadar uygulayın . liste solucan tarafından ziyaret edilen koordinat çiftlerini içerecektir.{ }1 0

D 6!d+!6dsaat yönünde başlayan ve saat yönünde dönen altı kardinal yön

h:*|x argümanın sonuncusu, yani solucan başının pozisyonu

(2*h:*|x)+/:D 6!d+!6kafanın koordinatlarını 2 ile çarpın ve ana yönleri ekleyin. noktalar arasındaki segmentleri temsil etmenin yolu budur.

+':x bitişik ziyaret edilen noktaların çiftlerini ekleyin - bu bize aralarındaki segmentlerin temsillerini verir

^(... )?... kafanın çevreleyen bölümlerinden hangilerinin henüz ziyaret edilmediğini öğrenin

p:2/ ikili kodlama ve atama p

m::?m,pekleme için mve farklı, yani ekleme tutmak piçin myalnızca poluşmazm

$[... ;... ;... ]if-then-else

c:X m?pdizinini bulmak piçinde mve bir endeks olarak kullanabilirsiniz X. sınır dışı endeksleme sonuçları 0N("null")

$[(~p)|^c:X m?p;x;... ]eğer p0 ise (çıkış yolu yok) veya cise 0N, xyakınsamaya zorlayacak ve döngüyü durduracak şekilde geri dönün

x,,h+D 6!d+:cbaşka yeni kafa eklemek xve tekrar

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.