Haskell , 1080 1033 ไบต์
;
f=
g
ij=f
a =hi
hi = g
hij= ij
g ' ' =0
g '"' =0;
g '$' =0;
g '&' =0-0
g '(' =0-0-0
g '*' =0-0-0;
g ',' =0-0-0;
g '.' =0-0-0-0
g '0' =0-0-0-0-0
g '2' =0-0-0-0-0;
g '4' =0-0-0-0-0;
g '6' =0; g '8' =0
g ':' =0; g '<' =0-0
g '>' =0; g '@' =0-0;
g 'B' =0; g 'D' =0-0;
g 'F' =0; g 'H' =0-0-0
g 'J' =0; g 'L' =0-0-0-0
g 'N' =0; g 'P' =0-0-0-0;
g 'R' =0; g 'T' =0-0-0-0;
g 'V' =0; g 'X' =0-0-0-0-0
g 'Z' =0; g '^' =0; g '`' =0
g 'b' =0; g 'd' =0; g 'f' =0;
g 'h' =0; g 'j' =0; g 'l' =0;
g 'n' =0; g 'p' =0; g 'r' =0-0
g 't' =0; g 'v' =0; g 'x' =0-0-0
g 'z' =0; g '\92' =0-0; g '|' =0;
g '~' =0; g y = 1 ;z=0; i(-0)z=z;
i m('\10':y ) ="y"; ; ; ; ; ; ; ;
i m(mnmnmnmnm:y ) = i(m - 1 ) y ; ;
i k m ="y"; ; k i [ ] =01<1010101010;
k m('\10':y ) = k(m + 1 )(i m y ) ; ;
k m y =01>10; m o = k 1$'\10':o ; ; ;
o i('\10':y ) = o i y ; ; ; ; ; ; ; ; ;
o i(k:y )|g k<i = o(1 - i ) y ; ; ; ; ; ;
o i(k:y )|g k>i = o(1 - i ) y ; ; ; ; ; ;
o i [ ] =01<10; o i y =01>10;v=01>10101010
s y|o 1 y = m y|o(-0) y = m y ; s y =v; ; ;
ลองออนไลน์!
คำอธิบาย
นี่เป็นงานที่น่าสนใจสำหรับ Haskell
ความเท่าเทียมกัน
ในการเริ่มต้นเราต้องการวิธีการพิจารณาว่าตัวละครมีจุดรหัสคี่หรือคู่ วิธีปกติที่อาจทำเช่นนี้คือการได้รับรหัสจุดและดัดแปลงโดย 2 อย่างไรก็ตามในฐานะที่อาจจะตระหนักถึงการได้รับรหัสจุดของตัวละครที่ต้องการนำเข้าซึ่งเนื่องจากข้อ จำกัด แหล่งที่มาหมายความว่ามันไม่สามารถ ใช้ Haskeller ที่มีประสบการณ์มากกว่าจะคิดว่าใช้การเรียกซ้ำ Char
เป็นส่วนหนึ่งของEnum
typeclass เพื่อให้เราสามารถรับรุ่นก่อนหน้าและผู้สืบทอด อย่างไรก็ตามpred
และsucc
ยังมีทั้งที่ใช้ไม่ได้เพราะไม่ได้สลับพาริตีไบต์
ดังนั้นสิ่งนี้ทำให้เราติดค้างอยู่ค่อนข้างมากเราไม่สามารถจัดการกับตัวอักษรได้ วิธีแก้ปัญหานี้คือการฮาร์ดโค้ดทุกอย่าง เราสามารถเป็นตัวแทน (ส่วนใหญ่) แม้กระทั่งตัวอักษรเป็นตัวอักษรอัตราต่อรองที่เรามีปัญหาเพราะ'
เป็นเลขคี่ดังนั้นจึงไม่สามารถอยู่ข้างตัวถ่านทำให้ตัวอักษรไม่สามารถแสดงตัวอักษรแปลก ๆ ได้ ดังนั้นเราจึงยากรหัสไบต์ทั้งหมดแล้วเพิ่มการจับทั้งหมดสำหรับไบต์คี่ในตอนท้าย
ปัญหาไบต์
คุณอาจสังเกตเห็นว่ามีบางไบต์ที่ไม่สามารถสร้างตัวอักษรได้โดยการใส่คำพูดในเครื่องหมายคำพูดเดี่ยว พวกเขาเป็น unprintables, \
การขึ้นบรรทัดใหม่และ เราไม่จำเป็นต้องกังวลเกี่ยวกับ unprintables ตั้งแต่ตราบใดที่เราไม่ได้ใช้สิ่งเหล่านี้เราไม่จำเป็นต้องตรวจสอบ ในความเป็นจริงเรายังคงสามารถใช้ unprintables แปลก ๆ เช่นแท็บฉันเพียงแค่ไม่จำเป็นต้อง ขึ้นบรรทัดใหม่ได้อย่างมากเพราะมันจะถูกตัดออกจากโปรแกรมต่อไป (เราอาจรวมบรรทัดใหม่เนื่องจากเป็นจุดรหัสค่อนข้างสะดวก แต่เราไม่จำเป็นต้อง) ใบ\
นี้ตอนนี้\
มี codepoint 92 ซึ่งสะดวกเป็นเลขคี่ตามด้วยหมายเลขคู่ดังนั้น\92
สลับระหว่าง evens และอัตราต่อรองดังนั้นตัวอักษร'\92'
ถูกต้องสมบูรณ์ '\10'
ต่อมาเมื่อเราทำจำเป็นต้องหมายถึงการขึ้นบรรทัดใหม่เราจะสังเกตเห็นว่ามันโชคดีที่มีคุณสมบัติเดียวกันนี้
ปัญหาระยะห่าง
ตอนนี้เพื่อเริ่มเขียนโค้ดจริงเราต้องสามารถใส่จำนวนอักขระได้มากในบรรทัดเดียว เพื่อที่จะทำสิ่งนี้ฉันเขียนหมวก:
;
f=
g
ij=f
a =hi
hi = g
hij= ij
หมวกไม่ได้ทำอะไรนอกจากจะเป็น Haskell ที่ถูกต้อง ตอนแรกฉันหวังว่าจะให้คำจำกัดความที่จะช่วยเราในรหัสในภายหลัง แต่มันก็ไม่ได้ นอกจากนี้ยังมีวิธีที่ง่ายกว่าในการสร้างหมวกเช่นช่องว่างและเครื่องหมายอัฒภาค แต่พวกเขาไม่ได้บันทึกไบต์ด้วยวิธีนี้ดังนั้นฉันจึงไม่ใส่ใจที่จะเปลี่ยน
Hardcoder
ดังนั้นตอนนี้ที่ฉันมีพื้นที่เพียงพอในบรรทัดฉันเริ่มค่าการเข้ารหัส นี่เป็นเรื่องที่ค่อนข้างน่าเบื่อ แต่ก็มีบางสิ่งที่น่าสนใจ สำหรับหนึ่งครั้งที่บรรทัดเริ่มได้รับอีกต่อไปเราสามารถใช้;
เพื่อประกาศหลายรายการในบรรทัดซึ่งช่วยให้เราตันของไบต์
ข้อที่สองคือเนื่องจากเราไม่สามารถเริ่มบรรทัดด้วยg
ทุก ๆ ครั้งได้บ่อยครั้งเราจึงต้องเยื้องบรรทัดเล็กน้อย ตอนนี้ Haskell ใส่ใจกับการเยื้องจริงๆดังนั้นมันจะบ่นเกี่ยวกับเรื่องนี้ อย่างไรก็ตามหากบรรทัดสุดท้ายก่อนที่บรรทัดที่เยื้องจะสิ้นสุดในเซมิโคลอนมันจะยอมให้ ทำไม? ฉันไม่ได้เป็นลม แต่ก็ใช้งานได้ ดังนั้นเราต้องจำไว้ว่าให้ใส่เครื่องหมายอัฒภาคไว้ที่ท้ายบรรทัด
ฟังก์ชันสำเร็จรูป
เมื่อเสร็จสิ้นการ hardcoder มันเป็นไปอย่างราบรื่นในตอนท้ายของโปรแกรม เราจำเป็นต้องสร้างฟังก์ชั่นง่ายๆ ครั้งแรกที่ฉันสร้างรุ่นของที่เรียกว่า drop
จะแตกต่างจากในว่าถ้าเราพยายามที่จะลดลงที่ผ่านมาท้ายของสตริงก็แค่ผลตอบแทน จะแตกต่างจากการดรอปในกรณีที่มันพยายามที่จะดรอปขึ้นบรรทัดใหม่มันจะกลับมาสิ่งเหล่านี้จะเป็นประโยชน์เพราะต่อมาเมื่อเราตรวจสอบว่าโปรแกรมเป็นรูปสามเหลี่ยมนี้จะช่วยให้เรากลับมาเมื่อ บรรทัดสิ้นสุดก่อนi
i
drop
"y"
i
"y"
False
k
k
nssTrue
nk
n + 1False
จากนั้นเราจะทำให้นามแฝงสำหรับ,k
เป็นเพียงกับในอาร์กิวเมนต์แรกและขึ้นบรรทัดใหม่ใช้ได้กับอาร์กิวเมนต์ที่สองm
m
k
1
o
ต่อไปเรามี o
ใช้ตัวเลขและสตริง มันเป็นตัวกำหนดว่าสตริงไบต์ (ละเว้นบรรทัดใหม่) สลับในความเท่าเทียมกัน (ใช้ของเราg
) เริ่มต้นด้วยหมายเลขอินพุต
สุดท้ายเรามีs
ซึ่งทำงานo
กับทั้ง1
และหากประสบความสำเร็จอย่างใดอย่างหนึ่งก็จะคล้อยตาม0
m
หากมันล้มเหลวทั้งคู่ก็จะกลับFalse
มา นี่คือฟังก์ชั่นที่เราต้องการ มันเป็นตัวกำหนดว่าการป้อนข้อมูลเป็นรูปสามเหลี่ยมและสลับ