Perl 5 , -p0
105 101 96 93 90 89 ไบต์
ใช้b
แทน1
อินพุต
ตรวจสอบให้แน่ใจว่าเมทริกซ์ใน STDIN ถูกยกเลิกด้วยการขึ้นบรรทัดใหม่
#!/usr/bin/perl -p0
s%b%$_="$`z$'";s:|.:/
/>s#(\pL)(.{@{-}}|)(?!\1)(\pL)#$&|a.$2.a#se&&y/{c/z />0:seg&/\B/%eg
ลองออนไลน์!
ใช้การทดแทน 3 ระดับ!
เวอร์ชัน 87 ไบต์นี้มีทั้งในรูปแบบอินพุตและเอาต์พุตที่ตีความได้ง่ายกว่า แต่ไม่สามารถแข่งขันได้เนื่องจากใช้อักขระต่างกัน 3 ตัวในเอาต์พุต:
#!/usr/bin/perl -0p
s%b%$_="$`z$'";s:|.:/
/>s#(\w)(.{@{-}}|)(?!\1)(\w)#$&|a.$2.a#se&&y/{c/z />0:seg&/\B/%eg
ลองออนไลน์!
เป็นการง่ายที่จะบันทึกไบต์อื่น ( s
ตัวแก้ไขregex ) ในทั้งสองเวอร์ชันโดยใช้อักขระ (ไม่ใช่ตัวอักษรและตัวเลข) ที่แตกต่างกันเป็นตัวยุติแถว (แทนที่จะขึ้นบรรทัดใหม่) แต่นั่นทำให้อินพุตไม่สามารถอ่านได้อีกครั้ง
มันทำงานอย่างไร
พิจารณาการทดแทน
s#(\w)(.{columns}|)(?!1)(\w)#c$2c#s
นี้จะได้พบกับตัวอักษรสองตัวที่มีความแตกต่างกันและติดกันในแนวนอนหรือแนวตั้งอื่น ๆ c
และแทนที่พวกเขาด้วย ในเขาวงกตที่มีเส้นทางที่ประกอบด้วยทั้งตัวอักษรb
อะไรจะเกิดขึ้นตั้งแต่ตัวอักษรที่เหมือนกัน แต่ทันทีที่หนึ่งของตัวอักษรจะถูกแทนที่ด้วยอีกคนหนึ่ง (เช่นz
) ตัวอักษรที่และเพื่อนบ้านจะถูกแทนที่ด้วยc
และทำซ้ำการประยุกต์ใช้เป็น น้ำท่วมเติมขององค์ประกอบที่เชื่อมต่อกับจากเมล็ดc
z
ในกรณีนี้ฉันไม่ต้องการเติมน้ำท่วมทั้งหมด ฉันต้องการเติมแขนข้างหนึ่งเพียงข้างz
เดียวดังนั้นหลังจากขั้นตอนแรกฉันก็อยากจะz
หายไป ใช้งานได้แล้วกับการc$2c
แทนที่ แต่ภายหลังฉันต้องการเริ่มต้นเติมน้ำท่วมตามแขนอีกข้างโดยเริ่มจากจุดเดิมและฉันไม่รู้ว่าc
s อันไหนเป็นของเดิมz
อีกต่อไป ดังนั้นฉันจะใช้แทน
s#(\w)(.{columns}|)(?!\1)(\w)#$&|a.$2.a#se
b | a
เป็นc
, b | c
เป็นc
และเป็นz | a
{
ดังนั้นในเขาวงกตที่ประกอบด้วยเส้นทางb
และเมล็ดz
ในขั้นตอนแรกb
จะถูกแทนที่ด้วยc
และz
จะถูกแทนที่ด้วย{
ซึ่งไม่ใช่ตัวอักษรและไม่ตรงกัน\w
และจะไม่ทำให้เกิดการเติมเพิ่มเติม c
แต่จะทำให้น้ำท่วมต่อเติมไปและเพื่อนบ้านแขนข้างหนึ่งของเมล็ดพันธุ์ที่ได้รับการเติมเต็ม เช่นเริ่มจาก
b c
b c
bbzbb becomes bb{bb
b b
b b
ฉันสามารถแทนที่ c ทั้งหมดด้วยตัวอักษรที่ไม่ใช่ (เช่น-
) และแทนที่{
ด้วยz
อีกครั้งเพื่อเริ่มการเติมน้ำท่วม:
- -
- -
bbzbb becomes cc{bb
b b
b b
และทำซ้ำขั้นตอนนี้จนกว่าเพื่อนบ้านทั้งหมดของเมล็ดจะถูกแปลง ถ้าฉันอีกครั้งแทนที่{
ด้วยz
และเติมน้ำท่วม:
- -
- -
--z-- stays --z--
- -
- -
สิ่งที่z
เหลืออยู่ข้างหลังในตอนท้ายเพราะไม่มีเพื่อนบ้านที่จะเปลี่ยนแปลงด้วย ทำให้ชัดเจนว่าเกิดอะไรขึ้นในส่วนของรหัสต่อไปนี้:
/\n/ >
ค้นหา newline แรก ออฟเซ็ตเริ่มต้นมาถึงแล้ว@-
s#(\w)(.{@{-}}|)(?!\1)(\w)#$&|a.$2.a#se
regex ที่กล่าวถึงข้างต้นด้วย@{-}
จำนวนคอลัมน์ (ตั้งแต่ธรรมดา@-
ทำให้สับสน parser perl และไม่ถูกแทนอย่างถูกต้อง)
&&
/\n/
เสมอประสบความสำเร็จและเปลี่ยนตัวเป็นจริงตราบใดที่เรายังสามารถเติมน้ำท่วม ดังนั้นการดำเนินการส่วนหลัง&&
หากการเติมน้ำท่วมของแขนข้างหนึ่งเสร็จสิ้น หากไม่ใช่ด้านซ้ายจะประเมินเป็นสตริงว่าง
y/{c/z / > 0
รีสตาร์ทการเติมน้ำท่วมและกลับ 1 ถ้าเติมน้ำท่วมก่อนหน้านี้ทำอะไร มิฉะนั้นส่งคืนสตริงว่าง โค้ดทั้งหมดนี้ห่ออยู่ข้างใน
s:|.: code :seg
ดังนั้นหากสิ่งนี้ถูกดำเนินการในสตริงเริ่มต้น$_
ด้วยz
ที่ตำแหน่งเมล็ดชิ้นส่วนของรหัสภายในจะถูกดำเนินการหลายครั้งส่วนใหญ่กลับไม่มีอะไร แต่1
ทุกครั้งที่แขนเพื่อนบ้านได้รับน้ำท่วม ได้อย่างมีประสิทธิภาพ$_
ได้รับการทำลายและถูกแทนที่ด้วยเป็นจำนวนมากในฐานะที่มีส่วนประกอบที่เกี่ยวโยงกันที่แนบมากับ1
z
ขอให้สังเกตว่าการวนซ้ำจะต้องดำเนินการจนถึงผลรวมของขนาดส่วนประกอบ + จำนวนครั้งของอาวุธ แต่ก็ตกลงเพราะจะ "จำนวนตัวอักษรรวมถึงการขึ้นบรรทัดใหม่ * 2 + 1" ครั้ง
เขาวงกตจะถูกตัดการเชื่อมต่อหากไม่มี1
(สตริงว่างเปล่า, จุดยอดที่แยกได้) หรือหากมีมากกว่า 1 แขน (มากกว่า 2 1
วินาที) สิ่งนี้สามารถตรวจสอบได้โดยใช้ regex /\B/
(สิ่งนี้ให้0
แทนที่จะเป็น1
รุ่น Perl ที่เก่ากว่ามันพิสูจน์ได้ว่าอันไหนผิด) 0
แต่น่าเสียดายถ้ามันไม่ตรงนี้จะให้เป็นสตริงว่างแทน แต่s:|.: code :seg
ได้รับการออกแบบเสมอกลับเป็นเลขคี่เช่นนั้นโดยทำ&
กับ/\B/
นี้จะให้หรือ0
1
สิ่งที่เหลืออยู่ก็คือการเดินเข้าไปในอาเรย์ทั้งหมดและในแต่ละตำแหน่งเมล็ดที่สามารถเดินได้ด้วยz
และนับแขนที่เชื่อมต่อ สามารถทำได้อย่างง่ายดายด้วย:
s%b%$_="$`z$'"; code %eg
ปัญหาเดียวคือในตำแหน่งที่ไม่สามารถเดินได้ค่าเก่าจะถูกเก็บไว้ เนื่องจากเราต้องการ0
ที่นั่นนั่นหมายถึงอาร์เรย์อินพุตดั้งเดิมต้อง0
อยู่ในตำแหน่งที่ไม่สามารถเดินได้และ0
จับคู่\w
ในการทดแทนเดิมและจะทำให้เกิดการเติมน้ำท่วม นั่นเป็นเหตุผลที่ฉันใช้\pL
แทน (จับคู่ตัวอักษรเท่านั้น)