วิธีนี้ใช้ได้กับค่าอินพุตที่จำเป็นทั้งหมด
ปัญหาที่ใหญ่ที่สุดของหน้าจอ Retina ในการท้าทายนี้คือความจริงที่ว่าสตริงมีความยาวสูงสุด 2 ^ 30 ตัวอักษรดังนั้นวิธีปกติในการจัดการกับตัวเลข (การแสดงแบบเอก) ไม่ทำงานกับค่าที่มากกว่า 2 ^ 30
เพื่อที่จะแก้ปัญหานี้ฉันได้นำวิธีการที่แตกต่างกันไปใช้การจัดเรียงตัวเลขทศนิยมแทนตัวเลข แต่ที่แต่ละหลักจะเขียนด้วยภาษาเดียว (ฉันจะเรียกวิธีนี้ว่าการเป็นตัวแทนดิจิทัล ) ยกตัวอย่างเช่นตัวเลข341
จะถูกเขียน111#1111#1#
ในรูปแบบดิจิทัล ด้วยการเป็นตัวแทนนี้เราสามารถทำงานกับตัวเลขสูงสุด2^30/10
(~ ร้อยล้านหลัก) มันใช้งานได้น้อยกว่า unary มาตรฐานสำหรับเลขคณิตโดยพลการ แต่ด้วยความพยายามเล็กน้อยเราสามารถดำเนินการใด ๆ ได้
หมายเหตุ: ดิจิทัลในทางทฤษฎีสามารถใช้ฐานอื่น ๆ (เช่นไบนารี110
จะอยู่1#1##
ในฐานที่ 2 ดิจิตัล) แต่เนื่องจาก Retina มี builtins ในการแปลงระหว่างทศนิยมและไม่เป็นเอกภาพและไม่มีวิธีโดยตรงที่จะจัดการกับฐานอื่น ๆ
อัลกอริทึมที่ฉันใช้คือทำให้การหารจำนวนเต็มต่อเนื่องสองจนกว่าเราจะถึงศูนย์จำนวนหน่วยงานที่เราทำคือจำนวนบิตที่จำเป็นในการเป็นตัวแทนของจำนวนนี้
ดังนั้นเราจะแบ่งสองหลักเป็นหน่วยหลักได้อย่างไร นี่เป็นตัวอย่างของ Retina ที่ทำ:
(1*)(1?)\1# We divide one digit, the first group captures the result, the second group captures the remainder
$1#$2$2$2$2$2 The result is put in place of the old number, the remainder passes to the next digit (so it is multiplied by 10) and is divided by two there -> 5 times the remainder goes to the next digit
การแทนที่นี้เพียงพอที่จะหารจำนวนหลักด้วย 2 เราเพียงแค่ต้องลบ. 5s ที่เป็นไปได้ออกจากท้ายหากหมายเลขเดิมเป็นเลขคี่
ดังนั้นนี่คือรหัสเต็มเราจะหารด้วยสองจนกว่าจะมีตัวเลขยังคงอยู่ในตัวเลขและใส่ตัวอักษรที่n
ด้านหน้าของสตริงที่การวนซ้ำแต่ละครั้ง: จำนวนn
ท้ายที่เป็นผลลัพธ์
. |
$*1# Convert to digitunary
{`^(.*1) Loop:|
n$1 add an 'n'
(1*)(1?)\1# |
$1#$2$2$2$2$2 divide by 2
)`#1*$ |
# erase leftovers
n Return the number of 'n's in the string
ลองออนไลน์!
โซลูชันที่อัปเดตแล้ว 37 ไบต์
การปรับโครงสร้างครั้งยิ่งใหญ่ด้วยแนวคิดที่ดีมากมายที่เล่นกอล์ฟได้ประมาณหนึ่งในสามของความยาวทั้งหมดขอบคุณ Martin Ender!
แนวคิดหลักคือใช้_
เป็นสัญลักษณ์ของเรา: ด้วยวิธีนี้เราสามารถใช้ตัวเลขปกติในสายอักขระของเราตราบใดที่เราแปลงกลับเป็น_
s เมื่อต้องการ: สิ่งนี้ช่วยให้เราประหยัดหลายไบต์ในการหารและการแทรกหลาย ตัวเลข
นี่คือรหัส:
<empty line> |
# put a # before each digit and at the end of the string
{`\d Loop:|
$*_ Replace each digit with the corrisponding number of _
1`_ |
n_ Add an 'n' before the first _
__ |
1 Division by 2 (two _s become a 1)
_# |
#5 Wherever there is a remainder, add 5 to the next digit
}`5$ |
Remove the final 5 you get when you divide odd numbers
n Return the number of 'n's in the string
ลองออนไลน์!