ขอบคุณ FryAmTheEggman สำหรับแรงบันดาลใจที่จำเป็นสำหรับโซลูชั่น XOR
0000 !@
0001 ?.|@!
0010 #?#!)@
0011 ?!@
0100 +?|@!?
0101 ??!@
0110 ?<@!!<_\~(
0111 ?<<@!
1000 )\!#?@{
1001 (~?/@#!
1010 ??|@!)
1011 \#??!1@
1100 ?(~!@
1101 ?.|@!)
1110 ?$@#)!<
1111 1!@
โปรแกรมทั้งหมดใช้0
สำหรับเท็จและ1
เป็นจริง
ลองออนไลน์! นี่ไม่ใช่ชุดทดสอบคุณจะต้องคัดลอกในโปรแกรมต่างๆและป้อนข้อมูลด้วยตนเอง
วิธีการแก้ปัญหาข้างต้นอยู่ในระยะ 2 ไบต์ของการเพิ่มประสิทธิภาพ (เว้นแต่เราจะผ่อนคลายการตีความความจริง / เท็จฉันเดา) ผมเคยให้เรียกใช้การค้นหาแรงเดรัจฉานใกล้เคียงกับสองวันผ่านโปรแกรมทั้งหมดที่เหมาะสมในด้านความยาว 2 คือถึง 7 ไบต์ (ไม่ค่อนข้างโปรแกรมทั้งหมด - ฉันทำสมมติฐานไม่กี่ในสิ่งที่ทุกความต้องการโปรแกรมที่ถูกต้องและสิ่งที่ไม่มี โปรแกรมที่ถูกต้องอาจมี) การค้นหาพบวิธีแก้ปัญหาสำหรับประตูที่เป็นไปได้ 15 จาก 16 ประตู - และมักจะมากกว่าหนึ่งประตู คุณสามารถค้นหารายการโซลูชันทางเลือกทั้งหมดใน pastebin นี้ซึ่งฉันได้จัดกลุ่มพวกเขาด้วยพฤติกรรมที่เท่าเทียมกัน รายการที่ฉันแสดงไว้ด้านบนที่ฉันเลือกเนื่องจากเป็นวิธีที่ง่ายที่สุดหรือน่าสนใจที่สุดและฉันจะเพิ่มคำอธิบายสำหรับพวกเขาในวันพรุ่งนี้
สำหรับเกตที่ 16: XOR เป็นเกทตัวเดียวที่ไม่สามารถใช้งานได้ใน 7 ไบต์ การค้นหากำลังดุร้ายในโปรแกรมที่มีขนาดใหญ่กว่านั้นไม่น่าเป็นไปได้ที่จะใช้รหัสที่ฉันมีอยู่ในปัจจุบัน ดังนั้นต้องเขียนด้วยมือ XOR สั้นที่สุดที่ฉันได้พบคือโปรแกรม 10 ไบต์ข้างต้นซึ่งขึ้นอยู่กับความพยายามที่ล้มเหลว (แต่ใกล้มาก) โดย FryAmTheEggman เป็นไปได้ว่ามีวิธีแก้ปัญหา 8 ไบต์หรือ 9 ไบต์อยู่ แต่นอกเหนือจากนั้นโซลูชันทั้งหมดควรเหมาะสมที่สุด
คำอธิบาย
คำเตือน: กำแพงข้อความ หากใครก็ตามที่สนใจว่าโปรแกรม Hexagony ที่มีการบีบอัดสูงเหล่านี้ทำงานอย่างไรฉันได้รวบรวมคำอธิบายสำหรับแต่ละรายการไว้ด้านล่าง ฉันพยายามเลือกวิธีแก้ปัญหาที่ง่ายที่สุดสำหรับแต่ละเกทในกรณีที่มีโปรแกรมที่ดีที่สุดมากกว่าหนึ่งรายการเพื่อให้คำอธิบายสั้นพอสมควร อย่างไรก็ตามพวกเขาบางคนยังคงกระวนกระวายใจดังนั้นฉันคิดว่าพวกเขาสมควรได้รับรายละเอียดเพิ่มเติมเล็กน้อย
0000
: เท็จ
ฉันไม่คิดว่าเราจะต้องการไดอะแกรมสำหรับอันนี้:
! @
. . .
. .
เนื่องจากตารางหน่วยความจำทั้งหมดถูกกำหนดค่าเริ่มต้นเป็นศูนย์!
เพียงพิมพ์ศูนย์และ@
ยุติโปรแกรม
นี่เป็นโซลูชัน 2 ไบต์เท่านั้น
0001
: และ
? .
| @ !
. .
นี้โดยทั่วไปจะดำเนินการลัดวงจร แผนภาพสีเทาด้านล่างแสดงจุดเริ่มต้นของโปรแกรมโดยที่อินพุตแรกถูกอ่านด้วย?
และตัวชี้คำสั่ง (IP) ล้อมรอบไปที่มุมซ้ายที่|
กระจกสะท้อน ตอนนี้มุมทำหน้าที่เป็นเงื่อนไขเช่นนี้มีสองเส้นทางการดำเนินการที่แตกต่างกันขึ้นอยู่กับค่าของอินพุตแรก แผนภาพสีแดงแสดงโฟลว์ควบคุมสำหรับA = 0
และแผนภาพสีเขียวสำหรับA = 1
:
อย่างที่คุณเห็นเมื่อA
เป็น0
แล้วเราก็พิมพ์และยุติ (จำไว้ว่าทั้งหมด.
ไม่มี ops) แต่เมื่อA
เป็น1
เช่นนั้น IP จะข้ามแถวแรกอีกครั้งโดยอ่านB
และพิมพ์แทน
โดยรวมมีโซลูชั่น 5 ไบต์สิบหกสำหรับประตูนี้ สิบสี่ของเหล่านั้นเป็นหลักเช่นเดียวกับข้างต้นไม่ว่าจะใช้>
แทน|
หรือแทนที่.
ด้วยคำสั่งที่มีประสิทธิภาพไม่มี op หรือวาง?
ในตำแหน่งที่สอง:
?.|@! .?|@! ?=|@! =?|@! ?_|@! _?|@! ?0|@!
?.>@! .?>@! ?=>@! =?>@! ?_>@! _?>@! ?0>@!
และมีวิธีแก้ปัญหาอื่นอีกสองวิธี (ซึ่งเทียบเท่ากัน) สิ่งเหล่านี้ยังใช้ตรรกะการลัดวงจรเช่นเดียวกัน แต่พา ธ การประมวลผลนั้นค่อนข้างบ้าคลั่ง (และปล่อยให้เป็นแบบฝึกหัดสำหรับผู้อ่าน):
?<!@|
?<!@<
0010
: A และไม่ใช่ B
# ?
# ! )
@ .
สิ่งนี้ยังใช้รูปแบบของการลัดวงจร แต่เนื่องจากการใช้#
การควบคุมการไหลเป็นเรื่องที่ยุ่งยากมาก #
เป็นสวิตช์ IP แบบมีเงื่อนไข Hexagony จริงมาพร้อมกับหก IP ที่มีป้ายกำกับ0
การ5
ซึ่งเริ่มต้นในช่วงหกมุมของตารางชี้ไปตามขอบตามเข็มนาฬิกาของพวกเขา (และโปรแกรมที่มักจะเริ่มต้นด้วย IP 0
) เมื่อ#
พบa ค่าปัจจุบันจะได้รับ modulo 6
และการควบคุมการไหลยังคงดำเนินต่อไปตาม IP ที่สอดคล้องกัน ฉันไม่แน่ใจว่าบ้าอะไรที่ทำให้ฉันเพิ่มฟีเจอร์นี้ แต่มันช่วยให้มีโปรแกรมที่น่าแปลกใจบางอย่าง (เช่นนี้)
เราจะแยกความแตกต่างสามกรณี เมื่อA = 0
ใดที่โปรแกรมนั้นค่อนข้างง่ายเนื่องจากค่าจะเกิดขึ้นเสมอ0
เมื่อ#
พบว่าไม่มีการสลับ IP:
#
ไม่ทำอะไรเลย?
อ่านA
(คือยังไม่ทำอะไรเลย) #
ยังคงไม่ทำอะไรเลย, !
พิมพ์0
, )
เพิ่มมัน (นี้เป็นสิ่งสำคัญมิฉะนั้น IP จะไม่ข้ามไปยังบรรทัดที่สาม) @
สิ้นสุดโปรแกรม เรียบง่ายพอสมควร ตอนนี้ลองพิจารณากรณี(A, B) = (1, 0)
:
เส้นทางสีแดงยังคงสอดคล้องกับทรัพย์สินทางปัญญาและฉันได้เพิ่มเส้นทางสีเขียวสำหรับไอพี0
1
เราเห็นว่าหลังจาก?
อ่านA
( 1
เวลานี้) #
สวิตช์จะเป็น IP ที่เริ่มต้นที่มุมขวาบน นั่นหมายความว่า?
สามารถอ่านB
( 0
) ตอนนี้)
เพิ่มที่1
เช่นว่าในมุมซ้ายด้านบนไม่ทำอะไรเลยและเรายังคงอยู่กับทรัพย์สินทางปัญญา#
1
งาน!
พิมพ์1
และ IP นั้นล้อมรอบด้วยเส้นทแยงมุมด้านซ้าย #
ยังคงทำอะไรและ@
ยกเลิกโปรแกรม
ในที่สุดกรณีแปลก ๆ จริงๆที่อินพุตทั้งสองคือ1
:
เวลานี้การป้อนข้อมูลที่สองคือยัง1
และเพิ่มขึ้นไปยัง)
2
ซึ่งหมายความว่าที่#
มุมบนซ้ายทำให้IP อื่นเปลี่ยนเป็น IP 2
แสดงเป็นสีน้ำเงิน บนเส้นทางนั้นเราจะเพิ่มมันเข้าไปอีก3
(ถึงแม้ว่ามันจะไม่เกี่ยวข้อง) จากนั้นก็ผ่านไป?
อีกเป็นครั้งที่สาม เนื่องจากเราได้ตอนตี EOF (เช่นการป้อนข้อมูลจะหมด), ?
ผลตอบแทน0
, !
พิมพ์นั้นและ@
สิ้นสุดโปรแกรม
โดยเฉพาะอย่างยิ่งนี่เป็นโซลูชัน 6 ไบต์เดียวสำหรับเกตนี้
0011
: A
? !
@ . .
. .
นี้เป็นเรื่องง่ายพอที่เราจะไม่ต้องแผนภาพ: ?
อ่านA
, !
พิมพ์มัน@
ยุติ
นี่เป็นโซลูชัน 3 ไบต์เท่านั้นสำหรับเกตนี้ (ตามหลักการแล้วอาจเป็นไปได้ที่จะทำ,;@
แต่การค้นหาไม่ได้รวม;
ไว้เพราะฉันไม่คิดว่าจะสามารถบันทึกไบต์!
สำหรับงานนี้ได้)
0100
: B และไม่ใช่ A
+ ?
| @ !
? .
อันนี้ง่ายกว่า "พี่ชาย" ของ0010
มันมาก การควบคุมการไหลนั้นเหมือนกันกับที่เราเคยเห็นข้างต้นสำหรับ0001
(และ) ถ้าหากA = 0
IP นั้นเลื่อนผ่านบรรทัดล่างให้อ่านB
และพิมพ์ก่อนสิ้นสุด หากA = 1
IP ผ่านเข้าไปในบรรทัดแรกอีกครั้งให้อ่านB
ด้วยเช่นกัน แต่การ+
เพิ่มหน่วยความจำที่ไม่ได้ใช้จะทำให้เกิดการรีเซ็ตค่าปัจจุบันเป็น0
ดังนั้นจึง!
พิมพ์0
ทุกครั้ง
มีตัวเลือก 6-byte ค่อนข้างมากสำหรับเรื่องนี้ (ทั้งหมด 42 ตัว) ครั้งแรกมีวิธีแก้ปัญหามากมายที่เทียบเท่ากับข้างต้น เราสามารถเลือกได้อย่างอิสระระหว่าง|
และอีกครั้ง>
และ+
สามารถถูกแทนที่ด้วยคำสั่งอื่น ๆ ที่ให้ขอบว่างเปล่ากับเรา:
"?|@!? &?|@!? '?|@!? *?|@!? +?|@!? -?|@!? ^?|@!? {?|@!? }?|@!?
"?>@!? &?>@!? '?>@!? *?>@!? +?>@!? -?>@!? ^?>@!? {?>@!? }?>@!?
นอกจากนี้เรายังสามารถใช้แทน]
ย้ายไปที่ IP ถัดไป (เช่นเลือก IP ) เพื่อให้สาขานี้กลับมาใช้ซ้ำที่มุมบนขวา นั่นให้โซลูชันอีก 18 ข้อ:?
]
1
?
"?|@!] &?|@!] '?|@!] *?|@!] +?|@!] -?|@!] ^?|@!] {?|@!] }?|@!]
"?>@!] &?>@!] '?>@!] *?>@!] +?>@!] -?>@!] ^?>@!] {?>@!] }?>@!]
และมีวิธีแก้ปัญหาอื่นอีกหกวิธีที่ทำงานแตกต่างกันไปตามระดับความบ้าคลั่งที่แตกต่างกัน:
/[<@!? ?(#!@] ?(#>@! ?/@#/! [<<@!? [@$\!?
0101
: B
? ?
! @ .
. .
Woohoo อีกวิธีง่าย ๆ : อ่านA
อ่านB
พิมพ์B
ยุติ แม้ว่าจะมีทางเลือกอื่นสำหรับสิ่งนี้ เนื่องจากA
เป็นเพียงอักขระเดียวเราจึงสามารถอ่านได้ด้วย,
:
,?!@
และยังมีตัวเลือกในการใช้ซิงเกิ้ล?
และใช้มิเรอร์เพื่อวิ่งผ่านมันสองครั้ง:
?|@! ?>@!
0110
: Xor
? < @
! ! < _
\ ~ ( . .
. . . .
. . .
อย่างที่ฉันบอกไว้ข้างต้นนี่เป็นประตูเดียวที่ไม่พอดีกับความยาวด้าน 2 ดังนั้นนี่เป็นคำตอบที่เขียนด้วยลายมือโดย FryAmTheEggman และตัวฉันเองและมีโอกาสดีที่มันไม่เหมาะสม มีสองกรณีที่จะแยกแยะ หากA = 0
โฟลวการควบคุมนั้นค่อนข้างง่าย (เพราะในกรณีนั้นเราจำเป็นต้องพิมพ์เท่านั้นB
):
เราเริ่มต้นบนเส้นทางสีแดง ?
อ่านA
, <
เป็นสาขาที่ deflects ซ้ายศูนย์ IP แรปไปที่ด้านล่างจากนั้น_
เป็นอีกมิรเรอร์และเมื่อ IP ชนมุมมันก็จะไปที่มุมซ้ายบนและยังคงอยู่บนเส้นทางสีน้ำเงิน ?
อ่านB
, !
พิมพ์มัน ตอนนี้(
ลดลงมัน สิ่งนี้มีความสำคัญเนื่องจากช่วยให้มั่นใจได้ว่าค่าจะไม่เป็นบวก (เป็นอย่างใดอย่างหนึ่ง0
หรือ-1
ตอนนี้) นั่นทำให้ IP wrap ไปที่มุมขวาซึ่ง@
จะยุติโปรแกรม
เมื่อA = 1
สิ่งต่าง ๆ มีความซับซ้อนมากขึ้น ในกรณีนั้นเราต้องการพิมพ์not B
ซึ่งในตัวมันเองไม่ยากเกินไป แต่เส้นทางการประมวลผลนั้นค่อนข้างเร็ว
คราวนี้การ<
เบี่ยงเบน IP ไปทางขวาจากนั้น<
ก็ทำหน้าที่เหมือนกระจกเงา ดังนั้น IP จะข้ามเส้นทางเดียวกันในทางกลับกันโดยอ่านB
เมื่อพบ?
อีกครั้ง IP ล้อมรอบไปที่มุมขวาและดำเนินการต่อบนเส้นทางสีเขียว มันเผชิญหน้าต่อไป(~
ซึ่งก็คือ "พร่องคูณด้วย -1" ซึ่งสัญญาแลกเปลี่ยน0
และจึงคำนวณ1
เป็นเพียงกระจกเงาและพิมพ์ผลลัพธ์ที่ต้องการ จากนั้นพยายามส่งคืนหมายเลขอื่น แต่ส่งกลับศูนย์ ตอนนี้ IP ยังคงอยู่ที่มุมล่างซ้ายบนเส้นทางสีน้ำเงิน การลดลงสะท้อนให้เห็นถึงnot B
\
!
?
(
<
(
ลดลงอีกครั้งเพื่อให้ค่าปัจจุบันเป็นลบเมื่อ IP เข้ามุม มันเคลื่อนที่ข้ามเส้นทแยงมุมขวาล่างและจากนั้นก็เข้า@
สู่โปรแกรมเพื่อยุติโปรแกรม
0111
: หรือ
? <
< @ !
. .
การลัดวงจรมากขึ้น
A = 0
กรณี (เส้นทางสีแดง) เป็นบิตสับสนที่นี่ IP ที่ได้รับการเบี่ยงเบนทางซ้าย, wraps ไปที่มุมซ้ายด้านล่างได้รับผลโดยทันที<
และกลับไปอ่าน?
B
จากนั้นจะไปที่มุมที่ถูกต้องพิมพ์B
ด้วย!
และสิ้นสุด
A = 1
กรณี (เส้นทางสีเขียว) เป็นบิตง่าย <
สาขา deflects IP ที่ถูกต้องเพื่อให้เราเพียงแค่พิมพ์ห่อกลับไปที่ด้านบนซ้ายและสิ้นสุดที่!
@
มีโซลูชัน 5 ไบต์อื่น ๆ เพียงตัวเดียว:
\>?@!
มันทำงานเป็นหลักเหมือนกัน <
แต่เส้นทางการดำเนินการที่เกิดขึ้นจริงมีความแตกต่างกันมากและจะใช้มุมสำหรับการแตกแขนงแทน
1000
: หรือ
) \
! # ?
@ {
นี่อาจเป็นรายการโปรดของฉันที่พบในการค้นหานี้ สิ่งที่ยอดเยี่ยมที่สุดคือการติดตั้งใช้งานได้nor
จริงถึง 5 อินพุต ฉันจะต้องอธิบายรายละเอียดของโมเดลหน่วยความจำสักหน่อยเพื่ออธิบายอันนี้ ดังนั้นในการทบทวนอย่างรวดเร็วโมเดลหน่วยความจำของ Hexagony จึงเป็นกริดหกเหลี่ยมที่แยกกันโดยที่แต่ละขอบถือค่าจำนวนเต็ม (เริ่มแรกจะเป็นศูนย์ทั้งหมด) มีตัวชี้หน่วยความจำ (MP) ซึ่งระบุถึงขอบและทิศทางตามขอบนั้น (เช่นมีขอบที่อยู่ติดกันสองแห่งที่ด้านหน้าและด้านหลังขอบปัจจุบันที่มีเพื่อนบ้านด้านซ้ายและขวาที่มีความหมาย) นี่คือแผนภาพของขอบที่เราจะใช้โดยมี MP เริ่มต้นตามที่แสดงในสีแดง:
ก่อนอื่นมาพิจารณากรณีที่อินพุตทั้งสอง0
:
เราเริ่มต้นบนเส้นทางสีเทาซึ่งก็เพิ่มขอบไปเพื่อให้สวิทช์ IP ซึ่งเป็นเส้นทางสีฟ้าเริ่มต้นในมุมขวาบน ไม่ทำอะไรเลยและอ่านอินพุต เราตัดไปที่มุมบนซ้ายที่เพิ่มอินพุตนั้น ทีนี้ตราบใดที่อินพุตมีค่าเป็นศูนย์สิ่งนี้จะส่งผลให้ a ดังนั้นมันจะไม่ทำอะไรเลย จากนั้นย้าย MP ไปทางซ้ายเช่นในประโยคแรกจากไปB เนื่องจากขอบนี้ยังคงมีค่าเริ่มต้นเป็นศูนย์ IP จะย้อนกลับไปที่มุมขวาบนและบนขอบหน่วยความจำใหม่ ดังนั้นการวนซ้ำนี้จะดำเนินต่อไปตราบเท่าที่อ่านค่าศูนย์เคลื่อนที่ MP ไปรอบ ๆ รูปหกเหลี่ยมจากB1
#
1
\
?
)
1
#
{
?
ถึงCถึงDและอื่น ๆ ไม่สำคัญว่าจะ?
ส่งกลับค่าศูนย์เนื่องจากเป็นอินพุตหรือเพราะ EOF
หลังจากหกซ้ำผ่านวงนี้{
กลับไป เวลานี้ขอบจะเก็บค่าจากการวนซ้ำครั้งแรกดังนั้น IP จะแรปที่มุมซ้ายและดำเนินการต่อบนเส้นทางสีเขียวแทน เพียงพิมพ์และยกเลิกโปรแกรม1
!
1
@
ตอนนี้จะเกิดอะไรขึ้นถ้าอินพุตใด ๆ เป็น1
อย่างไร
จากนั้น?
อ่านว่า1
ในบางจุดและเพิ่มขึ้นไปยัง)
2
นั่นหมายความว่า#
ตอนนี้จะเปลี่ยน IP อีกครั้งและเราจะดำเนินการต่อที่มุมขวาบนเส้นทางสีแดง ?
อ่านอินพุตอื่น (ถ้ามี) ซึ่งไม่สำคัญและ{
ขยับไปอีกหนึ่งขอบ สิ่งนี้จะต้องเป็นขอบที่ไม่ได้ใช้ดังนั้นจึงทำงานได้ถึง 5 อินพุต IP แรปไปที่มุมบนขวาซึ่งสะท้อนไปทันทีและตัดที่มุมซ้าย !
พิมพ์0
บนขอบไม่ได้ใช้และ#
สวิทช์กลับไป 0
IP IP นั้นยังคงรออยู่#
กำลังไปทางตะวันตกเฉียงใต้ (เส้นทางสีเทา) ดังนั้นมันจึงกระทบ@
และยกเลิกโปรแกรมทันที
โดยรวมแล้วมีโซลูชั่น 7 ไบต์เจ็ดรายการสำหรับประตูนี้ 5 ของพวกเขาทำงานเช่นนี้และเพียงใช้คำสั่งอื่นเพื่อย้ายไปยังขอบที่ไม่ได้ใช้ (และอาจเดินไปรอบ ๆ รูปหกเหลี่ยมที่แตกต่างกันหรือในทิศทางที่แตกต่าง):
)\!#?@" )\!#?@' )\!#?@^ )\!#?@{ )\!#?@}
และมีโซลูชันอีกประเภทหนึ่งที่ใช้งานได้กับอินพุตสองตัวเท่านั้น แต่เส้นทางการดำเนินการที่เป็นจริงยิ่งยุ่งกว่า:
?]!|<)@ ?]!|<1@
1001
: ความเท่าเทียมกัน
( ~
? / @
# !
นอกจากนี้ยังทำให้การใช้งานการเลือก IP ตามเงื่อนไขอย่างชาญฉลาด เราจำเป็นต้องแยกแยะความแตกต่างอีกครั้งระหว่างและA = 0
A = 1
ในกรณีแรกเราต้องการที่จะพิมพ์ในครั้งที่สองที่เราต้องการที่จะพิมพ์not B
B
สำหรับเรายังแยกแยะความแตกต่างของทั้งสองกรณีA = 0
B
เริ่มจากA = B = 0
:
เราเริ่มต้นบนเส้นทางสีเทา (~
สามารถปฏิเสธ IP ที่ตัดไปที่มุมซ้าย (ยังคงอยู่บนเส้นทางสีเทา) และอ่านด้วยA
การลดลงนั่นคือเราได้รับและตัด IP ไปที่มุมล่างซ้าย ตอนนี้เหมือนที่ฉันพูดก่อนหน้านี้ใช้โมดูโลค่าก่อนที่จะเลือกเขา IP ดังนั้นมูลค่าที่แท้จริงของการออก IP ซึ่งเริ่มต้นที่มุมซ้ายบนเส้นทางสีแดง อ่าน, decrements ว่าเป็นอย่างดีเพื่อให้เรายังคงอยู่บน IP เมื่อเราตีอีกครั้ง negates เพื่อให้ IP ตัดไปที่มุมขวาล่างพิมพ์และยุติ?
(
-1
#
6
-1
5
?
B
(
5
#
~
-1
1
ตอนนี้ถ้าB
เป็น1
แทนค่าปัจจุบันจะเป็น0
เมื่อเรากด#
ครั้งที่สองดังนั้นเราจึงเปลี่ยนกลับไปเป็น IP 0
(ตอนนี้บนเส้นทางสีเขียว) ที่นิยม?
เป็นครั้งที่สามที่ให้ผลผลิต0
, !
การพิมพ์และ@
สิ้นสุด
A = 1
สุดท้ายกรณีที่ ครั้งนี้มูลค่าปัจจุบันเป็นศูนย์อยู่แล้วเมื่อเราตี#
เป็นครั้งแรกดังนั้นสิ่งนี้ไม่เคยเปลี่ยนเป็น IP 5
ในสถานที่แรก เราเพียงดำเนินการต่อทันทีบนเส้นทางสีเขียว ?
ตอนนี้ไม่เพียงแค่ให้ศูนย์ แต่กลับมาB
แทน !
พิมพ์และ@
ยุติอีกครั้ง
โดยรวมมีโซลูชัน 7 ไบต์สามรายการสำหรับประตูนี้ อีกสองคนทำงานแตกต่างกันมาก (แม้จะมาจากคนอื่น) และใช้ประโยชน์จาก#
มัน โดยเฉพาะอย่างยิ่งพวกเขาอ่านค่าอย่างน้อยหนึ่งค่าด้วย,
(อ่านรหัสตัวอักษรแทนจำนวนเต็ม) จากนั้นใช้ค่าโมดูล่า 6 เพื่อเลือก IP มันเป็นถั่วสวย
),)#?@!
?~#,~!@
1010
: ไม่ข
? ?
| @ !
) .
อันนี้ค่อนข้างง่าย เส้นทางการดำเนินการเป็นสาขาแนวนอนที่เรารู้มาand
ก่อนหน้านี้ ??
อ่านและจากนั้นทันทีA
B
หลังจากที่สะท้อนให้เห็นถึงที่|
และแตกแขนงสำหรับB = 0
เราจะดำเนินการตามสาขาด้านล่างที่)
เพิ่มมูลค่าให้กับที่จะพิมพ์โดย1
!
ในสาขาด้านบน (ถ้ามีB = 1
) ?
เพียงแค่ตั้งค่าขอบเพื่อที่แล้วยังพิมพ์โดย0
!
มีโปรแกรมขนาด 6 ไบต์แปดรายการสำหรับประตูนี้ สี่ของพวกเขาจะสวยมากเหมือนกันโดยใช้>
แทน|
หรือ1
แทน)
(หรือทั้งสอง):
??>@!) ??>@!1 ??|@!) ??|@!1
สองใช้หนึ่งเดียว?
ที่ใช้สองครั้งเนื่องจากกระจก ปฏิเสธแล้วที่เกิดขึ้นในขณะที่เราได้สำหรับxor
ทั้งสองหรือ(~
~)
?>!)~@ ?>!~(@
และในที่สุดโซลูชันทั้งสองใช้สวิตช์ IP แบบมีเงื่อนไขเนื่องจากเหตุใดจึงใช้วิธีง่าย ๆ ถ้าวิธีที่ซับซ้อนก็ใช้ได้เช่นกัน:
??#)!@ ??#1!@
1011
: B หมายถึง A
\ #
? ? !
1 @
วิธีนี้ใช้การสลับ IP ค่อนข้างซับซ้อน ฉันจะเริ่มต้นด้วยA = 1
กรณีนี้เพราะมันง่ายกว่า:
เราเริ่มต้นบนเส้นทางสีเทาซึ่งอ่านA
ด้วยแล้วฮิต?
#
ตั้งแต่A
เป็น1
นี้สลับไป IP 1
(เส้นทางสีเขียว) !
ทันทีพิมพ์นั้น IP wraps ไปทางซ้ายด้านบนอ่านB
(ไม่จำเป็น) และสิ้นสุดลง
เมื่อA = 0
สิ่งต่าง ๆ น่าสนใจยิ่งขึ้น ก่อนอื่นให้พิจารณาA = B = 0
:
เวลานี้การ#
ไม่ทำอะไรเลยและเรายังคงอยู่บน IP 0
(เส้นทางสีแดงจากจุดนั้นเป็นต้นไป) ?
อ่านB
และเปลี่ยนมันเป็น1
1
หลังจากห่อที่มุมบนซ้ายเราก็ตี#
อีกครั้งดังนั้นเราจึงจบลงบนเส้นทางสีเขียวหลังจากทั้งหมดและพิมพ์1
เหมือนก่อนก่อนที่จะยุติ
ในที่สุดนี่คือ(A, B) = (0, 1)
กรณีเท็จ:
โปรดทราบว่าฉันได้ลบเส้นทางสีเทาเริ่มต้นเพื่อความกระจ่างแจ้ง แต่โปรแกรมเริ่มต้นด้วยวิธีเดียวกันและเราก็จบลงบนเส้นทางสีแดงเหมือนเมื่อก่อน ดังนั้นครั้งนี้ที่สองผลตอบแทน?
ตอนนี้เราพบ1
1
ณ จุดนี้สิ่งสำคัญคือต้องเข้าใจว่าตัวเลขจริง ๆ ทำอะไรใน Hexagony (จนถึงตอนนี้เราใช้มันเป็นศูนย์เท่านั้น): เมื่อพบตัวเลขค่าปัจจุบันจะถูกคูณด้วย 10 แล้วจึงเพิ่มตัวเลข นี้จะใช้ตามปกติในการเขียนตัวเลขทศนิยมคำต่อคำลงในซอร์สโค้ด แต่มันหมายความว่าเป็นแมปจริงค่าB = 1
11
ดังนั้นเมื่อเราเข้าชม#
สิ่งนี้จะถูกนำ6
ไปใช้เพื่อให้5
และด้วยเหตุนี้เราจึงเปลี่ยนเป็น IP 5
(แทนที่จะ1
เป็นก่อนหน้านี้) และดำเนินการต่อในเส้นทางสีน้ำเงิน กดปุ่ม?
ครั้งที่สามจะคืนค่าศูนย์ดังนั้นจึง!
พิมพ์ออกมาและหลังจากนั้นอีกสอง?
IP IP จะตัดที่ด้านล่างขวาที่โปรแกรมยกเลิก
มีโซลูชั่นขนาด 7 ไบต์สี่ตัวสำหรับสิ่งนี้และทั้งหมดทำงานต่างกัน:
#)/!?@$ <!?_@#1 \#??!1@ |/)#?@!
1100
: ไม่ใช่ A
? (
~ ! @
. .
เพียงแค่เส้นง่ายๆ: อ่านA
ด้วย?
, ลบล้างด้วยการ(~
พิมพ์กับยุติด้วย!
@
มีทางเลือกหนึ่งทางเลือกและนั่นก็คือการปฏิเสธด้วย~)
:
?~)!@
1101
: A แปลว่า B
? .
| @ !
) .
นี้เป็นจำนวนมากง่ายกว่าความหมายตรงข้ามเราก็พูดคุยเกี่ยวกับ and
มันเป็นอีกครั้งหนึ่งในบรรดาโปรแกรมสาขาแนวนอนเช่นหนึ่งสำหรับ ถ้าA
เป็น0
เช่นนั้นก็จะได้รับการเพิ่มขึ้น1
ที่สาขาด้านล่างและพิมพ์ มิฉะนั้นสาขาด้านบนจะถูกดำเนินการอีกครั้งโดยที่?
จะอ่านB
แล้ว!
พิมพ์ออกมาแทน
มีเป็นตันของทางเลือกที่นี่ (66 การแก้ปัญหาในทั้งหมด) ส่วนใหญ่เนื่องจากการเลือกฟรีของที่มีประสิทธิภาพไม่มี Ops สำหรับการเริ่มต้นเราสามารถแตกต่างกันไปการแก้ปัญหาดังกล่าวข้างต้นในทุกรูปแบบเดียวกับที่เราจะทำได้and
และเรายังสามารถเลือกระหว่าง)
และ1
:
?.|@!) .?|@!) ?=|@!) =?|@!) ?_|@!) _?|@!) ?0|@!)
?.|@!1 .?|@!1 ?=|@!1 =?|@!1 ?_|@!1 _?|@!1 ?0|@!1
?.>@!) .?>@!) ?=>@!) =?>@!) ?_>@!) _?>@!) ?0>@!)
?.>@!1 .?>@!1 ?=>@!1 =?>@!1 ?_>@!1 _?>@!1 ?0>@!1
จากนั้นจะมีเวอร์ชั่นอื่นโดยใช้การเลือก IP แบบมีเงื่อนไขโดยที่คำสั่งแรกสามารถเลือกได้เกือบทุกข้อและยังมีตัวเลือกระหว่าง)
และ1
สำหรับตัวเลือกบางตัว:
"?#1!@ &?#1!@ '?#1!@ )?#1!@ *?#1!@ +?#1!@ -?#1!@ .?#1!@
0?#1!@ 1?#1!@ 2?#1!@ 3?#1!@ 4?#1!@ 5?#1!@ 6?#1!@ 7?#1!@
8?#1!@ 9?#1!@ =?#1!@ ^?#1!@ _?#1!@ {?#1!@ }?#1!@
"?#)!@ &?#)!@ '?#)!@ *?#)!@ +?#)!@ -?#)!@
0?#)!@ 2?#)!@ 4?#)!@ 6?#)!@
8?#)!@ ^?#)!@ _?#)!@ {?#)!@ }?#)!@
1110
: Nand
? $
@ # )
! <
อันซับซ้อนอันสุดท้าย หากคุณยังอ่านอยู่แสดงว่าคุณเกือบทำแล้ว :) มาดูA = 0
กันก่อน:
?
อ่านแล้วเราตีA
$
นี่คือคำสั่งกระโดด (เช่น Befunge ของ#
) @
ซึ่งข้ามการเรียนการสอนต่อไปเพื่อให้เราไม่ยุติบน แทนที่จะ IP #
คงที่ อย่างไรก็ตามตั้งแต่A
เป็น0
นี้ไม่ได้ทำอะไร )
เพิ่มขึ้นเพื่อ1
ให้ IP ดำเนินการต่อบนพา ธ ด้านล่างที่1
พิมพ์ <
เบน IP ไปทางขวาที่มันตัดไปที่มุมซ้ายและสิ้นสุดโปรแกรม
ถัดไปเมื่อ(A, B) = (1, 0)
เราได้รับอินพุต:
มันเป็นหลักเช่นเดียวกับก่อนยกเว้นว่าที่#
เราเปลี่ยนไป IP 1
(เส้นทางสีเขียว) แต่เนื่องจากB
เป็น0
เราเปลี่ยนกลับไป IP 0
เมื่อเราตี#
เป็นครั้งที่สอง (ตอนนี้เส้นทางสีฟ้า) ที่จะพิมพ์1
เป็นมาก่อน
ในที่สุดA = B = 1
กรณี:
ครั้งนี้เมื่อเรา#
เป็นครั้งที่สองมูลค่าปัจจุบันยังคงอยู่1
เพื่อให้เราไม่เปลี่ยน IP อีกครั้ง การ<
สะท้อนกลับและครั้งที่สามที่เราไปถึง?
เราจะได้ศูนย์ ดังนั้น IP จะตัดไปที่ด้านล่างซ้ายซึ่งจะ!
พิมพ์ศูนย์และโปรแกรมจะสิ้นสุด
มีโซลูชั่นทั้งหมด 7 ไบต์ที่รวมอยู่ในนี้ ทางเลือกแรกใช้1
แทน)
:
?$@#1!<
จากนั้นมีวิธีแก้ปัญหาสองประการที่จะนำไปสู่การเปลี่ยนแปลง IP ของคุณ:
)?#_[!@ 1?#_[!@
สิ่งเหล่านี้ทำให้ใจฉัน: ส่วนที่น่าสนใจคือการสลับ IP สามารถใช้เป็นเงื่อนไขที่เลื่อนออกไป กฎการสลับ IP ของภาษานั้นทำให้ IP ปัจจุบันทำอีกก้าวหนึ่งก่อนที่สวิตช์จะเกิดขึ้น หากขั้นตอนนั้นเกิดขึ้นเมื่อผ่านมุมหนึ่งค่าปัจจุบันจะตัดสินใจว่าสาขาใดที่ IP จะดำเนินการต่อไปหากเราเปลี่ยนกลับไปเป็นระดับเดิม A = B = 1
ตรงนี้เกิดขึ้นเมื่อเข้าเป็น แม้ว่าทั้งหมดนี้จะสอดคล้องกับวิธีการออกแบบภาษาของฉัน แต่ฉันไม่เคยตระหนักถึงความหมายของสเป็คนี้ดังนั้นจึงเป็นเรื่องที่ดีเมื่อภาษาของฉันสอนเทคนิคใหม่ให้ฉัน: D
จากนั้นมีโซลูชันที่สามซึ่งจำนวนการสลับ IP ยิ่งแย่ลง (แม้ว่าจะไม่ได้ใช้ประโยชน์จากเงื่อนไขที่เลื่อนออกไป):
>?1]#!@
แล้วมีอีกหนึ่ง:
?$@#)!<
จากนั้นก็มีวิธีแก้ปัญหาที่เทียบเท่ากันทั้งสี่นี้ซึ่งใช้การสลับ IP แบบไม่มีเงื่อนไขและใช้ตรรกะทั้งหมดผ่านสาขาและมุม:
]<?<@!) ]<?<@!1 ]|?<@!) ]|?<@!1
1111
: จริง
1 !
@ . .
. .
คุณได้รับสิ่งที่ตัวเองที่ง่ายสำหรับการสิ้นสุด: ตั้งขอบ1
พิมพ์กับยุติด้วย!
@
:)
แน่นอนว่ามีทางเลือกหนึ่ง:
)!@
ตามปกติทุกแผนภาพการควบคุมการไหลที่สร้างขึ้นด้วย Timwi ของHexagonyColorerและแผนภาพหน่วยความจำของเขาEsotericIDE