จำลองการจับกลุ่มที่เรียบง่าย


27

Redstone เป็นเนื้อหาในเกม Minecraft และใช้สำหรับการคุมกำเนิดที่ซับซ้อนหลายอย่าง สำหรับโปรแกรมนี้คุณจะต้องจำลองสามรายการเท่านั้น: ลวด Redstone (บันทึกด้วย R), ไฟฉาย Redstone (บันทึกด้วย T) และบล็อก (บันทึกด้วย B)

นี่คือรายการของกฎพื้นฐานเกี่ยวกับวิธีการจับกลุ่มทำงาน:

A redstone torch sends power to any adjacent redstone wire.
TRRRR
 ^This redstone wire is powered.

Redstone wire can only hold power for 15 blocks.
TRRRRRRRRRRRRRRRR
                ^This last wire is unpowered, because the torch is >15 blocks away.

A block is said to be powered if a powered redstone wire is found adjacent to it.
TRRRB
    ^This block is powered.

If a block next to a redstone torch is powered, then the torch stops emitting power.
T
R
R
R
B <This block is powered.
T <This redstone torch does not emit power because of the block next to it.
R <This redstone is unpowered because the torch is not providing power.
R

อินพุตจะได้รับในสองมิติอาร์เรย์ขนาด 64x64 เช่นนี้:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

มีการรับประกันว่าอินพุตจะไม่มี "นาฬิกา" หรือการจับกลุ่มขับเคลื่อนโดยไฟฉายที่ชี้ไปยังบล็อกที่เปิดไฟฉาย จะมีเพียงหนึ่งวงจร redstone ในทุกอินพุต

โปรแกรมของคุณจะต้องเปลี่ยนตัวละครแต่ละตัวให้เป็น 1 หรือ 0, 1 เพื่อระบุว่ารายการนี้เป็นพลังงาน / เปล่งพลังงานและ 0 ถ้าเป็นพลังงาน / ไม่เปล่งพลังงาน

อินพุตนี้ควรมีเอาต์พุตนี้:

1111
   1
100000
1
111111111
        1
   001111

นี่เป็นรหัสสำหรับการเล่นกอล์ฟดังนั้นรหัสที่สั้นที่สุดจะชนะเช่นเคย


1
คุณคาดหวังผลลัพธ์แบบใดสำหรับสถานการณ์เช่น"TRR\nB B\nRRT"นี้
โฮเวิร์ด

111\n0 1\n000คือผลลัพธ์ มันดูเหมือนจะเป็นเสียงภายในกฎ ฉันจะใส่ข้อ จำกัด การป้อนข้อมูลที่บอกว่าคุณไม่สามารถมีสถานการณ์ใด ๆ เช่นTRR B R RRRที่มันกะพริบซ้ำ ๆ
beary605

1
เราสามารถสมมติว่าแต่ละอินพุตอาร์เรย์มีวงจรสมบูรณ์เพียงหนึ่งวงจรที่ทำงานจากบนลงล่างตามตัวอย่างของคุณหรือเราต้องใช้รหัสสำหรับวงจรแยกหลาย ๆ ตัวเริ่มต้นที่ใดก็ได้ในอาร์เรย์?
เกรแฮม

@ Graham: จะมีวงจร Redstone เพียงวงจรเดียวสำหรับแต่ละอินพุต
beary605

1
รู้ว่าเกม Minecraft ฉันคิดว่าในตัวอย่างของคุณเมื่อบล็อกในบรรทัดที่ 2 ไม่ได้หยุดคบเพลิงที่อยู่ติดกันจากการให้พลังงาน (Redstone ไม่ได้เชื่อมต่อกับบล็อก) นี่เป็นข้อผิดพลาดหรือการทำให้เข้าใจง่ายขึ้นหรือไม่
tomsmeding

คำตอบ:


4

Haskell, 400

import Data.Char
import Data.List
f x=[(++[x]).tail,(x:).init]
h(' ':_)=' '
h('T':s)=if elem 'b's then 'T'else 't'
h('t':s)=h$'T':s
h('B':s)=if any(`elem`s)['e'..'s']then 'b'else 'B'
h('b':s)=h$'B':s
h(_:s)=max 'd'$chr$ord(maximum s)-1
o ' '=' '
o c|elem c"dTB"='0'
o _='1'
a=(map.map)o.(!!(64^2+16)).iterate(map(map h.transpose).transpose.(\l->[g l|g<-id:f(map(const ' ')$head l)++map map (f ' ')]))

map(map h.transpose).transpose.(\l->[g l|g<-id:f(map(const ' ')$head l)++map map (f ' ')])แทนที่แต่ละไทล์โดยรายการของตัวเองตามด้วยเพื่อนบ้านทั้งสี่จากนั้นแม็พที่ผ่าน h h พูดสำหรับแต่ละกระเบื้องว่ามันตอบสนองต่อเพื่อนบ้านอย่างไร: Torches ปิด ('T' แทน 't') เมื่อมีบล็อกไฟฟ้า ('b') อยู่ใกล้ ๆ สายไฟ ('d' สำหรับการตายผ่าน 's') คัดลอกไม่สมบูรณ์ เพื่อนบ้านที่ทรงพลังที่สุดของพวกเขา (แม้ว่าจะแย่กว่าตาย) ฯลฯ

iterateทำซ้ำขั้นตอนนี้ซ้ำ(!!(64^2+16))ออกซ้ำวงจร acyclic เสร็จบรรจบกันและฉันก็เขียนมันแบบนั้นเพื่อให้ขอบเขตที่ใช้งานง่ายไม่ให้ลงจอดที่ 400


4

Python, 699

นี่เป็นเพียงการผ่านที่รวดเร็ว (หมดเวลาแล้ว) มันอาจจะสามารถเล่นกอล์ฟได้มากขึ้น

import sys
m=[list(x)for x in sys.stdin.read().split('\n')]
e=enumerate
S=set
s=lambda x:S([(r,c)for r,i in e(m)for c,j in e(i)if j==x])
q=S()
t=s('T')
b=s('B')
n=s('R')
def d(o,r,c,i,h,q):
 if i<0:return 0
 o[(r,c)]=1
 for p in[(r+1,c),(r-1,c),(r,c+1),(r,c-1)]:
  if p in q or(p in b and not(r,c)in n):continue
  if(r,c)in b and p in t-q:
   x=S([p])
   q|=x
   o[p]=0
   return 1
  if p in h or not p in o:continue
  h|=S([p])
  if not d(o,p[0],p[1],i-1,h,q):return 1
g=1
while g:
 o=dict(zip(b,[0]*len(b))+zip(n,[0]*len(n))+zip(q,[0]*len(q)))
 g=0
 for x,y in t:
  if not(x,y)in q and d(o,x,y,15,S(),q):g=1
for p in o.keys():m[p[0]][p[1]]=o[p]
print"\n".join(map(lambda x:"".join(map(str,x)),m))

อ๋อตัวอย่างเช่นคุณสามารถใช้และสร้างf=set l=lambda x:zip(x,[0]*len(x))คุณยังคงมีมากกว่า 700 ตัวอักษร ... or not (a,z)in oนอกจากนี้คุณยังเหลือพื้นที่ไร้ประโยชน์ที่
Morwenn

คุณต้องการพื้นที่ว่างหลังจากพิมพ์คำสั่งของคุณหรือไม่?
Zacharý

@ZacharyT คุณพูดถูก ขอบคุณ!
ESultanik

นี่ได้ถูกกล่าวไปแล้ว แต่f=setจะโกนหนวดสักสองสามตัวแล้วคุณก็จะมีตัวละครที่ไร้ประโยชน์ @not (a,z)in o
Zacharý

ใช้แท็บและช่องว่างเพื่อประหยัดการเยื้อง
mbomb007

4

Python 2, 556 ไบต์

c=' 0';L=len;M=map;q=list;r='B';s='16';t='T';u='0';E=enumerate
b=[q(M(lambda x:x+[u,s][x==t],q(w[:-1])))+[c]*(64-L(w))for w in open('redstone.txt')]
k=lambda h,l,z:max(q(M(lambda x:[int((x or c)[1:]),0][l^((x or c)[0]==h)],z)))
def v(d=0):
 for e,f in E(b):
    for g,G in E(f):z=[e!=0and b[e-1][g],g<L(f)-1and f[g+1],e<L(b)-1and b[e+1][g],g and f[g-1]];j=G;i=j[0]+str([[s,u][k(r,1,z)>0],4,4,k(t,0,z),0,max(1,k(r,0,z))-1][ord(j[0])%7]);b[e][g]=i;d=d|(i!=j)
 return d
while v():0
for f in b:print''.join(M(lambda j:[' ',`int(j[1:]!=u)`][j[0]!=' '],f))+'\n'

เห็นมันในทางปฏิบัติ

  • สมมติว่าแต่ละบรรทัดในอินพุตสิ้นสุดด้วยการขึ้นบรรทัดใหม่
  • ส่งออกผ่าน print()
  • เอาต์พุตแต่ละบรรทัดลงท้ายด้วย whitespace จำนวนมากและขึ้นบรรทัดใหม่

  • จำนวนไบต์ที่บันทึกไว้ต้องขอบคุณ @ mbomb007 (# 34718)
  • บันทึก 1 ไบต์ขอบคุณ @ZacharyT (# 55550)

คุณไม่จำเป็นต้องมีอินพุตและเอาต์พุตผ่านไฟล์ คุณอาจจะใช้ stdin และ stdout ด้วยและinput() printนอกจากนี้ยังเป็นเช่นเดียวกับstr(int(bool(j[1:]!=u))) `int(j[1:]!=u)`
mbomb007

@ mbomb007 ก็ไม่มากก็ยังต้องแต่จุดที่ดีเกี่ยวกับstr( bool(
Quelklef

`x`(โดยใช้ backticks เป็นนามแฝงสำหรับrepr) เหมือนกับstr(x)(สำหรับเลขจำนวนเต็มขนาดเล็กอย่างน้อยมันแตกต่างกันไปสำหรับวัตถุบางชนิด longs, generators ฯลฯ ) กอล์ฟอื่น ๆ : เป็นเช่นเดียวกับif g!=0 if gคุณสามารถมีได้k=lambda h,l,z:max(...
mbomb007

@ mbomb007 Backticks ไม่ได้มีไว้สำหรับ Py3และฉันไม่มี 2 บนพีซีนี้ ถ้าฉันติดตั้งหรือเปลี่ยนคอมพิวเตอร์ฉันจะเพิ่มมันขอบคุณ
Quelklef

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