เส้นทางสุ่มท่อประปา


23

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้เวลาในสามจำนวนเต็มความกว้างw, ความสูงและนับขั้นตอนh sคุณจะได้รับการวาดภาพที่ไม่ใช่ตัวเองตัดสุ่มเดิน sก้าวยาว ๆ บน5*wโดย5*hพิกเซลภาพที่ทุก ๆ 5 5 เซลล์พิกเซลเป็นทั้งว่างเปล่า (สีเบจบริสุทธิ์) หรือหนึ่งในสิบสองเหล่านี้ง่าย "ท่อ":

ท่อขยาย

ภาพด้านบนถูกขยายเพื่อแสดงรายละเอียด นี่คือขนาดท่อจริง:

ท่อ

(เส้นสีเทาเป็นเพียงการแยกประเภทท่อ)

การเดินแบบสุ่มจะเป็นเส้นทางไปป์แบบต่อเนื่องเดี่ยวที่เริ่มต้นที่จุดปลายท่อหนึ่ง (หนึ่งในสี่ประเภทท่อด้านล่าง) และสิ้นสุดที่จุดปลายท่ออื่น

เริ่มต้นด้วยการเว้นว่างwตามhกริดและสุ่มเลือกเซลล์หนึ่งเซลล์เพื่อเป็นจุดเริ่มต้น จากนั้นสุ่มเลือกหนึ่งในสี่ทิศทางเพื่อเริ่มต้นและวาดจุดปลายท่อที่เกี่ยวข้อง เซลล์เริ่มต้นนี้ทำเครื่องหมายขั้นตอนแรกในการเดินของคุณและทุกครั้งที่คุณวาดเซลล์ใหม่หรือเขียนทับเซลล์ที่มีอยู่เดิมจะนับเป็นขั้นตอนอื่น

ทีนี้, ซ้ำ ๆ , เลือกสุ่มไปทางขวา, ซ้าย, หรือตรง, วาดเซลล์ท่อที่เหมาะสมหากทิศทางที่เลือกนั้นถูกต้อง. ย้อนกลับและเลือกใหม่หากทิศทางไม่ถูกต้องจนกว่าsเส้นทางขั้นตอนทั้งหมดจะเกิดขึ้น เส้นทางควรลงท้ายด้วยจุดปลายท่อซึ่งอาจอยู่ที่ใดก็ได้บนกริดขึ้นอยู่กับเส้นทางที่ใช้

มันสำคัญมากที่จะต้องทราบว่ามีเพียงเซลล์ท่อตรงสองเส้นเท่านั้นที่สามารถเขียนทับได้และเซลล์ท่อตรงที่มีทิศทางตรงข้ามเท่านั้นผลลัพธ์ที่ได้คือเซลล์แยก มิฉะนั้นจะต้องวางท่อทั้งหมดไว้ในเซลล์ว่าง

เมื่อวาดทางแยกส่วนหนึ่งของเส้นทางที่อยู่ถัดจากเซลล์เริ่มต้นจะถูกวาดไว้ด้านบน

มันขึ้นอยู่กับคุณหรือไม่ว่ากริดนั้นมีเงื่อนไขขอบเขตเป็นระยะ (PBC) หรือไม่เช่นว่าท่อที่ออกด้านหนึ่งของกริดจะออกมาในอีกด้านหนึ่งหรือไม่ หากไม่มี PBC ขอบเขตของกริดจะนับว่าเป็นสิ่งกีดขวางที่คุณสามารถวิ่งเข้าไปในท่อได้

กรณีพิเศษ

  • เมื่อsเป็น 0 ไม่มีท่อควรจะวาดและผลผลิตที่ควรจะเป็นที่ว่างเปล่า5*wโดย5*hภาพ (เช่นสีเบจทั้งหมด)
  • เมื่อsคือ 1 ท่อต้นขั้วเดียว

    ต้นขั้วท่อขยาย(ขนาดจริง: ท่อต้นขั้ว)

    ควรวาดที่เซลล์เริ่มต้นที่เลือกแบบสุ่ม

รายละเอียดอื่น ๆ

  • คุณอาจสันนิษฐานว่าsเป็นอย่างมากw*hดังนั้นเส้นทางจะเป็นไปได้เสมอ (แม้ว่าเส้นทางที่ยาวขึ้นอาจเป็นไปได้เนื่องจากทางแยก)
  • wและhจะเป็นบวกเสมอ
  • ตัวเลือกแบบสุ่มทั้งหมดต้องสุ่มอย่างสม่ำเสมอ เช่นคุณไม่ควรหลีกเลี่ยงการตัดกันเมื่อเป็นไปได้แม้ว่าจะทำให้ปัญหาง่ายขึ้น อนุญาตให้ใช้ตัวสร้างตัวเลขแบบหลอกได้
  • อาจใช้สีที่ต่างกันสามสีใด ๆ แทนสีดำสีน้ำเงินและสีเบจ
  • ภาพออกของคุณอาจถูกขยายเพื่อให้พวกเขาเป็นจริง5*w*kโดย5*h*kพิกเซลที่kเป็นจำนวนเต็มบวก (ขยายตัวอย่างใด ๆ ที่คุณโพสต์ขอแนะนำแม้ว่าคุณkจะเป็น 1)
  • อาจใช้รูปแบบไฟล์ภาพแบบไม่สูญเสียใด ๆ ร่วมกันและภาพอาจถูกบันทึกลงในไฟล์, แสดง, หรือแสดงข้อมูลดิบถึง stdout

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

ตัวอย่าง

(ขยายทั้งหมด 500%)

หากอินพุตเป็นw=2, h=1, s=0เอาต์พุตเอาต์พุตจะเป็น:

หากอินพุตเป็นw=2, h=1, s=1ผลลัพธ์จะเป็นหนึ่งในภาพเหล่านี้ที่มีโอกาสเท่ากัน:

ถ้าอินพุตเป็นw=2, h=1, s=2เอาต์พุตจะเป็น

หรืออาจจะเป็น

ถ้าสมมติว่ากริดมี PBC

(โปรดทราบว่าการเริ่มเส้นทางเช่นนี้จะทำให้ขั้นตอนที่สองเป็นไปไม่ได้)


นี่คือผลลัพธ์ที่เป็นไปได้สำหรับw=3, h=2, s=6สมมติว่า PBC:


นี่คือผลลัพธ์ที่เป็นไปได้สำหรับw=3, h=3, s=9สมมติว่า PBC:

โปรดสังเกตว่าเส้นทางไม่จำเป็นต้องครอบคลุมเซลล์ทั้งหมดเนื่องจากการแยกนับเป็นสองขั้นตอน นอกจากนี้เราสามารถอนุมานได้ว่าจุดสิ้นสุดของมุมคือเซลล์เริ่มต้นเนื่องจากสะพานลอยแยกต้องถูกวาดขึ้นหลังจากนั้น ดังนั้นเราสามารถสรุปลำดับของตัวเลือกแบบสุ่มที่ทำ:

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

ในที่สุดนี่คือตัวอย่างของw=4, h=5, s=20และw=4, h=5, s=16:


1
ความคิดทั้งหมดเป็นเพียงแค่การเดินสุ่มใช่มั้ย
Akangka

แถวที่ 2: You will be drawing a non-self-intersecting random walk... มันเป็นการตัดกันด้วยตนเองหรือไม่?
edc65

@ChristianIrwan ไม่จริงเหรอ การเดินสุ่มสามารถกลับมาเป็นสองเท่าได้เองหรือไม่ตัดกันเลยก็ได้ นี่เป็นกรณีพิเศษเนื่องจากมีการแยกส่วน แต่ไม่นับว่าเป็นการคำนวณซ้ำในพื้นที่เดียวกัน และใช่นี่อาจเป็นรูปแบบ ASCII หรืออะไรบางอย่าง แต่ฉันชอบความคิดในการสร้างภาพที่ดูดี
งานอดิเรกของ Calvin

2
@ ChristianIrwan ฉันตอบแล้วว่าเมื่อฉันพูดว่า "และใช่นี่อาจเป็นรูปแบบศิลปะ ASCII หรือบางอย่าง แต่ฉันชอบความคิดในการสร้างภาพที่ดูดี" ฉันเลือกที่จะไม่เกี่ยวข้องกับศิลปะ ASCII
งานอดิเรกของ Calvin

1
อนุญาต "นอต" หรือไม่
aditsu

คำตอบ:


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*

ลองออนไลน์

ใช้ PBC เอาต์พุตในรูปแบบ PGM คุณสามารถลบ:+ใกล้ถึงจุดสิ้นสุดเพื่อรับเอาท์พุท visual nicer ในเบราว์เซอร์

มันช้ามากสำหรับการป้อนข้อมูลที่ใหญ่ขึ้นโดยเฉพาะอย่างยิ่งหากการนับก้าวใกล้กับพื้นที่

ตัวอย่างผลลัพธ์สำหรับอินพุต4 3 10(ปรับสัดส่วน 500%):

ตัวอย่าง

คำอธิบายสั้น ๆ :

วิธีการทั่วไปคือ:

  • ทำซ้ำขั้นตอนต่อไปนี้จนสำเร็จ:
  • กำหนดค่าเริ่มต้น 2 เมทริกซ์: หนึ่งการบันทึกที่ด้านข้างจะถูกใช้ในแต่ละเซลล์และอีกอันสำหรับภาพ
  • ถ้า s = 0 เราเสร็จแล้ว:
  • เลือกเซลล์สุ่มและวาดสี่เหลี่ยมจากนั้นทำ s-1 ต่อไปนี้:
  • เลือกทิศทางแบบสุ่ม ถ้าด้านนั้นถูกใช้แล้วล้มเหลวและเริ่มต้นใหม่
  • ทำเครื่องหมายด้านที่ใช้แล้ววาดไปป์ที่เกิดขึ้นจริงในภาพ (วาดเส้น 3 เส้นที่อยู่ติดกันที่มีความยาว 6 เส้นเริ่มต้นทางขวา "หลัง" จุดศูนย์กลางพิกเซลของเซลล์ปัจจุบันจากนั้นเพิ่มจุดเพื่อครอบส่วนท้ายของท่อ)
  • อัปเดตตำแหน่งปัจจุบัน (ย้ายไปยังเซลล์ถัดไป)
  • ตรวจสอบว่าเซลล์ว่างเปล่าหรือมีการข้ามที่ถูกต้องหรือไม่ ถ้าไม่ล้มเหลวและเริ่มต้นใหม่
  • ทำเครื่องหมายด้านข้างในทิศทางตรงกันข้ามกับที่ใช้ในเซลล์นี้จากนั้นจึงดำเนินการวนรอบต่อไป

1

QBasic, 517 516 ไบต์

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
  • ใช้เวลาw, hและsจากการป้อนข้อมูลของผู้ใช้คั่นด้วยเครื่องหมายจุลภาค
  • เอาต์พุตถูกวาดบนหน้าจอ ในขณะที่โปรแกรมกำลังค้นหาโซลูชันคุณอาจเห็นโซลูชันบางส่วนกะพริบผ่านมา
  • ห้ามใช้เงื่อนไขขอบเขตเป็นระยะ ฉันพบว่ามันง่ายกว่าในการวาดและทดสอบการเชื่อมต่อท่อโดยไม่ต้องกังวลว่าครึ่งหนึ่งของท่ออยู่ที่ด้านหนึ่งของตารางและอีกครึ่งหนึ่งอยู่ที่อื่น

วิธีการที่นี่คือการลองใช้ทิศทางแบบสุ่มในแต่ละขั้นตอนและเริ่มต้นใหม่ตั้งแต่ต้นหากมีการเคลื่อนที่ที่ไม่ถูกต้อง เราวาดท่อตามทิศทางที่ตัดสินใจและใช้POINTเพื่อทดสอบคะแนนบนหน้าจอสำหรับเงื่อนไขความถูกต้องของเรา การเคลื่อนไหวนั้นถูกต้องหากไม่ได้อยู่นอกขอบเขตของกริดและ:

  1. เซลล์ที่ย้ายไปยังว่างเปล่า หรือ
  2. ทั้งสอง
    1. เซลล์ที่ย้ายไปยังมีท่อที่วิ่งผ่านทั้งในแนวนอนและแนวตั้งและ
    2. ส่วนไปป์ใหม่ไม่เพิ่มส่วนของไพพ์ที่มีอยู่เป็นสองเท่า

เช่นเดียวกับaditsu คำตอบของ CJamรหัสนี้จะช้ามากและสามารถเป็นใจ numbingly ช้าถ้าเป็นส่วนที่สำคัญของs w*hกับการตั้งค่า QB64 ของฉันมันมากับคำตอบสำหรับ5,5,19ธรรมทันที 5,5,20แต่จะใช้เวลานานกว่าที่ฉันก็เต็มใจที่จะรอ

หากคุณต้องการที่จะทำงานที่มีขนาดใหญ่ / ตัวอย่างบรรจุหนาแน่นมากขึ้นนี่คือวิธีการเดิมของฉันโดยใช้การค้นหาความลึกแรก มีประสิทธิภาพมากขึ้นด้วยค่าใช้จ่ายที่เพิ่มเป็นพิเศษ 300 ไบต์

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

ตัวอย่างเอาต์พุตสำหรับอินพุต10, 10, 100ขนาดจริง:ไฟฟ้าแบบสุ่ม 10x10

สามารถพบรุ่นที่นักเล่นยังคงอยู่ในส่วนสำคัญนี้ นอกจากจะถูก ungolfed และแสดงความคิดเห็นอย่างละเอียดแล้วมันจะขยายเอาต์พุตด้วยปัจจัยคงที่และช่วยให้การตั้งค่าล่าช้าระหว่างขั้นตอนช่วยให้คุณดูอัลกอริทึม DFS ในที่ทำงาน นี่คือตัวอย่างการเรียกใช้:

การใช้งานที่หรูหรา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.