Hexagony , 920 722 271 ไบต์
คุณพูดว่าลูปผลไม้หกประเภท นั่นคือสิ่งที่ Hexagonyสร้างขึ้นมาเพื่อ
){r''o{{y\p''b{{g''<.{</"&~"&~"&<_.>/{.\.....~..&.>}<.._...=.>\<=..}.|>'%<}|\.._\..>....\.}.><.|\{{*<.>,<.>/.\}/.>...\'/../==.|....|./".<_>){{<\....._>\'=.|.....>{>)<._\....<..\..=.._/}\~><.|.....>e''\.<.}\{{\|./<../e;*\.@=_.~><.>{}<><;.(~.__..>\._..>'"n{{<>{<...="<.>../
ไม่เป็นไร โอ้พระเจ้าฉันทำอะไรกับตัวเอง ...
รหัสนี้คือความยาวด้านหกเหลี่ยม 10 (เริ่มต้นที่ 19) มันอาจจะเล่นกอล์ฟได้มากกว่านี้บางทีอาจเป็นขนาด 9 แต่ฉันคิดว่างานของฉันเสร็จที่นี่ ... สำหรับการอ้างอิงมี 175 คำสั่งจริงในแหล่งที่มาซึ่งส่วนใหญ่เป็นกระจกที่ไม่จำเป็น (หรือเพิ่มเพื่อยกเลิก ออกคำสั่งจากเส้นทางข้าม)
แม้จะมีเส้นตรงชัดเจนรหัสเป็นจริงสองมิติ: Hexagony จะจัดเรียงใหม่เป็นรูปหกเหลี่ยมปกติ (ซึ่งเป็นรหัสที่ถูกต้อง แต่ช่องว่างทั้งหมดเป็นตัวเลือกใน Hexagony) นี่คือรหัสที่คลี่ในทั้งหมดของมัน ... ดีฉันไม่ต้องการที่จะพูดว่า "ความงาม":
) { r ' ' o { { y \
p ' ' b { { g ' ' < .
{ < / " & ~ " & ~ " & <
_ . > / { . \ . . . . . ~
. . & . > } < . . _ . . . =
. > \ < = . . } . | > ' % < }
| \ . . _ \ . . > . . . . \ . }
. > < . | \ { { * < . > , < . > /
. \ } / . > . . . \ ' / . . / = = .
| . . . . | . / " . < _ > ) { { < \ .
. . . . _ > \ ' = . | . . . . . > {
> ) < . _ \ . . . . < . . \ . . =
. . _ / } \ ~ > < . | . . . . .
> e ' ' \ . < . } \ { { \ | .
/ < . . / e ; * \ . @ = _ .
~ > < . > { } < > < ; . (
~ . _ _ . . > \ . _ . .
> ' " n { { < > { < .
. . = " < . > . . /
คำอธิบาย
ฉันจะไม่ลองและเริ่มอธิบายเส้นทางการทำงานที่ซับซ้อนทั้งหมดในเวอร์ชัน golfed นี้ แต่อัลกอริทึมและการควบคุมการไหลโดยรวมนั้นเหมือนกับเวอร์ชั่นที่ไม่ได้รับการแก้ไขซึ่งอาจง่ายต่อการศึกษาสำหรับผู้อยากรู้อยากเห็นจริง ๆ
) { r ' ' o { { \ / ' ' p { . . .
. . . . . . . . y . b . . . . . . .
. . . . . . . . ' . . { . . . . . . .
. . . . . . . . \ ' g { / . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . > . . . . < . . . . . . . . .
. . . . . . . . . . . . . . > . . ) < . . . . .
. . . . . . . . . . / = { { < . . . . ( . . . . .
. . . . . . . . . . . ; . . . > . . . . . . . . . <
. . . . . . . . . . . . > < . / e ; * \ . . . . . . .
. . . . . . . . . . . . @ . } . > { } < . . | . . . . .
. . . . . / } \ . . . . . . . > < . . . > { < . . . . . .
. . . . . . > < . . . . . . . . . . . . . . . | . . . . . .
. . . . . . . . _ . . > . . \ \ " ' / . . . . . . . . . . . .
. . . . . . \ { { \ . . . > < . . > . . . . \ . . . . . . . . .
. < . . . . . . . * . . . { . > { } n = { { < . . . / { . \ . . |
. > { { ) < . . ' . . . { . \ ' < . . . . . _ . . . > } < . . .
| . . . . > , < . . . e . . . . . . . . . . . . . = . . } . .
. . . . . . . > ' % < . . . . . . . . . . . . . & . . . | .
. . . . _ . . } . . > } } = ~ & " ~ & " ~ & " < . . . . .
. . . \ . . < . . . . . . . . . . . . . . . . } . . . .
. \ . . . . . . . . . . . . . . . . . . . . . . . < .
. . . . | . . . . . . . . . . . . . . . . . . = . .
. . . . . . \ . . . . . . . . . . . . . . . . / .
. . . . . . > . . . . . . . . . . . . . . . . <
. . . . . . . . . . . . . . . . . . . . . . .
_ . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
สุจริตในวรรคแรกฉันล้อเล่นเพียงครึ่งเดียว ความจริงที่ว่าเรากำลังจัดการกับวัฏจักรของหกองค์ประกอบเป็นจริงช่วยได้มาก โมเดลหน่วยความจำของ Hexagony เป็นกริดหกเหลี่ยมแบบไม่มีที่สิ้นสุดที่ขอบของกริดแต่ละอันประกอบด้วยเลขจำนวนเต็มความแม่นยำที่มีการลงนามซึ่งเริ่มต้นที่ศูนย์
นี่คือไดอะแกรมของเลย์เอาต์ของหน่วยความจำที่ฉันใช้ในโปรแกรมนี้:
บิตยาวตรงด้านซ้ายถูกนำมาใช้เป็นสตริง 0 สิ้นสุดa
ของขนาดโดยพลการซึ่งมีความเกี่ยวข้องด้วยตัวอักษรR เส้นประที่อยู่บนตัวอักษรอื่น ๆ แสดงถึงโครงสร้างชนิดเดียวกันโดยแต่ละเส้นนั้นหมุนด้วย 60 องศา ในขั้นต้นตัวชี้หน่วยความจำชี้ไปที่ขอบป้าย1ซึ่งหันไปทางทิศเหนือ
บิตแรกที่เป็นเส้นตรงของโค้ดจะตั้งค่า "ดาว" ด้านในของขอบให้กับตัวอักษรroygbp
เช่นเดียวกับการตั้งค่าขอบเริ่มต้นเป็น1
เช่นที่เรารู้ว่าวงจรสิ้นสุด / เริ่มต้น (ระหว่างp
และr
):
){r''o{{y''g{{b''p{
หลังจากนี้เรากลับมาอยู่บนขอบที่มีข้อความ1
ตอนนี้แนวคิดทั่วไปของอัลกอริทึมคือ:
- สำหรับแต่ละตัวอักษรในวงรอบให้อ่านตัวอักษรจาก STDIN และหากตัวอักษรนั้นแตกต่างจากตัวอักษรปัจจุบันให้ต่อท้ายสตริงที่เกี่ยวข้องกับตัวอักษรนั้น
- เมื่อเราอ่านจดหมายที่เรากำลังมองหาอยู่เราเก็บจดหมาย
e
ไว้ที่ขอบ? เพราะตราบใดที่รอบยังไม่สมบูรณ์เราต้องสมมติว่าเราจะต้องกินตัวละครนี้ด้วย หลังจากนั้นเราจะย้ายวงแหวนไปที่ตัวละครถัดไปในวงรอบ
- มีสองวิธีที่กระบวนการนี้สามารถถูกขัดจังหวะ:
- ไม่ว่าเราจะเสร็จสิ้นรอบ ในกรณีนี้เราทำอีกรอบอย่างรวดเร็วผ่านวงจรแทนสิ่งเหล่านั้นทั้งหมด
e
ใน? ขอบกับn
s เพราะตอนนี้เราต้องการให้วงจรนั้นอยู่บนสร้อยคอ จากนั้นเราไปยังรหัสการพิมพ์
- หรือเรากด EOF (ซึ่งเราจำได้ว่าเป็นรหัสอักขระเชิงลบ) ในกรณีนี้เราเขียนค่าลบลงใน? ขอบของอักขระปัจจุบัน (เพื่อให้เราสามารถแยกแยะได้ง่ายจากทั้งสอง
e
และn
) จากนั้นเราค้นหาขอบ1 (เพื่อข้ามส่วนที่เหลือของวัฏจักรที่อาจไม่สมบูรณ์) ก่อนที่จะย้ายไปพิมพ์รหัสเช่นกัน
- รหัสการพิมพ์จะผ่านรอบอีกครั้ง: สำหรับตัวละครแต่ละตัวในรอบนั้นจะเป็นการล้างสตริงที่เก็บไว้ในขณะที่พิมพ์
e
สำหรับตัวละครแต่ละตัว จากนั้นมันจะย้ายไปที่? ขอบที่เกี่ยวข้องกับตัวละคร ถ้ามันเป็นลบเราก็จะยุติโปรแกรม ถ้ามันเป็นบวกเราก็พิมพ์และย้ายไปที่ตัวละครต่อไป เมื่อเราเสร็จสิ้นรอบเรากลับไปที่ขั้นตอนที่ 2
อีกสิ่งหนึ่งที่น่าสนใจคือวิธีที่ฉันใช้สตริงขนาดตามอำเภอใจ (เพราะเป็นครั้งแรกที่ฉันใช้หน่วยความจำที่ไม่มีขอบเขตใน Hexagony)
ลองนึกภาพเราในบางจุดที่เรายังคงอ่านตัวอักษรR (เพื่อให้เราสามารถใช้แผนภาพที่เป็นอยู่) และa [0]และ1ได้รับแล้วเต็มไปด้วยตัวละคร (ทุกอย่างตะวันตกเฉียงเหนือของพวกเขายังคงเป็นศูนย์ ) เช่นบางทีเราได้เพียงแค่อ่านตัวละครสองตัวแรกของการป้อนข้อมูลลงในขอบเหล่านั้นและตอนนี้การอ่านog
y
ตัวละครใหม่จะถูกอ่านเข้าไปในขอบ เราใช้? r
ขอบเพื่อตรวจสอบว่าตัวละครตัวนี้จะมีค่าเท่ากับ (มีเคล็ดลับที่ดีที่นี่: Hexagony สามารถแยกความแตกต่างระหว่างค่าบวกและค่าบวกได้อย่างง่ายดายดังนั้นการตรวจสอบความเท่าเทียมกันผ่านการลบนั้นน่ารำคาญและต้องใช้อย่างน้อยสองสาขา แต่ตัวอักษรทั้งหมดนั้นน้อยกว่า 2 ปัจจัยจากกัน เราสามารถเปรียบเทียบค่าโดยการใช้โมดูโลซึ่งจะให้เป็นศูนย์ถ้ามันเท่ากัน)
เนื่องจากy
แตกต่างจากr
เราจึงย้ายขอบ (ไม่มีป้ายกำกับ) ที่เหลือเข้าไปและคัดลอกที่y
นั่น ตอนนี้เราย้ายออกไปรอบหกเหลี่ยมคัดลอกตัวอักษรหนึ่งขอบเพิ่มเติมในแต่ละครั้งจนกว่าเราจะมีy
ตรงข้ามขอบใน แต่ตอนนี้มีตัวละครใน[0]ซึ่งเราไม่ต้องการเขียนทับ แต่เรา "ลาก" ในy
รอบหกเหลี่ยมต่อไปและตรวจสอบ1 แต่มีตัวละครอยู่ที่นั่นด้วยเราเลยออกไปอีกหกเหลี่ยม ตอนนี้[2]ยังคงเป็นศูนย์ดังนั้นเราจึงคัดลอกy
เป็นมัน ตัวชี้หน่วยความจำตอนนี้ย้ายกลับไปตามสายไปทางวงแหวนด้านใน เรารู้เมื่อเรามาถึงจุดเริ่มต้นของสตริงเพราะ (unlabelled) ขอบระหว่างa [i]ทั้งหมดเป็นศูนย์ในขณะที่? เป็นบวก
นี่อาจเป็นเทคนิคที่มีประโยชน์สำหรับการเขียนโค้ดที่ไม่น่าสนใจใน Hexagony โดยทั่วไป