มีจำนวนองค์ประกอบในข้อมูลของคุณ:
say elems <1 1 0 2 0 2 1 2 2 2 4 4 3 3>; # 14
grepบล็อกของคุณใช้สององค์ประกอบในแต่ละครั้ง:
{$^a eq $^b}
ดังนั้นหากคุณเพิ่มหรือลบองค์ประกอบคุณจะได้รับข้อผิดพลาดที่คุณได้รับเมื่อมีการเรียกใช้บล็อกในองค์ประกอบเดียวที่เหลือในตอนท้าย
มีหลายวิธีในการแก้ปัญหาของคุณ
แต่คุณยังถามเกี่ยวกับตัวเลือกในการอนุญาตให้ทับซ้อนกันเช่นคุณได้รับสอง(2 2)รายการย่อยเมื่อ2 2 2พบลำดับ และในหลอดเลือดดำที่คล้ายกันคุณอาจต้องการเห็นการแข่งขันสองรายการไม่ใช่ศูนย์โดยมีการป้อนข้อมูลเช่น:
<1 2 2 3 3 4>
ดังนั้นฉันจะมุ่งเน้นการแก้ไขปัญหาที่จัดการกับปัญหาเหล่านั้นด้วย
แม้จะมีการ จำกัด พื้นที่โซลูชันเพื่อจัดการกับปัญหาพิเศษ แต่ยังมีอีกหลายวิธีในการแสดงวิธีแก้ปัญหา
วิธีหนึ่งที่เพิ่มโค้ดอีกเล็กน้อยเข้าท้ายของคุณ:
my @s = <1 1 0 2 0 2 1 2 2 2 4 4 3 3>;
say grep {$^a eq $^b}, @s .rotor( 2 => -1 ) .flat
.rotorวิธีการแปลงรายการลงในรายการย่อยรายการ-แต่ละความยาวเดียวกัน ยกตัวอย่างเช่นการแสดงsay <1 2 3 4> .rotor: 2 ((1 2) (3 4))หากอาร์กิวเมนต์ความยาวเป็นคู่คีย์จะมีความยาวและค่าจะเป็นออฟเซ็ตสำหรับการเริ่มต้นคู่ถัดไป หากออฟเซตเป็นลบคุณจะได้รับรายการย่อยทับกัน ดังนั้นการแสดงsay <1 2 3 4> .rotor: 2 => -1((1 2) (2 3) (3 4))
.flatวิธีการ "แบน" invocant ของมัน ยกตัวอย่างเช่นการแสดงsay ((1,2),(2,3),(3,4)) .flat(1 2 2 3 3 4)
วิธีที่ง่ายกว่าในการเขียนวิธีการแก้ปัญหาข้างต้นคือการละเว้นflatและการใช้.[0]และ.[1]เพื่อจัดทำดัชนีในรายการย่อยที่ส่งคืนโดยrotor:
say @s .rotor( 2 => -1 ) .grep: { .[0] eq .[1] }
ดูความคิดเห็นของ Elizabeth Mattijsen สำหรับรูปแบบอื่นที่ทำให้ขนาดรายการย่อยเป็นแบบทั่วไป
หากคุณต้องการรูปแบบการเข้ารหัสทั่วไปมากขึ้นคุณอาจจะเขียนสิ่งที่ชอบ:
say @s .pairs .map: { .value xx 2 if .key < @s - 1 and [eq] @s[.key,.key+1] }
.pairsวิธีในรายการกลับรายการของคู่แต่ละคู่ที่สอดคล้องกับแต่ละองค์ประกอบในรายการ invocant ของตน .keyของแต่ละคู่เป็นดัชนีขององค์ประกอบในรายการ invocant นั้น .valueคุ้มค่าขององค์ประกอบ
.value xx 2สามารถเขียน.value, .valueได้ (ดูxx.)
@s - 1คือจำนวนขององค์ประกอบใน@sลบ 1
[eq]ใน[eq] listเป็นลดลง
หากคุณต้องการการจับคู่รูปแบบข้อความเพื่อตัดสินใจว่าองค์ประกอบใดที่มีองค์ประกอบเท่ากันอย่างต่อเนื่องคุณอาจแปลงรายการอินพุตให้เป็นสตริงให้จับคู่กับคำวิเศษณ์จับคู่ที่สร้างรายการการแข่งขันจากนั้นแมปจากรายการผลลัพธ์ของการจับคู่ที่คุณต้องการ ผลลัพธ์. เพื่อจับคู่กับการซ้อนทับ (เช่น2 2 2ผลลัพธ์ที่((2 2) (2 2))ใช้อยู่:ov:
say @s .Str .match( / (.) ' ' $0 /, :ov ) .map: { .[0].Str xx 2 }
2 2 2 2มันจะพิมพ์ 3(2 2)วินาทีซึ่งเป็นไปตามที่คาดไว้ ไม่เคยได้ยินเกี่ยวกับวิธีการที่rotorฉันเริ่มต้นด้วยsquishวิธีการและตรวจสอบว่ามันมีคุณสมบัติหรือข้อโต้แย้งเช่น@s.squish(:length 2, :multiple_instances yes)แต่มันไม่ได้มีคุณสมบัติดังกล่าวและมันก็ไม่เหมาะสำหรับงาน เมื่อเทียบกับsquish,rotorดูเหมือนว่าค่อนข้างพอดี จริงๆแล้วมันอาจจะเหมาะสมที่สุดสำหรับการทำงานประเภทนี้