ฉันคิดว่าฉันจะใช้โอกาสนี้เพื่อแสดงคุณลักษณะใหม่ของ Retina: ลูปหลายขั้นตอน สิ่งนี้จะสั้นลงหลาย ๆ งานมาก (โดยเฉพาะการเปลี่ยนตามเงื่อนไข)
ii
-
+`(.)\1|0
(.)-|(\d)(\d)
-$1$3$2
12
i3
23
i1
31
i2
)`(\d)i
i$1
^\D*$
$&0
Retina เป็นภาษาการเขียนโปรแกรมที่อิงจาก regex ของฉันเอง ซอร์สโค้ดสามารถจัดกลุ่มเป็นสเตจได้: แต่ละสเตจประกอบด้วยสองบรรทัดโดยที่แรกประกอบด้วยเรกซ์ (และอาจมีการกำหนดค่าบางอย่าง) และบรรทัดที่สองคือสตริงการแทนที่ ขั้นตอนจะถูกนำไปใช้กับ STDIN ตามลำดับและผลลัพธ์สุดท้ายจะถูกพิมพ์ไปยัง STDOUT
คุณสามารถใช้ข้อมูลด้านบนโดยตรงเป็นไฟล์ต้นฉบับด้วย-s
สวิตช์บรรทัดคำสั่ง อย่างไรก็ตามฉันไม่ได้นับสวิตช์เพราะคุณสามารถใส่แต่ละบรรทัดในไฟล์แยกกันได้ (จากนั้นคุณจะสูญเสีย 15 ไบต์สำหรับบรรทัดใหม่ แต่เพิ่ม +15 สำหรับไฟล์เพิ่มเติม)
คำอธิบาย
สิ่งใหม่เกี่ยวกับการแก้ปัญหานี้คือ)
ในขั้นตอนสุดท้าย นี่เป็นการปิดลูปแบบหลายขั้นตอน ไม่มีการจับคู่(
ซึ่งหมายความว่าการวนซ้ำเริ่มต้นในระยะแรก ดังนั้น 7 ขั้นตอนแรกจะถูกทำซ้ำจนกว่าจะผ่านเต็มทั้ง 7 ของพวกเขาหยุดการเปลี่ยนแปลงผล 7 ขั้นตอนเหล่านี้ทำการแปลงแบบต่าง ๆ ซึ่งค่อย ๆ ลดจำนวนเมทริกซ์ในสตริงและรวมเฟส เมื่อเราไปถึงผลลัพธ์สุดท้ายแล้วไม่มีรูปแบบใดในเจ็ดรูปแบบที่ตรงกันอีกต่อไปและลูปจะสิ้นสุดลง หลังจากนั้นเราจะเพิ่ม 0 หากไม่มีผลลัพธ์ในหลัก
นี่คือสิ่งที่แต่ละขั้นตอนทำ:
ii
-
รวมคู่ทั้งหมดi
เข้าด้วยกัน-
เพื่อลดอักขระเฟส
+`(.)\1|0
<empty>
ตอนนี้ถ้ามีตัวอักขระที่เหมือนกันสองตัวที่เหลืออยู่มันเป็น--
เมทริกซ์ที่เหมือนกันหนึ่งหรือสองตัว ไม่ว่าในกรณีใดการทวีคูณพวกมันจะทำให้เกิดอัตลักษณ์ แต่เราไม่ต้องการข้อมูลเฉพาะตัวดังนั้นเราจึงลบข้อมูลทั้งหมดและข้อมูลเฉพาะตัวที่ชัดเจน0
ออกไป ขั้นตอนนี้ซ้ำแล้วซ้ำอีกในตัวเองด้วย+
จนกว่าผลจะหยุดการเปลี่ยนแปลง สิ่งนี้ทำให้มั่นใจได้ว่าสิ่งต่าง ๆ123321
ได้รับการแก้ไขอย่างสมบูรณ์เช่นว่าขั้นตอนต่อไปสามารถสันนิษฐานได้ว่าตัวเลขทุกคู่มีความแตกต่างกัน
(.)-|(\d)(\d)
-$1$3$2
นี่คือการแปลงสองแบบแยกกันในหนึ่งเดียว (สำหรับ golfitude) โปรดทราบว่าหากการจับคู่ทางเลือกแรก$2
และ$3
ว่างเปล่าและหากการจับคู่ที่สอง$1
ว่างเปล่า ดังนั้นสามารถแบ่งย่อยเป็นสองขั้นตอนเหล่านี้:
(\d)(\d)
-$2$1
เพียงแค่สลับตัวเลขทุกคู่และเพิ่มเครื่องหมายลบ เนื่องจากเราเอาออกทั้งหมด0
และคู่ที่เหมือนกันทั้งหมดนี้จะตรงกับ12
, 23
, 31
, 21
, ,32
13
ขั้นตอนนี้อาจดูแปลก แต่ช่วยให้ฉันตรวจสอบเพียงครึ่งหนึ่งของกรณีเหล่านี้ในภายหลังเพราะสิ่งที่ฉันไม่สามารถประมวลผลได้จะถูกสลับที่นี่ในการทำซ้ำครั้งถัดไป
อีกส่วนหนึ่งของเวทีด้านบนคือ:
(.)-
-$1
สิ่งนี้จะค่อย ๆ เคลื่อน-
สัญญาณไปทางซ้าย (หนึ่งตำแหน่งต่อการวนซ้ำ) ฉันทำเช่นนี้ในที่สุดพวกเขาทั้งหมดอยู่ติดกันและได้รับการแก้ไขในขั้นตอนก่อนหน้า
12
i3
23
i1
31
i2
สามขั้นตอนเหล่านี้สามารถแก้ไขผลิตภัณฑ์สามคู่ได้อย่างง่ายดาย ดังที่ฉันได้กล่าวไว้ข้างต้นนี่จะจับได้เพียงครึ่งหนึ่งของคดีที่เกี่ยวข้อง แต่อีกครึ่งหนึ่งจะได้รับการดูแลในการทำซ้ำครั้งถัดไปหลังจากขั้นตอนก่อนหน้าสลับคู่ทั้งหมด
)`(\d)i
i$1
นี่คือขั้นตอนสุดท้ายของการวนซ้ำ มันคล้ายกับหนึ่งที่เปลี่ยนแปลงไปทางซ้ายยกเว้น-
i
ความแตกต่างที่สำคัญคืออันนี้สลับi
กับตัวเลขเท่านั้น หากฉันใช้(.)i
ในกรณีที่ฉันได้รับหนึ่ง-i
หรือi-
สองจะถูกสลับไปเรื่อย ๆ และโปรแกรมจะไม่ยุติ ดังนั้นนี่แค่เปลี่ยนพวกมันไปทางขวาของ-
เครื่องหมาย นี้ก็เพียงพอ - ตราบใดที่ทุกคน-
และi
ปรากฏร่วมกันในบางจุดที่พวกเขาสามารถได้รับการแก้ไขอย่างถูกต้อง
^\D*$
$&0
ขั้นตอนสุดท้าย (นอกวง) โปรดจำไว้ว่าเราลบข้อมูลเฉพาะตัวทั้งหมดเสมอดังนั้นหากผลลัพธ์นั้นเป็นตัวตนจริง (คูณเฟส) ดังนั้นเราจะไม่ต้องการตัวเลขหลักในผลลัพธ์อีกต่อไปดังนั้นเราจึงเพิ่มกลับ
ตัวอย่างเช่นนี่คือรูปแบบกลางทั้งหมดของ0223202330203313021301011023230323
(การข้ามขั้นตอนที่ไม่ทำการเปลี่ยนแปลงใด ๆ ):
0223202330203313021301011023230323
321321312 # Remove identities
-23-31-12-132 # Swap all pairs
-23-31-i3-132 # Resolve 12
-i1-31-i3-132 # Resolve 23
-i1-i2-i3-132 # Resolve 31
-i-1i-2i-3-312 # Move - to the left and swap pairs
-i-1i-2i-3-3i3 # Resolve 12
-i-i1-i2-3-i33 # Move i to the left
-i-i1-i2-3-i # Remove identities
--ii-1i-2-3i # Move - to the left
--ii-i1-2-i3 # Move i to the left
----i1-2-i3 # Resolve ii
i1-2-i3 # Remove identities
i-1-2i3 # Move - to the left
i-1-i23 # Move i to the left
-i-1i-32 # Move - to the left and swap pairs
-i-i1-32 # Move i to the left
--ii-1-23 # Move - to the left and swap pairs
--ii-1-i1 # Resolve 23
----1-i1 # Resolve ii
1-i1 # Remove identities
-1i1 # Move - to the left
-i11 # Move i to the left
-i # Remove identities. Now the loop can't change this any longer.
-i0 # Fix the result by adding in the 0.