เคล็ดลับการเล่นกอล์ฟใน Perl 6


16

คุณมีเคล็ดลับทั่วไปสำหรับการเล่นกอล์ฟใน Perl 6 อย่างไร ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ Perl 6 (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ

โปรดทราบว่า Perl 6 ไม่ใช่ Perl 5 ดังนั้นคำถามนี้ไม่ซ้ำกัน เคล็ดลับส่วนใหญ่สำหรับการเล่น Perl 5 ไม่ใช้กับ Perl 6

คำตอบ:


9

หลีกเลี่ยงsubตัวอักษร ในหลายกรณีคุณสามารถใช้{}สำหรับการบล็อกโค้ดได้ ตัวอย่างเช่นอย่าเขียนรหัสต่อไปนี้

sub ($a){$a*2}

ให้ใช้บล็อกไวยากรณ์แทน นอกจากนี้ยังช่วยให้คุณสามารถที่จะใช้$_, @_และ%_ตัวแปรตัวยึดถ้าคุณต้องการเพียงตัวแปรเดียว หากท่านต้องการข้อมูลเพิ่มเติมคุณสามารถใช้$^a, $^bตัวแปรและอื่น ๆ

{$_*2}

นอกจากนี้ในบางกรณีที่ไม่ค่อยเกิดขึ้นคุณสามารถใช้รหัสใดก็ได้ (โดยเฉพาะเมื่อคุณมีนิพจน์ธรรมดา) *แทนที่อาร์กิวเมนต์ตัวยึด

* *2

8

Perl 6 มีคุณสมบัติที่แปลกประหลาดจริง ๆ ซึ่งอนุญาตให้ใช้อักขระ Unicode ทั้งหมดในประเภทNd , Nlและ  Noเพื่อใช้เป็นตัวอักษรจำนวนตรรกยะ บางส่วนเหล่านี้สั้นกว่าการเขียนค่าตัวเลขใน ASCII:

  • ¼(2 ไบต์) สั้นกว่า.25หรือ1/4(3 ไบต์)
  • ¾(2 ไบต์) สั้นกว่า.75หรือ3/4(3 ไบต์)
  • (3 ไบต์) สั้นกว่า1/16(4 ไบต์)
  • 𐦼(4 ไบต์) สั้นกว่า11/12(5 ไบต์)
  • 𒐲(4 ไบต์) สั้นกว่า216e3(5 ไบต์)
  • 𒐳(4 ไบต์) สั้นกว่า432e3(5 ไบต์)

ในฐานะที่ติดตามนี้คุณยังสามารถใช้เลขยกกำลัง Unicode แม้จะมีตัวเลขหลายและ / หรือลบ: ==>say (3² + 4², 2²⁰, 5⁻²) (25 1048576 0.04)รายการที่สมบูรณ์ของ Unicode คุณสามารถละเมิดเช่นนี้อยู่ที่นี่: docs.perl6.org/language/unicode_texas
Ramillies

8

เรียนรู้ฟังก์ชั่นเพื่ออ่านอินพุต Perl 6 มีฟังก์ชั่นที่น่าสนใจมากมายที่สามารถอ่านอินพุตจาก ARGV หรือ STDIN ได้อย่างง่ายดาย (หากไม่มีการระบุไว้ใน ARGV) ซึ่งสามารถย่อโค้ดของคุณได้หากใช้อย่างถูกต้อง หากคุณเรียกพวกเขาว่าเป็นวิธีจัดการกับไฟล์คุณสามารถบังคับให้พวกเขาทำงานกับ filehandle เฉพาะ (มีประโยชน์ถ้าคุณยกตัวอย่างเช่นอ่านจากSTDINแต่คุณต้องอ่านอาร์กิวเมนต์ของ ARGV)

get

ฟังก์ชั่นนี้รับเพียงบรรทัดเดียวแล้วทำการเปลี่ยนมันโดยอัตโนมัติดังนั้นคุณไม่จำเป็นต้องทำ สิ่งนี้มีประโยชน์หากคุณจำเป็นต้องอ่านเพียงหนึ่งบรรทัด

lines

ฟังก์ชันนี้รับทุกบรรทัดจากไฟล์หรือ STDIN มันเป็นรายการที่ขี้เกียจดังนั้นถ้าคุณใช้กับforมันมันจะอ่านเฉพาะสิ่งที่คุณต้องการ ตัวอย่างเช่น.

say "<$_>"for lines

slurp

นี่จะอ่านไฟล์ทั้งหมดหรือ STDIN และจะส่งคืนผลลัพธ์เป็นสตริงเดียว


ข้อผิดพลาดนั้นได้รับการแก้ไข - ไม่ทราบว่าเมื่อใด แต่say "<$_>" for linesทำงานได้ในขณะนี้
cat

5

คำเตือน : กำแพงข้อความใกล้เข้ามา มันเป็นลูกเล่นเล็ก ๆ ที่ฉันรวบรวมมาเมื่อเวลาผ่านไป

เขียนวิธีแก้ปัญหาของคุณเป็นบล็อกนิรนาม

สิ่งนี้ถูกกล่าวถึงแล้ว แต่ฉันต้องการจะย้ำอีกครั้ง ใน TIO คุณสามารถเขียนลงในส่วนหัวบล็อกเป็นรหัสที่เหมาะสมและเริ่มท้ายด้วยmy $f = ;สิ่งนี้ดูเหมือนจะเป็นวิธีที่สั้นที่สุดที่จะทำให้งานเสร็จ (เนื่องจากคุณไม่จำเป็นต้องสนใจอ่านข้อความใด ๆ เลยมันเป็นสิ่งที่คุณได้รับในการโต้แย้ง)

วิธีที่ดีอีกประการหนึ่งคือการใช้-nหรือ-pสวิทช์ แต่ผมไม่ได้หาวิธีที่จะทำให้การทำงานใน TIO

ใช้ไวยากรณ์ลำไส้ใหญ่สำหรับการส่งผ่านข้อโต้แย้ง

นั่นคือแทนที่จะthing.method(foo,bar)คุณสามารถทำthing.method:foo,barและบันทึก 1 ตัวอักษร น่าเสียดายที่คุณไม่สามารถเรียกวิธีอื่นในผลลัพธ์ด้วยเหตุผลที่ชัดเจนดังนั้นจึงเหมาะสมที่จะใช้สำหรับวิธีสุดท้ายในบล็อกเท่านั้น

ใช้$_มากเท่าที่คุณสามารถ

บางครั้งการใช้อาร์กิวเมนต์รายการเดียวจะดีกว่าหลายอาร์กิวเมนต์ เมื่อมีการเข้าถึง$_คุณอาจเรียกวิธีการที่มันเพียงแค่เริ่มต้นด้วยจุด: เช่นจะมีค่าเท่ากับ.sort$_.sort

อย่างไรก็ตามโปรดทราบว่าแต่ละบล็อกได้รับเป็นของตัวเอง$_ดังนั้นพารามิเตอร์ของบล็อกด้านนอกจะไม่แพร่กระจายไปยังด้านใน หากคุณต้องการเข้าถึงพารามิเตอร์ของฟังก์ชั่นหลักจากบล็อกด้านใน ...

ใช้^ตัวแปรหากคุณไม่สามารถใช้ได้$_

แทรกระหว่างเครื่องหมายและชื่อตัวแปรเช่นนี้^ $^aใช้งานได้เฉพาะภายในบล็อกเท่านั้น คอมไพเลอร์จะนับจำนวนของสิ่งเหล่านี้ที่คุณมีในบล็อกเรียงลำดับพจนานุกรมและจากนั้นกำหนดอาร์กิวเมนต์แรกให้กับอาร์กิวเมนต์แรกหนึ่งในสองและหนึ่งต่อไป ^ความต้องการที่จะนำมาใช้เฉพาะในการเกิดขึ้นครั้งแรกของตัวแปร ดังนั้น{$^a - $^b}ใช้ 2 สเกลาร์และลบออก สิ่งเดียวที่สำคัญคือลำดับตัวอักษรดังนั้น{-$^b + $^a}สิ่งเดียวกัน

หากคุณเคยรู้สึกว่าการใช้ไวยากรณ์บล็อกแหลม (เช่น->$a,$b {$a.map:{$_+$b}}) คุณจะดีกว่าการเขียนคำสั่งปลอมที่จุดเริ่มต้นของบล็อกโดยใช้^สำหรับแต่ละอาร์กิวเมนต์ที่คุณจะไม่ใช้ในบล็อกหลัก (เช่น{$^b;$^a.map:{$_+$b}}) (หมายเหตุ) วิธีที่ดีกว่าในการเล่นกอล์ฟนี่คือ{$^a.map(*+$^b)}ฉันแค่อยากอวดคอนเซ็ปต์)

อ่านเอกสารของโอเปอเรเตอร์อย่างระมัดระวัง

ผู้ประกอบการมีประสิทธิภาพมากและบ่อยครั้งที่พวกเขาเป็นวิธีที่สั้นที่สุดในการทำสิ่งต่างๆให้สำเร็จ โดยเฉพาะอย่างยิ่งผู้ประกอบการเมตา (ผู้ประกอบการที่ใช้ประกอบเป็นอาร์กิวเมนต์) [], [\], X, <</ >>และZมีความคุ้มค่าของความสนใจของคุณ อย่าลืมว่า meta-op สามารถใช้ meta-op อื่นเป็นอาร์กิวเมนต์ (เช่นXZ%%ฉันจัดการให้ใช้ที่นี่ ) คุณสามารถใช้>>วิธีการโทรด้วยซึ่งอาจมีราคาถูกกว่าแผนที่ ( @list>>.methodแทนที่จะเป็น@list.map(*.method)แต่ควรระวังพวกเขาไม่เหมือนกัน! ) และสุดท้ายก่อนที่คุณจะใช้เลขฐานสอง<< >>โปรดจำไว้ว่าZบ่อยครั้งที่จะทำสิ่งเดียวกันในตัวละครน้อยลง

หากคุณกองจำนวนมาก meta-Ops บนแต่ละอื่น ๆ []คุณสามารถระบุลำดับความสำคัญการใช้วงเล็บ ที่จะช่วยคุณประหยัดเมื่อคุณพะเนินเทินทึกผู้ประกอบการจำนวนมากว่ามันสับสนคอมไพเลอร์ (นั่นไม่ได้เกิดขึ้นบ่อยมาก)

สุดท้ายถ้าคุณต้องการสิ่งที่จะบีบบังคับ Bool, Int หรือ Str ไม่ได้ใช้วิธีการ.Bool, .Intและ.Strแต่ผู้ประกอบการ?, และ+ ~หรือดีกว่าเพียงแค่วางมันลงในนิพจน์ทางคณิตศาสตร์เพื่อบังคับให้พวกมันเข้าสู่ Int เป็นต้น +@listทางที่สั้นที่สุดที่จะได้รับความยาวของรายการคือ หากคุณต้องการคำนวณ 2 ถึงความยาวของรายการเพียงแค่พูด2**@listและมันจะทำสิ่งที่ถูกต้อง

ใช้ตัวแปรรัฐอิสระ$, @และ%

ในแต่ละบล็อกเกิดขึ้นของทุก$(หรือ@หรือ%) หมายถึงสเกลาเงาใหม่ (หรืออาร์เรย์หรือกัญชา) รัฐตัวแปร (ตัวแปรที่มีค่ายังคงมีอยู่ทั่วโทรไปยังบล็อก) หากคุณต้องการตัวแปรสถานะที่จำเป็นต้องอ้างอิงเพียงครั้งเดียวในซอร์สโค้ดทั้งสามนี้เป็นเพื่อนใหญ่ของคุณ (ส่วนใหญ่มักจะเป็น$.) ยกตัวอย่างเช่นในวงจรย้อนกลับคณิตศาสตร์$++%6ท้าทายก็สามารถนำมาใช้ในการเลือกผู้ประกอบการจะวนจากอาร์เรย์ซึ่งได้รับการจัดทำดัชนีโดย

ใช้รูปแบบย่อยmap, grepet al,

นั่นหมายความว่า: ทำค่อนข้างกว่าmap {my block},list list.map({my block})แม้ว่าคุณจะสามารถใช้งานได้list.map:{my block}สองวิธีนี้จะมีจำนวนไบต์เท่ากัน และบ่อยครั้งที่คุณจะต้องวงเล็บรายการเมื่อเรียกวิธีการ แต่ไม่เมื่อเรียกย่อย ดังนั้นวิธีการย่อยออกมาดีกว่าหรืออย่างน้อยก็เหมือนกับวิธีที่หนึ่ง

ยกเว้นอย่างเดียวที่นี่คือเมื่อวัตถุซึ่งจะmapped, grepped และอื่น ๆ $_ที่อยู่ใน จากนั้นเห็นได้ชัดเต้น.map:{}map {},$_

ใช้ทางแยก ( &และ|) แทนและ&&||

เห็นได้ชัดว่าพวกมันสั้นลง 1 ไบต์ ในทางกลับกันพวกเขาจะต้องยุบตัวโดยถูกบังคับให้เข้าสู่บริบทบูลีน สิ่งนี้สามารถทำได้ด้วย?เสมอ ที่นี่คุณควรทราบ meta-op !opที่บังคับให้บริบท bool ใช้opและคัดค้านผลลัพธ์

หากคุณมีรายการและคุณต้องการที่จะเปิดเป็นชุมทางที่ไม่ได้ใช้และ[&] [|]แทนที่จะใช้และ.any .allนอกจากนี้ยังมี.noneสิ่งที่ไม่สามารถลอกเลียนแบบได้ง่ายโดยจุดเชื่อมต่อ


1
ฉันคิดว่า&&และ||ยังคงมีประโยชน์สำหรับการลัดวงจรหรือไม่
ASCII เท่านั้น

@ ASCII เท่านั้น: ใช่แน่นอนพวกเขาเป็น
Ramillies

4

ลดพื้นที่ที่ใช้สำหรับตัวแปร

มีบางส่วนของสิ่งนี้

ลบช่องว่าง

ตัวแปรที่ประกาศโดยใช้myสามารถประกาศได้โดยไม่มีช่องว่างระหว่างmyและชื่อตัวแปร เทียบเท่ากับmy @amy@a

ใช้ตัวแปร sigil-less

คุณสามารถประกาศตัวแปรโดยใช้แบ็กสแลชเพื่อลบ sigil ก่อนชื่อตัวแปรเช่น:

my \a=1;

(น่าเสียดายที่คุณไม่สามารถลบพื้นที่ได้ :()

สิ่งนี้มีประโยชน์เนื่องจากคุณสามารถอ้างถึงได้ว่าเป็นชื่อตัวแปรเปล่าในภายหลัง

 a=5;
 a.say

โดยพื้นฐานแล้วจะช่วยประหยัดไบต์หากคุณใช้ตัวแปรมากกว่าหนึ่งครั้งในที่อื่นในรหัสของคุณ ข้อเสียคือตัวแปรจะต้องเริ่มต้น

ใช้$!และ$/

ตัวแปรเหล่านี้ก่อนประกาศมักจะใช้สำหรับข้อยกเว้นและการแข่งขัน regex ตามลำดับ myแต่ไม่จำเป็นต้องได้รับการกำหนดโดยใช้

$!=1;
$/=5;

มีประโยชน์อย่างยิ่งคือการใช้$/เป็นอาร์เรย์และใช้ทางลัด$ตามด้วยหมายเลขในการเข้าถึงองค์ประกอบของ$/อาร์เรย์นั้น

$/=100..200;
say $5;  #105
say $99; #199

2

ใช้...แทนfirst

โดยทั่วไปหากคุณต้องการค้นหาหมายเลขแรกที่ตรงกับเงื่อนไข&fคุณสามารถแทนได้ดังนี้:

first &f,1..*

อย่างไรก็ตามคุณสามารถใช้...โอเปอเรเตอร์แทนได้:

+(1...&f)

หากคุณต้องเริ่มต้นจาก0คุณสามารถมีหลังจากนั้นแทน-1+

หากคุณต้องการให้ดัชนีขององค์ประกอบแรกในรายการ@aที่มีเงื่อนไข&fโดยปกติคุณจะ:

first &f,@a,:k

แทน:

(@a...&f)-1

(หรือกลับกันถ้าคุณต้องการจัดทำดัชนี 0) ในทำนองเดียวกันคุณสามารถรับองค์ประกอบทั้งหมดจนถึงองค์ประกอบแรกที่ผ่านเงื่อนไข

ข้อเสียนี้คือรายการมีที่จะผ่านเงื่อนไขในบางจุดที่มิฉะนั้น...ผู้ประกอบการจะพยายามที่จะคาดการณ์ปิดท้ายของรายการและส่วนใหญ่มีแนวโน้มที่โยนความผิดพลาด คุณไม่สามารถใช้รหัสใด ๆ ที่ด้านซ้ายมือได้เนื่องจากจะถูกตีความว่าเป็นส่วนหนึ่งของลำดับ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.