Sıhhi Tesisat Rastgele Yolları


23

Üç tam sayı, genişlik w, yükseklik hve adım sayımı alan bir program veya işlev yazın s. Bir sigara kendini kesen çizim olacaktır rasgele yürüyüş s bir uzun adımlar 5*wile 5*hpiksel her 5 5 tarafından piksel hücresi ya boş (saf bej) 'dir görüntü veya bu oniki basit "boru" biri:

genişletilmiş borular

Yukarıdaki resim ayrıntı göstermek için büyütülmüş. İşte gerçek boyuttaki borular:

borular

(Gri çizgiler sadece boru tiplerini ayırmak içindir.)

Rastgele yürüyüş, bir boru uç noktasında (dört dört boru tipinden biri) başlayıp başka bir boru uç noktasında biten tek bir kesintisiz boru yolu olacaktır.

Boş bir başla wile hızgara ve rasgele başlangıç noktası olduğu bir hücre seçin. Ardından, başlamak ve karşılık gelen boru uç noktasını çizmek için dört yönden birini rasgele seçin. Bu başlangıç ​​hücresi yürüyüşünüzdeki ilk adımı işaretler ve her yeni bir hücre çizdiğinizde veya mevcut bir adımın üzerine yazıldığında, atılan başka bir adım olarak sayılır.

Şimdi, art arda, seçilen yön geçerliyse uygun boru hücresini çizerek rasgele sağa, sola veya düze gitmeyi seçin. Tam sadım yolu oluşuncaya kadar bir yönün geçerli olup olmadığını geri izleyin ve yeniden seçin . Yol, yolun izlediği rotaya bağlı olarak, şebekenin herhangi bir yerinde olabilecek bir boru uç noktasıyla bitmelidir.

Sadece iki düz boru hücresinin üzerine yazılabileceğini ve bunun tersi yöndeki düz boru hücresi tarafından yazılabileceğini not etmek çok önemlidir, sonuç kesişme hücresidir. Aksi takdirde, tüm borular boş hücrelere yerleştirilmelidir.

Bir kavşak çizildiğinde, yolun başlangıç ​​hücresinden daha ileride olan kısmı üstüne çizilmelidir.

Size kalmış olup olmadığı ızgara vardır periyodik sınır şartları (PBC), yani ızgara bir tarafını çıkan bir boru diğer tarafta çıkacaktır olsun. PBC olmadan şebeke sınırı, diğer borular gibi koyabileceğiniz bir engel olarak sayılır.

Özel durumlar

  • s0 olduğunda , hiçbir boru çizilmemeli ve çıktı görüntüye 5*wgöre boş olmalıdır 5*h(yani tüm bej).
  • s1 ne zaman bir tek boru sapı

    genişletilmiş boru saplaması(Gerçek boyut: boru saplaması)

    rastgele seçilen başlangıç ​​hücresinde çizilmelidir.

Diğer detaylar

  • sEn fazla w*hbunun bir yolun her zaman mümkün olacağı varsayılabilir . (Kesişimler nedeniyle daha uzun yollar mümkün olsa da)
  • wve hher zaman olumlu olacak.
  • Tüm rastgele seçimler eşit olarak rasgele olmalıdır . örneğin, problemi kolaylaştırsa bile, mümkün olduğunda kavşak yapmaktan kaçınmamalısınız. Sözde rasgele sayı üreteçlerine izin verilir.
  • Siyah, mavi ve bej yerine görsel olarak farklı üç renk kullanılabilir.
  • Çıktı resimleriniz, pozitif bir tamsayı 5*w*kolan 5*h*kpikseller şeklinde olacak şekilde büyütülebilir k. (Gönderdiğiniz örnekleri büyütmek, 1’iniz olsa bile önerilir k.)
  • Yaygın kayıpsız herhangi bir görüntü dosyası formatı kullanılabilir ve görüntü bir dosyaya kaydedilebilir, görüntülenebilir veya stdout'a işlenmemiş olarak serpilir.

Bayt cinsinden en kısa kod kazanır.

Örnekler

(Hepsi% 500 oranında büyütüldü.)

Giriş ise w=2, h=1, s=0o zaman çıkış her zaman olacaktır:

Girdi w=2, h=1, s=1o zaman çıktı eşit şansla bu görüntülerden biri olacaktır:

Giriş ise w=2, h=1, s=2o zaman çıkış olacaktır.

veya muhtemelen

Kılavuzun PBC olduğu varsayılırsa.

(Gibi yolu başlatmak, ikinci bir adım imkansız yapacağını unutmayın .)


w=3, h=2, s=6PBC'nin farz ettiği olası bazı çıktılar :


w=3, h=3, s=9PBC'nin varsayıldığı gibi olası bir çıktı şöyledir :

Kesişim iki basamak olarak sayıldığından yolun tüm hücreleri kapsaması gerekmediğine dikkat edin. Ayrıca, köşe kesişme noktasının başlangıç ​​hücresi olduğunu anlayabiliriz, çünkü kesişme üst geçidi daha sonra çizilmiş olmalıdır. Böylece yapılan rastgele seçimler dizisini çıkartabiliriz:

start at top left, facing east
go straight
go right
go right
go right
go straight
go left
go right
end

Son olarak, burada örnekleridir w=4, h=5, s=20ve w=4, h=5, s=16:


1
Bütün fikir sadece rastgele bir yürüyüş değil mi?
Akangka

Satır 2: You will be drawing a non-self-intersecting random walk... kendini kesişen mi yoksa değil mi?
edc65

@HristiyanIrwan Pek sayılmaz. Rastgele yürüyüşler genellikle kendilerine katlanabilir veya kendilerini hiçbir şekilde kestiremez. Bu, kesişmeler yapıldığı için benzersiz bir durumdur, ancak aynı zemine geri dönmek sayılmaz. Ve evet bu bir bilim-sanat biçiminde olabilir ya da bir şey ama ben güzel görünümlü görüntüler yapma fikrini seviyorum.
Calvin'in Hobileri

2
@HristiyanIrwan Ben zaten "Ve evet, bu bir sanat-sanat biçiminde olabilir ama ben güzel görünümlü görüntüler yapma fikrini sevdim" dediğimde cevap verdim. Ben sanatla uğraşmamayı seçiyorum.
Calvin'in Hobileri

1
"Düğümlere" izin verilir mi?
aditsu

Yanıtlar:


4

CJam, 274

q~:K;:B;:A;{0aA*aB*:M5*5f*:I;K{[Bmr:QAmr:P]5f*:R;3Ym*{R.+:)2{1$0=I=2$W=@tI@0=@t:I;}:F~}/R2f+1FK({MQ=P=:EY4mr:D#&1{{MQMQ=PE2D#+tt:M;}:G~7,1>[W0_1_0_W]2/D=:Off*{[QP]5f*2f+.+_:H1F_OW%.+2FOW%.m2F}/H2FO~P+:P;Q+:Q;MQ=P=:E_5YD2%-*=!JK2-=+*1{D2+4%:D;G}?}?}fJ]}0?}g'P2NA5*SI,N2NI:+N*

Çevrimiçi deneyin

PBC kullanır, PGM formatında çıkar. :+Tarayıcıda daha iyi bir görsel çıktı elde etmek için yakın ucunu kaldırabilirsiniz .

Daha büyük girişler için, özellikle adım sayısı bölgeye yakınsa, çok yavaştır.

Giriş için örnek sonuç 4 3 10(% 500 ölçekli):

örnek

Kısa açıklama:

Genel yaklaşım:

  • başarılı olana kadar aşağıdaki adımları tekrarlayın:
  • 2 matris başlat: her hücrede hangi tarafın kullanıldığını ve bir görüntü için bir kayıt kullanıldığını
  • s = 0 ise, bittikten sonra:
  • rastgele bir hücre seçin ve bir kare çizin, sonra aşağıdaki s-1 kere yapın:
  • rastgele bir yön seçin; bu taraf zaten kullanılıyorsa, başarısız olun ve baştan başlayın
  • Kullanılan tarafı işaretleyin ve görüntüdeki asıl boruyu çizin (uzunluktaki 3 bitişik çizgiyi çizin, geçerli hücrenin merkez pikselinden "hemen sonra", sonra borunun ucunu kapatmak için bir nokta ekleyin)
  • Mevcut pozisyonu güncelle (bir sonraki hücreye geç)
  • hücrenin boş olup olmadığını kontrol edin veya geçerli bir geçit; değilse, başarısız olun ve baştan başlayın
  • tarafı bu hücrede kullanıldığı gibi ters yönde işaretleyin, sonra döngüye devam edin

1

QBasic, 517 516 bayt

RANDOMIZE TIMER
SCREEN 9
INPUT w,h,s
1CLS
IF s=0GOTO 9
x=5*INT(RND*w)
y=5*INT(RND*h)
GOSUB 7
FOR k=1TO s-1
r=INT(RND*4)+1
a=x+5*((r=2)-(r=4))
b=y+5*((r=1)-(r=3))
c=(POINT(a,b+2)*POINT(a+4,b+2)+POINT(a+2,b)*POINT(a+2,b+4))*(0=POINT((a+x)\2+2,(b+y)\2+2))
IF((0=POINT(a+2,b+2))+c)*(a>=0)*(b>=0)*(a<5*w)*(b<5*h)=0GOTO 1
x=a
y=b
GOSUB 7
o=1AND r
p=x-2+3*o-5*(r=2)
q=y+1-3*o-5*(r=1)
u=p+3-o
v=q+2+o
LINE(p,q)-(u,v),7,B
LINE(p+o,q+1-o)-(u-o,v-1+o),1
NEXT
9IF c GOTO 1
END
7LINE(x+1,y+1)-(x+3,y+3),7,B
PSET(x+2,y+2),1
RETURN
  • Alır w, hve skullanıcı girişinden, virgülle ayrılmış.
  • Çıktı ekranda çizilir. Program bir çözüm ararken, geçmişte titreyen kısmi çözümler görebilirsiniz.
  • Periyodik sınır koşullarını kullanmaz. Borunun yarısının şebekenin bir tarafında ve diğer yarısında endişelenmenize gerek kalmadan bağlantı borularının çizilmesini ve test edilmesini daha kolay buldum.

Buradaki yaklaşım, her adımda rastgele bir yön denemek ve geçersiz bir hareketle sonuçlanırsa baştan baştan başlamaktır. Yönleri belirlendiği gibi boruları çizeriz ve POINTgeçerlilik koşullarımız için ekrandaki noktaları test etmek için kullanırız. Bir taşıma, şebekenin sınırları dışına çıkmazsa geçerlidir ve:

  1. Taşınacak hücre boş; veya
  2. Her ikisi de
    1. Taşınmış hücre, yatay veya dikey olarak düz bir borudan geçen bir boru içerir ve
    2. Yeni boru bölümü mevcut boru bölümünü iki katına çıkarmıyor

Gibi aditsu en CJam cevap bu kod çok yavaş olduğunu ve eğer beyni uyuşturan yavaş olabilir sönemli bir bölümü olduğunu w*h. QB64 kurulumumda, 5,5,19derhal derhal bir yanıtla geliyor , ancak beklemeye istekli olduğumdan daha uzun sürüyor 5,5,20.

Daha büyük / daha yoğun paketlenmiş örnekler çalıştırmak istiyorsanız, derinlemesine ilk aramayı kullanan orijinal yaklaşımım . Bir kuyruklu 300 ekstra bayt pahasına, çok daha verimli.

RANDOMIZE TIMER
SCREEN 9
INPUT w,h,s
DIM t(s),m(s)
0
FOR z=1TO s
t(z)=-1
NEXT
i=5*INT(RND*w)
j=5*INT(RND*h)
k=1
1CLS
IF s=0GOTO 9
x=i
y=j
GOSUB 7
FOR z=1TO k-1
r=m(z)
GOSUB 6
x=a
y=b
GOSUB 7
o=1AND r
p=x-2+3*o-5*(r=2)
q=y+1-3*o-5*(r=1)
u=p+3-o
v=q+2+o
LINE(p,q)-(u,v),7,B
LINE(p+o,q+1-o)-(u-o,v-1+o),1
NEXT
IF c*(k=s)THEN k=k-1:GOTO 1 ELSE IF k=s GOTO 9
IF k<1GOTO 0
IF t(k)>=0GOTO 4
t(k)=0
f=30
WHILE f
r=INT(RND*4)+1
IF f AND 2^r THEN t(k)=t(k)*5+r:f=f-2^r
WEND
4r=t(k)MOD 5
m(k)=r
t(k)=t(k)\5
GOSUB 6
c=(POINT(a,b+2)*POINT(a+4,b+2)+POINT(a+2,b)*POINT(a+2,b+4))*(0=POINT((a+x)\2+2,(b+y)\2+2))
IF((0=POINT(a+2,b+2))+c)*(a>=0)*(b>=0)*(a<5*w)*(b<5*h)THEN k=k+1 ELSE IF t(k)>0GOTO 4 ELSE t(k)=-1:k=k-1
GOTO 1
6a=x+5*((r=2)-(r=4))
b=y+5*((r=1)-(r=3))
RETURN
7LINE(x+1,y+1)-(x+3,y+3),7,B
PSET(x+2,y+2),1
RETURN
9

Girişler için örnek çıktı 10, 10, 100, gerçek boyut:10x10 rasgele tesisat

Bir hâlâ meraklısı sürümü bulunabilir bu özünden . Doldurulmadan ve iyice yorumlanmanın yanı sıra, çıktıyı sabit bir faktörle ölçeklendirir ve DFS algoritmasını işte izlemenizi sağlayarak adımlar arasında belirli bir gecikme sağlar. İşte bir örnek çalışma:

lüks tesisat sıhhi

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.