เคล็ดลับสำหรับการเล่นกอล์ฟใน CJam


43

CJamสแต็คที่ใช้ภาษาในการเล่นกอล์ฟ GolfScript แรงบันดาลใจที่สร้างขึ้นโดยผู้ใช้ PPCG aditsu

ดังนั้นในคำถามเคล็ดลับเฉพาะภาษาอื่น ๆ ของหลอดเลือดดำ:

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


4
ดูเพิ่มเติมเคล็ดลับสำหรับการเล่นกอล์ฟใน GolfScript ; ภาษามีความคล้ายคลึงกันมากพอที่จะปรับใช้เทคนิคต่าง ๆ ได้หลายวิธี
Ilmari Karonen

2
@IlmariKaronen หลังจากที่ได้รับคำตอบในคำถามนั้นฉันจะบอกว่ามีเพียงครึ่งเดียวเท่านั้นที่ใช้กับ CJam เนื่องจากความแตกต่างทางไวยากรณ์หรือตรรกะในภาษาต่างๆ
เครื่องมือเพิ่มประสิทธิภาพ

คำตอบ:


23

แก้ไขโมดูโลสำหรับตัวเลขลบ

มันมักจะน่ารำคาญที่ผลลัพธ์ของการดำเนินการแบบโมดูโลให้สัญญาณเหมือนกับตัวถูกดำเนินการแรก เช่น-5 3%ให้แทน-2 1บ่อยกว่าที่คุณไม่ต้องการหลัง การแก้ไขแบบไร้เดียงสาคือการใช้แบบโมดูโลเพิ่มตัวหารหนึ่งครั้งและใช้แบบโมดูโลอีกครั้ง:

3%3+3%

แต่นั่นยาวและน่าเกลียด แต่เราสามารถใช้ความจริงที่ว่าการจัดทำดัชนีอาร์เรย์อยู่เสมอแบบแยกส่วนและไม่ทำงานอย่างถูกต้องกับดัชนีเชิงลบ ดังนั้นเราแค่เปลี่ยนตัวหารเป็นช่วงและเข้าถึงที่:

3,=

นำไปใช้กับ-5สิ่งนี้ให้1ตามที่คาดไว้ และมีความยาวมากกว่าหนึ่งไบต์%!

ถ้าโมดูลัสเป็นกำลัง 2 คุณสามารถบันทึกไบต์อื่นโดยใช้การคำนวณบิตทริก (ซึ่งเร็วกว่ามากเช่นกัน) เปรียบเทียบ:

32,=
31&

สำหรับกรณีพิเศษของ65536 == 2^16ไบต์อื่นสามารถบันทึกได้โดยใช้ลักษณะการตัดคำของชนิดอักขระ:

ci

13

การผลักดันช่วงของอักขระที่ต่อกัน

  • สตริงที่มีตัวเลขทั้งหมด"0123456789"สามารถเขียนเป็น

    A,s
    
  • ตัวอักษร ASCII ตัวพิมพ์ใหญ่ ( A-Z) สามารถเลื่อนเป็น

    '[,65>
    

    ซึ่งสร้างสตริงของอักขระทั้งหมดจนถึงZจากนั้นละ 65 ตัวแรก (ถึง@ )

  • ตัวอักษร ASCII ทั้งหมด ( A-Za-z) สามารถผลักดันเป็น

    '[,65>_el+
    

    ซึ่งใช้งานได้ด้านบนจากนั้นสร้างสำเนาแปลงเป็นตัวพิมพ์เล็กและต่อท้าย

    แต่มีวิธีที่สั้นกว่าที่จะทำมัน!

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

    '[,_el^
    

    '[,สร้างช่วงของอักขระ ASCII ทั้งหมดขึ้นอยู่กับZ , _elสร้างสำเนาตัวพิมพ์เล็กและ^ช่วยให้ตัวละครเดียวของสายทั้งที่ปรากฏในหนึ่ง แต่ไม่ใช่ทั้งสอง

    เนื่องจากตัวอักษรทั้งหมดในสตริงแรกเป็นตัวพิมพ์ใหญ่ทั้งหมดในตัวที่สองเป็นตัวพิมพ์เล็กและตัวอักษรที่ไม่ใช่ตัวอักษรทั้งหมดอยู่ในทั้งสองสตริงผลลัพธ์ในสตริงของตัวอักษร

  • ตัวอักษร RFC 1642 Base64 ( A-Za-z0-9+/) สามารถผลักได้โดยใช้เทคนิคด้านบนและต่อท้ายตัวอักษรที่ไม่ใช่:

    '[,_el^A,s+"+/"+
    

    วิธีที่สั้นพอ ๆ กันในการกดสตริงนี้ใช้ความแตกต่างแบบสมมาตรเพียงอย่างเดียว:

    "+,/0:[a{A0":,:^
    

    เราจะหาสตริงที่จุดเริ่มต้นได้อย่างไร

    ทุกช่วงตัวละครที่ใช้ ( A-Z, a-z, 0-9, +, /) สามารถผลักดันให้เป็นความแตกต่างที่สมมาตรในช่วงที่เริ่มต้นที่ไบต์โมฆะคือ'A,'[,^, 'a,'{,^, '0,':,^, และ'+,',,^'/,'0,^

    ดังนั้นการดำเนินการ:,:^ในการ"A[a{):+,/0"ที่จะผลักดันตัวละครที่ต้องการ แต่ไม่ได้อยู่ในลำดับที่ถูกต้อง

    เราจะหาคำสั่งที่เหมาะสมได้อย่างไร กำลังดุร้ายต่อการช่วยเหลือ! โปรแกรม

    '[,_el^A,s+"+/"+:T;"0:A[a{+,/0"e!{:,:^T=}=
    

    วนซ้ำทุกการเรียงสับเปลี่ยนที่เป็นไปได้ของสตริงใช้:,:^และเปรียบเทียบผลลัพธ์กับเอาต์พุตที่ต้องการ ( Permalink )

  • ตัวอักษร radix-64 ที่ใช้เช่นโดย crypt ( .-9A-Za-z) สามารถสร้างขึ้นได้โดยใช้วิธีการด้านบน:

    ".:A[a{":,:^
    

    นี่เป็นวิธีที่สั้นที่สุดที่ฉันรู้

    เนื่องจากอักขระทั้งหมดในเอาต์พุตที่ต้องการอยู่ในลำดับ ASCII จึงไม่จำเป็นต้องวนซ้ำในการเรียงสับเปลี่ยน

  • :,:^ไม่ได้ทุกช่วงการตัดแบ่งตัวละครที่สามารถผลักดันในการสั่งซื้อที่ต้องการใช้

    ยกตัวอย่างเช่นในช่วง0-9A-Za-z;-?ที่ไม่สามารถผลักดันโดยการดำเนินการเกี่ยวกับการเปลี่ยนแปลงใด:,:^"0:A[a{;@"

    อย่างไรก็ตามเราสามารถค้นหารูปแบบที่หมุนได้ของสตริงที่ต้องการซึ่งสามารถทำได้โดยใช้รหัส

    A,'[,_el^'@,59>]s2*:T;"0:A[a{;@"e!{:,:^T\#:I)}=Ip
    

    ซึ่งจะพิมพ์ ( Permalink ) ต่อไปนี้:

    10
    0:@[a{A;
    

    ซึ่งหมายความว่า

    "0:@[a{A;":,:^Am>
    

    มีผลเช่นเดียวกับ

    A,'[,_el^'@,59>]s
    

    ซึ่งสามารถใช้กับสแต็คที่ว่างเปล่าโดยไม่ต้อง prepending[


11

หลีกเลี่ยง {…} {…} หรือไม่

สมมติว่าคุณมีจำนวนเต็มในกองซ้อน ถ้ามันแปลกคุณต้องการคูณมันด้วย 3 แล้วบวก 1; มิฉะนั้นคุณต้องการหารด้วย 2

คำสั่ง "ปกติ" ถ้า / else จะมีลักษณะเช่นนี้:

_2%{3*)}{2/}?

อย่างไรก็ตามการใช้บล็อกนั้นไม่ใช่วิธีที่จะไปเนื่องจาก{}{}เพิ่มสี่ไบต์ไปแล้ว ?ยังสามารถใช้เพื่อเลือกหนึ่งในสองรายการในสแต็ก:

_2%1$3*)@2/?

นี่คือหนึ่งไบต์ที่สั้นกว่า


บล็อก-? หากไม่มีคำสั่งว่างให้เว้นว่างไว้ ตัวอย่างเช่น,

{}{2/}?

มีความยาวมากกว่าสองไบต์

{2/}|

ถ้าคุณมี

{2/}{}?

และสิ่งที่คุณกำลังตรวจสอบคือจำนวนเต็มไม่เป็นลบคุณสามารถทำได้

g)/

ใหม่{}&และ{}|มีประโยชน์ แต่บางครั้งก็มีปัญหาถ้าคุณไม่สามารถถ่วงกองได้

ยังคงในกรณีของ

_{…}{;}?

คุณสามารถใช้ตัวแปรชั่วคราวแทน:

:T{T…}&

1
!)/และg)/จะสั้นกว่าในตัวอย่าง
jimmy23013

11

สลับคำสั่ง

CJam ไม่มีคำสั่งสลับ ซ้อนกันถ้างบทำงานเช่นกัน แต่{{}{}?}{}?มีความยาว 12 ไบต์อยู่แล้ว ...

หากเราสามารถแปลงสภาพให้เป็นจำนวนเต็มขนาดเล็กที่ไม่เป็นลบได้เราสามารถแปลงคำสั่งเคสทั้งหมดในสตริงที่คั่นด้วยและประเมินผลลัพธ์ที่สอดคล้องกัน

ตัวอย่างเช่นถ้าเราต้องการที่จะดำเนินการcode0ถ้าจำนวนเต็มของสแต็คเป็น0 , code1ถ้ามันเป็น1และcode2ถ้ามันเป็น2เราสามารถใช้อย่างใดอย่างหนึ่ง

_{({code2}{code1}?}{;code0}?

หรือ

[{code0}{code1}{code2}]=~

หรือ

"code0 code1 code2"S/=~

S/แยกสตริงเข้าสู่["code0" "code1" "code2"], =สารสกัดจากก้อนที่สอดคล้องกันและ~ประเมินรหัส

คลิกที่นี่เพื่อดูคำสั่งสลับการทำงาน

ในที่สุดตามที่แนะนำโดย @ jimmy23013 และ @RetoKoradi เราสามารถทำให้สวิตช์สั้นลงได้มากขึ้นในบางกรณี Say code0, code1และcode2มีความยาวL 0 , L 1และL 2ตามลำดับ

ถ้าL 0 = L 1 ≥ L 2

"code0code1code2"L/=~

สามารถใช้แทนซึ่งLเป็นL 0 แทนที่จะแยกที่ตัวคั่นให้/แบ่งสตริงออกเป็นส่วน ๆ ที่มีความยาวเท่ากันที่นี่

ถ้าL 0 ≥ L 1 ≥ L 2 ≥ L 0 - 1 ,

"cccooodddeee012">3%~

สามารถนำมาใช้แทน >ลบองค์ประกอบ 0, 1 หรือ 2 จากจุดเริ่มต้นของสตริงและ3%แยกทุกองค์ประกอบที่สาม (เริ่มต้นด้วยองค์ประกอบแรก)


สำหรับตัวอย่างสุดท้ายนั่นมีข้อได้เปรียบมากกว่านี้ "code0code1code2"5/=~หรือไม่? ดูเหมือนจะตรงไปตรงมามากขึ้นสำหรับฉันและมันมีความยาวเท่ากัน
Reto Koradi

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

11

การเล่นกอล์ฟค่าอาร์เรย์และสตริงทั่วไป

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

  • [0 1]2,สามารถเขียนเป็น
  • [1 0]สามารถเขียนเป็นYYb(เช่น 2 ในไบนารี)
  • [1 1]สามารถเขียนเป็นZYb(เช่น 3 ในไบนารี)
  • เมทริกซ์สามารถเขียนเป็น[[0 1] [1 0]]2e!
  • [LL] สามารถเขียนเป็นSS/(แยกช่องว่างด้วยช่องว่างเดียว)
  • "\"\""L`สามารถเขียนเป็น
  • "{}"{}sสามารถเขียนเป็น

หลังสามารถขยายเป็นกรณีที่คุณต้องการประเภทวงเล็บทั้งหมดเพื่อบันทึกไบต์อื่น:

  • "[{<()>}]"{<()>}a`สามารถเขียนเป็น
  • "()<>[]{}"{<()>}a`$สามารถเขียนเป็น

โดยเฉพาะอย่างยิ่งเคล็ดลับการแปลงฐานอาจเป็นประโยชน์ในการจำสำหรับกรณี obscurer บางอย่างที่ปรากฏขึ้นทุกขณะ เช่น[3 2]จะเป็นE4b(14 ในฐาน 4)

ในกรณีที่ทำได้ยากยิ่งขึ้นคุณอาจพบว่าตัวดำเนินการตัวประกอบmfมีประโยชน์ เช่นเป็น[2 7]Emf

โปรดขยายรายการนี้หากคุณเจอตัวอย่างอื่น ๆ


10

การล้างสแต็ก

หากคุณต้องการล้างสแต็กทั้งหมดให้ล้อมในอาเรย์แล้ววางไว้:

];

สิ่งที่ยุ่งยากกว่าก็คือถ้าคุณทำการคำนวณจำนวนมาก แต่ต้องการเก็บองค์ประกอบสแต็คด้านบนและทิ้งทุกอย่างที่อยู่ด้านล่าง วิธีการที่ไร้เดียงสาคือการจัดเก็บองค์ประกอบบนสุดในตัวแปรล้างสแต็กดันตัวแปร แต่มีทางเลือกที่สั้นกว่ามาก: ห่อสแต็กในอาร์เรย์และแยกองค์ประกอบสุดท้าย:

]W=

(ขอบคุณเครื่องมือเพิ่มประสิทธิภาพที่แสดงสิ่งนี้ให้ฉันเมื่อวันก่อน)

แน่นอนถ้ามีเพียงสององค์ประกอบในกองซ้อน\;จะสั้นกว่า


\;จะปรากฏองค์ประกอบด้านล่าง TOS เท่านั้น คุณหมายถึง;;อะไร
CalculatorFeline

1
@CalculatorFeline ในช่วงครึ่งหลังของคำตอบนั้นเกี่ยวกับการล้างทุกอย่างยกเว้น TOS
Martin Ender

9

e และพลังของสิบ

ในภาษาอื่น ๆ อีกมากมายคุณสามารถเขียน1e3แทน1000ใน CJam

วิธีนี้ใช้ได้กับฐานที่ไม่ใช่จำนวนเต็มและแม้กระทั่งสำหรับเลขชี้กำลังจำนวนเต็มเช่นกัน ตัวอย่างเช่น1.23e2กด123.0และ1e.5กด3.1622776601683795 (รากที่สองของ10 )

สิ่งที่ไม่ชัดเจนในทันที1e3คือจริง ๆ แล้วเป็นสองโทเค็น:

  • 1ดันจำนวนเต็ม1บนสแต็ก

  • e3คูณได้โดย1000

เหตุใดจึงสำคัญ

  • คุณสามารถโทรหาe<numeric literal>บางอย่างที่มีอยู่แล้วในสแต็ก

    2 3 + e3 e# Pushes 5000.
    
  • คุณสามารถแมปe<numeric literal>ผ่านอาร์เรย์ได้

    5 , :e3  e# Pushes [0 1000 2000 3000 4000].
    

9

บรรทัดฐานแบบยุคลิด

วิธีที่ตรงไปตรงมาในการคำนวณหาปริภูมิแบบยุคลิดของเวกเตอร์คือ, สแควร์รูทของผลรวมของกำลังสองขององค์ประกอบ

2f#:+mq

อย่างไรก็ตามมีวิธีที่สั้นกว่ามาก

mhผู้ประกอบการด้านตรงข้ามมุมฉากที่ปรากฏจำนวนเต็มสองจำนวนและจากสแต็คและผลักดันsqrt (ก2 + B 2 )

หากเรามีเวกเตอร์x: = [x 1 … x n ], n> 1บนสแต็ก:mh(ลดลงด้วยด้านตรงข้ามมุมฉาก) จะบรรลุดังนี้:

  • x 1แรกและx 2ถูกผลักและmhถูกดำเนินการโดยปล่อยให้sqrt (x 1 2 + x 2 2 )บนสแต็ก

  • จากนั้นผลักx 3และmhดำเนินการอีกครั้งโดยปล่อย
    sqrt (sqrt (x 1 2 + x 2 2 ) 2 + x 3 2 ) = sqrt (x 1 2 + x 2 2 + x 3 2 )บนสแต็ก

  • หลังจากx nได้รับการประมวลผลที่เราจะเหลือsqrt (x 1 2 + x ... n 2 ) , บรรทัดฐานของยูคลิดx

หากn = 1และx 1 <0โค้ดด้านบนจะสร้างผลลัพธ์ที่ไม่ถูกต้อง:mhzทำงานอย่างไม่มีเงื่อนไข (ขอบคุณ @ MartinBüttnerสำหรับการชี้ว่า)

ฉันใช้เคล็ดลับนี้เป็นครั้งแรกในคำตอบนี้


2
ของหลักสูตรนี้มีผลกระทบต่อการวิเคราะห์เชิงตัวเลขของโปรแกรมของคุณ ...
ปีเตอร์เทย์เลอร์

8

แปลงจากฐาน n ด้วยรายการตัวเลขที่มากกว่า n

CJam แปลงรายการเป็นตัวเลขด้วยสูตรนี้: A 0 * n l + A 1 * n l-1 + A 2 * n l-2 + A l * n 0 (โดยไม่จำเป็นต้องลบn) nเป็นฐานและlเป็นความยาวของรายการ นี่หมายความว่าฉันสามารถเป็นจำนวนเต็มใด ๆ ซึ่งไม่จำเป็นต้องอยู่ในช่วง[0,n)ซึ่งไม่จำเป็นต้องเป็นในช่วงของ

ตัวอย่างบางส่วน:

  • 0bแยกรายการสุดท้ายและส่งไปที่จำนวนเต็ม ทำงานเหมือนW=iและบันทึกไบต์ถ้าไม่ใช่จำนวนเต็ม แต่ทุกอย่างในรายการจะต้องสามารถแปลงเป็นจำนวนเต็มได้
  • 1bส่งคืนผลรวม ทำงานเหมือน:i:+และบันทึกสองไบต์หากไม่ใช่จำนวนเต็ม นอกจากนี้ยังทำงานกับรายการที่ว่างเปล่าในขณะที่:+ไม่ได้
  • [i{_1&9 32?_@\m2/}16*;]W%:c2bcแปลงตัวอักษรสตริงตอนจบบรรทัดและแท็บซึ่งสามารถจะกลับมาแปลงด้วย อย่างไรก็ตามฟังก์ชั่นการเข้ารหัสไม่ใช่เรื่องง่ายที่จะเล่นกอล์ฟในโปรแกรมรหัสกอล์ฟ แต่โดยปกติคุณไม่ต้องการสิ่งนั้น
  • คุณสามารถใช้รหัสต่อไปนี้การแปลงสตริงอักขระ Unicode ไม่ได้อยู่ใน 16 2A#b128b:cบิตซึ่งสามารถแปลงกลับมาด้วย (คำอธิบายจะถูกเพิ่มในภายหลังหรือบางทีฉันจะเขียนเวอร์ชันใหม่ในภายหลัง)

    128b2A#b         " Convert to base 1024. ";
    W%2/)W%\:+       " Convert to two base 1024 digit groups. ";
    [0X@
    {
      _54+
      @I+_Am>@\-
      _Am<@+ 0@-@1^
    }fI
    ]);)
    @\+[~+]2A#b_2G#<!{2A#b}*
    \W%+:c
    

วิธีการที่คล้ายกันนี้ทำงานได้กับชุดnจำนวนเต็มใด ๆที่มีการปรับค่าต่างกันnถ้าคุณสามารถหาวิธีกำจัดตัวเลขที่สำคัญที่สุดได้


8

การใช้ $เป็นประกอบไปด้วยถ้า

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

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

หากคุณมีA B Cสแต็กคุณสามารถดำเนินการได้

!$

แทน

\@?

เพื่อคัดลอกBถ้าCเป็นความจริงและAอย่างอื่น

หากCเป็นบูลีนจริง ( 0หรือ1) คุณสามารถดำเนินการได้

$

แทน

@@?

เพื่อคัดลอกAหากCเป็นความจริงและเป็นBอย่างอื่น


ในการเข้าใจถึงปัญหาหลังนี้เป็นเคล็ดลับที่ค่อนข้างชัดเจน แต่ฉันไม่เคยคิดมาก่อน ฉันใช้มันเป็นครั้งแรกในคำตอบนี้
Dennis

7

แผนที่สำหรับรายการซ้อน

สมมติว่าคุณมีรายการซ้อนเช่นเมทริกซ์:

[[0 1 2][3 4 5][6 7 8]]

หรืออาร์เรย์ของสตริง:

["foo""bar"]

และคุณต้องการแมปบล็อกไปยังระดับที่ซ้อนกัน (เช่นใช้กับแต่ละหมายเลขหรืออักขระแต่ละตัว) โซลูชันไร้เดียงสานั้นซ้อนกัน%:

{{...}%}%

f%แต่คุณจริงสามารถผลักดันบล็อกภายในลงบนสแต็คและการใช้งานแล้ว fคือ "แผนที่พร้อมพารามิเตอร์เพิ่มเติม" ดังนั้นมันจะจับคู่%กับรายการภายนอกโดยใช้บล็อกเป็นพารามิเตอร์ที่สอง:

{...}f%

บันทึกสองไบต์

เคล็ดลับอีกอย่างที่ต้องทำfor (i=0; i<5; ++i) for (j=0; j<5; ++j) {...}คือ

5,_f{f{...}}

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

สิ่งนี้มีจำนวนอักขระเหมือนกันกับการจับคู่บล็อกกับผลิตภัณฑ์คาร์ทีเซียน (แม้ว่าตัวละครจะสั้นลงหากคุณต้องการคู่เป็นอาร์เรย์):

5,_m*{~...}%

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

ขอบคุณเดนนิสที่แสดงเคล็ดลับนี้ให้ฉัน

0.6.4 อัปเดต

fและ:ตอนนี้ได้รับการปรับปรุงอย่างมากโดยการดำเนินการอื่น ๆ รวมถึงตัวเอง ซึ่งหมายความว่าคุณสามารถบันทึกได้มากขึ้นในขณะนี้ การแมปโอเปอเรเตอร์กับรายการที่ซ้อนกันยิ่งสั้นลงตอนนี้:

{:x}%
{x}f%
::x

สิ่งนี้ไม่ได้ช่วยในเรื่องการแมปบล็อกลงในรายการที่ซ้อนกัน

สำหรับการใช้บล็อกหรือตัวดำเนินการกับผลิตภัณฑ์คาร์ทีเซียนสิ่งนี้ก็สั้นลงเช่นกันสำหรับบล็อกและตัวดำเนินการ:

5,_f{f{...}}
5,_ff{...}

5,_f{fx}
5,_ffx

สิ่งที่ดีคือตอนนี้คุณสามารถซ่อนสิ่งเหล่านี้ได้ ดังนั้นคุณสามารถใช้โอเปอเรเตอร์ได้ง่ายๆเช่นเดียวกับรายการระดับที่สาม:

:::x

หรือบล็อกที่มีเล่ห์เหลี่ยมบางอย่าง:

{...}ff%

การปรับปรุงที่ดี แต่ก็ยังไม่มีf~...
jimmy23013

@ user23013 fคาดว่าผู้ประกอบการไบนารี่~จะไม่พร้อม; คุณไม่อาจต้องการ:~? นอกจากนี้เราสามารถพูดคุยเรื่องนี้ในการแชท
aditsu

ฉันขาดอะไรบางอย่างเกี่ยวกับการอัพเดท 0.6.4 นี้หรือไม่? ฉันยังได้รับข้อความแสดงข้อผิดพลาดที่ทำเคล็ดลับเหล่านั้นเช่นUnhandled char after ':': :( ลิงก์ )
Runer112

2
@ Runer112 ใช้งานได้สำหรับฉัน ตรวจสอบว่าคุณโหลดซ้ำอย่างถูกต้อง (ไม่ใช่จากแคช) ทั้งนี้ขึ้นอยู่กับเบราว์เซอร์ของคุณ Ctrl + F5 ควรทำงาน
Martin Ender

@ MartinBüttnerมันเกิดจากการแคชโง่ ๆ ขอบคุณ
Runer112

7

ตัวดำเนินการ Vectorized สำหรับงานศิลปะ ASCII

สำหรับความท้าทายศิลปะ ASCII จำนวนมากจะมีประโยชน์ในการสร้างรูปแบบที่แตกต่างกันสองรูปแบบเพื่อซ้อนทับในภายหลัง ตัวดำเนินการ Vectorized จะมีประโยชน์มากในการบรรลุประเภทของการทับซ้อนที่หลากหลาย

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

  • .e<

    ตัวดำเนินการขั้นต่ำe<ใช้สำหรับคู่ของสตริงอักขระอาร์เรย์และจำนวนเต็ม มันจะปรากฏสองรายการจากสแต็กและกดล่างบน e กลับ

    เนื่องจากช่องว่างมีจุดรหัสที่ต่ำกว่าอักขระ ASCII ที่พิมพ์ได้อื่น ๆ ทั้งหมด.e<จึงสามารถใช้เพื่อ "ลบ" ชิ้นส่วนของรูปแบบที่สร้างขึ้น:

    "\/\/\/\/\/" "    " .e<
    
    e# This pushes "    \/\/\/".
    

    สำหรับตัวอย่างเต็มรูปแบบให้ดูคำตอบของฉันฉันต้องการรังผึ้ง

  • .e>

    ตัวดำเนินการสูงสุดe>ทำงานเป็นตัวดำเนินการขั้นต่ำโดยมีผลลัพธ์ตรงกันข้าม

    อีกครั้งเนื่องจากจุดรหัสต่ำของช่องว่าง.e>สามารถใช้เพื่อแทรกรูปแบบของอักขระที่พิมพ์ได้ในบล็อกของช่องว่าง:

    [[" " " " " " " "] [" " " " " " " "]][["+" "" "-" ""]["" "*" "" "/"]] ..e>
    
    e# This pushes [["+" " " "-" " "] [" " "*" " " "/"]].
    

    สำหรับตัวอย่างเต็มรูปแบบให้ดูคำตอบของฉันเจ็ดดิสเพลย์ Slash

  • .e&

    ตัวดำเนินการตรรกะและe&ผลักดันอาร์กิวเมนต์ด้านซ้ายถ้ามันเป็นเท็จและอาร์กิวเมนต์ที่ถูกต้องเป็นอย่างอื่น

    หากรูปแบบทั้งสองไม่มีองค์ประกอบที่ผิดพลาดสิ่งนี้สามารถใช้เพื่อกำหนดรูปแบบหนึ่งโดยไม่มีเงื่อนไขกับอีกรูปแบบหนึ่ง:

    "################" " * * * *" .e&
    
    e# This pushes " * * * *########".
    

    สำหรับตัวอย่างทั้งหมดดูคำตอบของฉันในการพิมพ์ธงชาติอเมริกัน! .

  • .e|

    ตัวดำเนินการเชิงตรรกะ OR e|สามารถใช้ได้ดังด้านบนพร้อมลำดับอาร์กิวเมนต์ที่กลับรายการ:

    " * * * *" "################" .e|
    
    e# This pushes " * * * *########".
    

6

ใช้&เพื่อตรวจสอบว่ารายการนั้นอยู่ในรายการหรือไม่

สำหรับ

1 [1 2 3] #W>
1 [1 2 3] #)

คุณสามารถใช้ได้

1 [1 2 3] &,
1 [1 2 3] &

แทนซึ่งจะส่งกลับ 0/1 และ facty / falsey ตามลำดับ


6

z และอาร์เรย์ที่ไม่ใช่สี่เหลี่ยม

ผู้ประกอบการซิปztransposes แถวและคอลัมน์ของสองมิติ1อาร์เรย์ซึ่งองค์ประกอบสามารถเป็นซ้ำได้

สำหรับอาร์เรย์ที่ไม่ใช่รูปสี่เหลี่ยมผืนผ้า - ซึ่งแตกต่างจากzipฟังก์ชั่นในตัวเช่น Python (ตัดแถวให้มีความยาวเท่ากัน) หรือ Ruby (รองแถวด้วยnil) - CJam แปลงคอลัมน์ของแถวเป็นแถวโดยไม่สนใจความยาวและ ช่องว่าง

ตัวอย่างเช่นการซิปอาร์เรย์

[
  [1]
  [2 4]
  [3 5 6]
]

เทียบเท่ากับการซิปอาร์เรย์

[
  [1 4 6]
  [2 5]
  [3]
]

หรืออาร์เรย์

[
  [1]
  [2 4 6]
  [3 5]
]

การกระทำทั้งสามอย่างผลักดัน

[
  [1 2 3]
  [4 5]
  [6]
]

บนสแต็ก

ในขณะที่นี่หมายความว่าzไม่ใช่การมีส่วนร่วม (ซึ่งจะมีประโยชน์ในบางโอกาส) แต่ก็มีแอปพลิเคชั่นบางอย่าง

ตัวอย่างเช่น:

  • เราสามารถจัดเรียงคอลัมน์ของอาร์เรย์ให้อยู่ด้านบน (เช่นเปลี่ยนอาร์เรย์แรกเป็นวินาที) โดยการซิปสองครั้ง:

    zz
    
  • การแก้ไขเล็กน้อยของวิธีการด้านบนสามารถใช้สำหรับปัญหาที่คล้ายกัน

    ตัวอย่างเช่นในการจัดแนวคอลัมน์ของอาร์เรย์ให้อยู่ด้านล่าง (เช่นเพื่อเปลี่ยนอาร์เรย์ที่สองเป็นอันดับแรก) เราสามารถซิปสองครั้งด้วยลำดับแถวที่กลับด้าน:

    W%zzW%
    
  • ด้วยอาร์เรย์ของสตริงเราสามารถคำนวณความยาวของสตริงที่ยาวที่สุดดังนี้:

    :,:e>
    

    อย่างไรก็ตามโดยการซิปและการคำนวณจำนวนแถวของผลลัพธ์เราสามารถบันทึกสามไบต์:

    z,
    

1 หาก "แถว" ของAใด ๆ ไม่สามารถทำซ้ำได้ให้zถือว่าพวกมันเป็น singletons ดังนั้นการซิปจะใช้กับอาร์เรย์ใดก็ได้


1
เพียงวิธีที่แตกต่างของการแสดงภาพในสิ่งเดียวกัน แต่สำหรับฉันพฤติกรรมนั้นมีเหตุผลมากกว่าถ้าฉันนึกภาพzการแปลงคอลัมน์เป็นแถวในขณะที่ค่าว่างถูกข้ามไป ในตัวอย่างคอลัมน์แรกในอินพุตคือ 1, 2, 3, คอลัมน์ที่สองคือ 4, 5 (ตำแหน่งว่างถูกข้าม) และคอลัมน์ที่สามคือ 6 เหล่านี้คือแถวของผลลัพธ์
Reto Koradi

@RetoKoradi นั่นเป็นวิธีที่ดีกว่ามากในการอธิบาย
Dennis

6

ข้อยกเว้น

ข้อยกเว้นทั้งหมดเป็นอันตรายใน CJam เนื่องจากการส่งออกไปยัง STDERR จะถูกละเว้นโดยค่าเริ่มต้นเราสามารถใช้สิ่งนี้เพื่อประโยชน์ของเรา

ตัวดำเนินการทั้งหมดใน CJam ทำงานโดยการ popping ศูนย์หรือองค์ประกอบเพิ่มเติมจากสแต็กดำเนินงานบางอย่างและผลักศูนย์หรือองค์ประกอบเพิ่มเติมบนสแต็ก มีข้อยกเว้นเกิดขึ้นในขณะที่ทำงานดังนั้นจึงยังคงปรากฏองค์ประกอบ แต่ไม่มีการส่งคืน

นี่คือกรณีการใช้งานไม่กี่:

  • การล้างสแต็กขนาดเล็ก

    หากต้องการล้างสแต็กที่มีสององค์ประกอบ@สามารถใช้งานได้ @พยายามที่จะปรากฏองค์ประกอบสามกอง แต่ล้มเหลวหลังจาก popping ที่สอง

    ตัวดำเนินการอื่นใดที่ปรากฏองค์ประกอบสามอย่างจะตอบสนองวัตถุประสงค์เดียวกัน

    เห็นในการกระทำที่นี่

  • การลบองค์ประกอบสองหรือสามองค์ประกอบออกจากสแต็ก

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

    หากต้องการแสดงองค์ประกอบสองรายการbทำงานหากหนึ่งในนั้นเป็นตัวละครหรือไม่มีองค์ประกอบใดเป็นจำนวนเต็ม

    หากต้องการแสดงองค์ประกอบสามรายการtทำงานหากไม่มีองค์ประกอบสองรายการที่อยู่ด้านล่างสุดจะทำซ้ำได้การทำซ้ำได้มากที่สุดด้านล่างว่างเปล่าหรือไม่มีรายการใดเลยที่เป็นจำนวนเต็ม

  • ออกจากการวนซ้ำ

    ในบางครั้งเราจำเป็นต้องออกจากลูปเมื่อจำนวนเต็มกลายเป็นศูนย์หรือสตริงสั้นเกินไป แทนที่จะทำการทดสอบเงื่อนไขเหล่านี้หากการดำเนินการที่เกี่ยวข้องล้มเหลวเป็นศูนย์สตริงว่างเปล่าหรือซิงเกิลตันเราสามารถปล่อยให้โปรแกรมดำเนินการตามธรรมชาติได้

    ตัวอย่างที่เกี่ยวข้องกับคณิตศาสตร์ให้ดูที่นี่

    ตัวอย่างที่เกี่ยวข้องกับสายให้ดูที่นี่

  • การดำเนินการตามเงื่อนไข

    หากไม่ควรเรียกใช้ซอร์สโค้ดสำหรับอินพุตบางประเภทบางครั้งเราสามารถใช้โอเปอเรเตอร์ที่ล้มเหลวของอินพุตนั้น

    ตัวอย่างเช่นiจะล้มเหลวสำหรับสตริงที่ไม่ได้ประเมินเป็นจำนวนเต็มและewจะล้มเหลวสำหรับสตริงที่มีความยาว 0 หรือ 1

    เห็นในการกระทำที่นี่


5

สูงสุด / นาทีจากอาร์เรย์

นี่คือหนึ่งสำหรับการเริ่ม!

เมื่อคุณต้องการค้นหาจำนวนสูงสุดหรือต่ำสุดจากอาเรย์วิธีที่ง่ายที่สุดและเล็กที่สุดคือการเรียงลำดับอาเรย์แล้วนำองค์ประกอบแรกหรือองค์ประกอบสุดท้ายออกมา

ดังนั้นถ้าอาร์เรย์อยู่ในตัวแปร A

A$W=

สูงสุดและ

A$0=

เป็นขั้นต่ำ

รับทั้งสองในเวลาเดียวกันก็เป็นไปได้

A$)\0=

สิ่งนี้อาจดูเหมือนชัดเจนหลังจากอ่าน แต่ความพยายามครั้งแรกของทุกคนมีแนวโน้มที่จะใช้e<หรือe>ผ่านการวนซ้ำผ่านอาร์เรย์ซึ่งจะไปเหมือน

A{e<}*

ซึ่งมีความยาว 2 ไบต์และยิ่งยาวขึ้นหากคุณต้องการทั้ง max และ min


แน่นอนถ้าคุณไม่ทราบส่วนที่เหลือของอาร์เรย์ที่เหลืออยู่ในสแต็คที่คุณสามารถใช้งานจริง(และ)แทนและ0= W=
Martin Ender

ขณะนี้มี:e<และ:e>
aditsu

@aditsu ถึงแม้ว่าพวกเขาจะไม่สั้นกว่าคำแนะนำด้านบน
เครื่องมือเพิ่มประสิทธิภาพ

5

ใช้การประทับเวลาสำหรับตัวเลขขนาดใหญ่

หากคุณต้องการเป็นจำนวนมาก แต่โดยพลการอย่างใดอย่างหนึ่งที่คุณมักจะจะใช้สัญกรณ์วิทยาศาสตร์เหมือนหรือยกของที่มีขนาดใหญ่ในตัวตัวแปรเพื่ออำนาจที่คล้ายกันเช่น9e9 KK#อย่างไรก็ตามหากคุณไม่สนใจว่าจำนวนจริงคืออะไรและไม่จำเป็นต้องเหมือนกันอย่างสม่ำเสมอ (เช่นขอบบนของหมายเลขสุ่ม) คุณสามารถทำได้สองไบต์โดยใช้

es

แทน. สิ่งนี้ให้เวลาประทับปัจจุบันเป็นมิลลิวินาทีและอยู่ในลำดับ 10 12


3
e9นอกจากนี้ยังทราบว่าถ้าคุณต้องการเป็นจำนวนมากโดยพลการขนาดใหญ่และต้องการยกเลิกการเป็นจำนวนบวกกันคุณสามารถใช้
jimmy23013

5

ตรวจสอบว่าสองสตริง / อาร์เรย์ไม่เท่ากัน

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

=!

ตรวจสอบความเท่าเทียมกันและกลับผลลัพธ์ อย่างไรก็ตามภายใต้เงื่อนไขบางประการที่คุณสามารถใช้ได้

#

เมื่อ#นำไปใช้กับสองอาร์เรย์จริง ๆ แล้วค้นหาอาร์เรย์ที่สองเป็น subarray ของแรก (และให้ดัชนีที่เริ่ม subarray) ดังนั้นหากทั้งสองอาร์เรย์มีความเหมือนกันจะพบ subarray ตั้งแต่เริ่มต้นและการให้0ซึ่งเป็นเท็จ แต่ถ้าไม่พบอาเรย์ที่สองมันจะให้-1อันที่จริง

เหตุผลที่เราต้องการเงื่อนไขเพิ่มเติมในสองอาร์เรย์นี้ก็คือสิ่งนี้ยังให้ค่าเท็จถ้าอาร์เรย์ที่สองเป็นคำนำหน้าที่ไม่น่าสนใจของแรกเช่น:

"abc""ab"#

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


5

c และจำนวนเต็ม 16 บิต

เพิ่ม (หรือลบ) ได้ลงนามจำนวนเต็ม 16 บิตที่มีการตัดที่เหมาะสมคุณสามารถใช้หรือ+65536%+2G#%

อย่างไรก็ตาม

+ci

สั้นกว่ามาก อักขระล้อมรอบที่65536ดังนั้นการเลือกไปที่ Character ( c) จากนั้นไปที่ Long ( i) จะมีเอฟเฟกต์คล้ายกัน65536%โดยมีข้อดีเพิ่มเติมที่ผลลัพธ์จะไม่เป็นลบ

เคล็ดลับเดียวกันสามารถใช้เพื่อผลักดัน65535 :

Wci

4

ชุดพาวเวอร์

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

[1 2 3 4 5]La\{1$f++}/

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

[1 2 3 4 5]1a\{1$f*+}/

4

ตรวจสอบว่ารายการในรายการเหมือนกันทั้งหมดหรือไม่

ฉันคิดว่านี่น่าพูดถึงเช่นกัน ใช้:

)-

ส่งคืนความจริงถ้าไม่เหมือนกันทั้งหมดหรือรายการว่างเปล่าถ้าเหมือนกันทั้งหมด ข้อผิดพลาดหากรายการว่างเปล่า

ในกรณีที่รายการที่สกัดอาจเป็นอาร์เรย์ (หรือสตริง) ตัวเอง:

)a-

ใช้!หรือ!!เพื่อรับค่าบูลีน ในกรณีที่ไอเท็มที่ดึงมาอาจเป็นอาเรย์และมีไอเท็มต่างกันมากที่สุดสองรายการและคุณต้องการให้มันเป็น 1 หากไม่เหมือนกันทั้งหมดนี่จะสั้นกว่า:

_|,(

4

0= สำหรับสตริง

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

อย่างไรก็ตามหากอาร์เรย์นั้นเป็นสตริงการส่งไปที่อักขระจะเพียงพอ

ตัวอย่าง

"xyz"c e# Pushes 'x.

ฉันไม่เห็นว่าทำไม CJam ไม่เพียงให้cแยกองค์ประกอบแรกของอาร์เรย์ใด ๆ ซึ่งจะมีประโยชน์และสอดคล้องกันมากกว่า
แยกผลไม้

4

การหมุนอาร์เรย์ (หรือสแต็ก) หนึ่งหน่วยทางด้านซ้าย

CJam มีซ้ายหมุนประกอบการm<ซึ่งโดยปกติคือสิ่งที่คุณควรใช้ในการหมุนอาร์เรย์ด้วยจำนวนหน่วยโดยพลการไปทางซ้าย

ในบางกรณีคุณสามารถใช้(+เพื่อเปลี่ยนและผนวก:

[1 2 3]       (+ e# Pushes [2 3 1].
[[1] [2] [3]] (+ e# Pushes [[2] [3] 1].

ตัวอย่างที่สองไม่ทำงานเนื่องจากองค์ประกอบแรกของอาร์เรย์ยังเป็นตัวทำซ้ำได้ดังนั้นการ+ต่อข้อมูลแทนการต่อท้าย

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

[1 2 3]       :\ e# Pushes 2 3 1.
[[1] [2] [3]] :\ e# Pushes [2] [3] [1].

ตราบใดที่คุณไม่มีการเปิด[เคล็ดลับนี้ยังสามารถใช้เพื่อหมุนสแต็กทั้งหมดเช่นเพื่อนำรายการสแต็กล่างสุดไปด้านบน:

]:\

3

พิมพ์รายการและล้างสแต็ก

ให้บอกว่าสแต็กของคุณมีรายการสตริง / หมายเลข / ฯลฯ ด้านบนและรายการพิเศษอื่น ๆ ด้านล่าง กล่าวคือ

123 "waste" ["a" "b" "rty" "print" "me" "please"]

ตอนนี้คุณมีความสนใจในการพิมพ์รายการสุดท้ายเท่านั้นดังนั้นคุณทำ

S*]W=

ซึ่งผลลัพธ์

a b rty print me please

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

นี่สามารถเล่นกอล์ฟต่อไปได้!

p];

นั่นสั้นกว่า 2 ไบต์ !

และถ้าคุณมีเพียง 1 รายการในกองอื่นนอกเหนือจากรายการมันจะยิ่งสั้นลง!

p;

ความงามของ pมันคือการลบไอเท็มยอดนิยมส่วนใหญ่ออกจากสแต็กทำให้เป็นสตริง (เพิ่มบรรทัดใหม่ในตอนท้าย) และพิมพ์ไปยัง STDOUT ทันทีโดยไม่ต้องรอโค้ดให้เสร็จ

ดังนั้นรหัสข้างต้นจะส่งออก

["a" "b" "rty" "print" "me" "please"]

ซึ่งเป็นตัวแทนที่แน่นอนของรายการเมื่อมันอยู่ในกอง!


3

ผลิตภัณฑ์คาร์ทีเซียนหรือชุดค่าผสมที่เป็นไปได้ทั้งหมดของสองชุดขึ้นไป

CJam มีเครื่องคิดเลขผลิตภัณฑ์แบบคาร์ทีเซียนm*ซึ่งใช้อาร์เรย์ / รายการสตริงสองอันดับแรกบนสแต็กและสร้างคู่ที่เป็นไปได้ทั้งหมดจากมัน ตัวอย่างเช่น

[1 2 3 4]"abc"m*

ใบไม้

[[1 'a] [1 'b] [1 'c] [2 'a] [2 'b] [2 'c] [3 'a] [3 'b] [3 'c] [4 'a] [4 'b] [4 'c]]

เป็นกอง

แต่ถ้าคุณต้องการชุดค่าผสมที่เป็นไปได้ทั้งหมดจากรายการ / สตริงมากกว่า 2 รายการ คุณใช้m*มันหลายครั้งเหรอ? ตัวอย่างเช่น

[1 2 3 4][5 6]"abc"m*m*

จะปล่อยให้ต่อไปนี้ในสแต็ค

[[1 [5 'a]] [1 [5 'b]] [1 [5 'c]] [1 [6 'a]] [1 [6 'b]] [1 [6 'c]] [2 [5 'a]] [2 [5 'b]] [2 [5 'c]] [2 [6 'a]] [2 [6 'b]] [2 [6 'c]] [3 [5 'a]] [3 [5 'b]] [3 [5 'c]] [3 [6 'a]] [3 [6 'b]] [3 [6 'c]] [4 [5 'a]] [4 [5 'b]] [4 [5 'c]] [4 [6 'a]] [4 [6 'b]] [4 [6 'c]]]

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

มีวิธีง่ายๆในการทำเช่นนั้น เพียงแค่ห่อทุกรายการที่คุณต้องการสำหรับผลิตภัณฑ์คาร์ทีเซียนของคุณในอาร์เรย์จับคู่สร้างผลิตภัณฑ์คาร์ทีเซียนแล้วแผ่ในแต่ละครั้ง:

[1 2 3 4][5 6]"abc"]{m*{(+}%}*

ใบนี้

[['a 5 1] ['b 5 1] ['c 5 1] ['a 6 1] ['b 6 1] ['c 6 1] ['a 5 2] ['b 5 2] ['c 5 2] ['a 6 2] ['b 6 2] ['c 6 2] ['a 5 3] ['b 5 3] ['c 5 3] ['a 6 3] ['b 6 3] ['c 6 3] ['a 5 4] ['b 5 4] ['c 5 4] ['a 6 4] ['b 6 4] ['c 6 4]]

บนสแต็ก

ต้องการรักษาลำดับหรือไม่ เพียงสลับก่อนเพิ่มรายการที่ดึงกลับไปยังอาร์เรย์ กล่าวคือ

{m*{(\+}%}*

ต้องการเรียงสับเปลี่ยน?

{m*{(+$}%_&}*

ต้องการเฉพาะองค์ประกอบที่ไม่ซ้ำกันในชุดค่าผสมหรือไม่

{m*{(+_&}%}*

นั่นคือคนทั้งหมด สำหรับตอนนี้


1
ตอนนี้คุณสามารถทำได้]:m*:e_ด้วยอาร์เรย์จำนวนเท่าใดก็ได้
aditsu

3

ปฏิบัติการบนสายอักขระ

บางครั้งหากคุณกำลังทำงานกับโครงสร้างข้อมูลที่ซับซ้อนในขณะที่รายการในนั้นง่ายการแปลงเป็นสตริงอาจช่วย

ตัวอย่างเช่นถ้าคุณต้องการรับไอเท็มแรกหรือรายการสุดท้ายในอาร์เรย์สองมิติของบิตและไม่สนใจประเภทที่ส่งคืนsA<บันทึกไบต์จาก0=A<หรือ:+A<หรือ

หรือถ้าคุณต้องการแก้ไขบิตในอินพุตคุณสามารถแก้ไขสตริงก่อนที่จะประเมิน

หรือถ้าคุณมีโครงสร้างนี้และต้องการแปลงเป็นรายการง่าย ๆ :

[[[[[[[[[1]2]3]4]5]6]7]8]9]

คุณสามารถทำได้หลายตัวละครด้วยวิธีอื่น:

[a{~)\}h;]W%

แต่มันจะสั้นกว่านี้ด้วยสตริง:

s:~

มันสั้นกว่าแม้ว่ามันอาจมีตัวเลขที่มีมากกว่าหนึ่งหลัก:

[`La`-~]

หรือ:

`']-~]

หากคุณไม่ต้องการอาร์เรย์อื่นที่มีอาร์เรย์ดังกล่าวจำนวนมาก


ขณะe_นี้มี
aditsu

@aditsu ดูคำตอบและความคิดเห็นนี้ บางครั้งsก็ยังทำงานได้ดีขึ้น
jimmy23013

แน่นอนว่าเมื่อคุณสามารถทำงานกับสตริงได้โดยตรงก็จะสั้นลง
aditsu

3

การใช้ NแทนLa

ในหลายกรณีคุณต้องการบางสิ่งบางอย่างที่เริ่มต้นไปยังอาร์เรย์ที่มีอาร์เรย์ที่ว่างเปล่าเป็นองค์ประกอบเท่านั้นซึ่ง Laดูเหมือนจะไม่จำเป็นอีก 1 ไบต์

ในหลายกรณีคุณต้องเพิ่มบรรทัดใหม่หลังจากแต่ละองค์ประกอบก่อนทำการพิมพ์ซึ่งอาจเป็นสิ่งที่ต้องการNoหรือN*หรือ

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

บางครั้งSก็ใช้งานได้หากคุณต้องการแยกเอาต์พุตด้วยช่องว่าง

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


2

แบ่งออกเป็นหนึ่งครั้งหรือมากกว่านั้น

สมมติว่าคุณมีสตริง "abbcdbbfghbdbb"และคุณต้องการแยกมันb

"abbcdbbfghbdbb"'b/

ใบนี้วางซ้อนกัน:

["a" "" "cd" "" "fgh" "d" "" ""]

สังเกตเห็นสตริงว่างเปล่า? นั่นเป็นเพราะทั้งสองbคนอยู่ด้วยกันและไม่มีอะไรอยู่ในนั้น ในบางครั้งคุณต้องการหลีกเลี่ยงสิ่งนี้ คุณสามารถทำได้โดย

"abbcdbbfghbdbb"'b/La-

หรือกรองสตริงว่าง

"abbcdbbfghbdbb"'b/{},

แต่นั่นคือ 3 ไบต์พิเศษ

ผู้ประกอบการเล็ก ๆ น้อย ๆ %ที่รู้จักกันน้อยลงสำหรับกรณีการใช้งานนี้โดยเฉพาะคือ นอกเหนือจากการทำ mod และ map และการแยกตามหมายเลข ( "abcd"2%= "ac") แล้ว%ยังสามารถแยกสตริง / อาร์เรย์ ดังนั้นสำหรับกรณีการใช้งานด้านบน:

"abbcdbbfghbdbb"'b%

จะออกไป

["a" "cd" "fgh" "d"]

บนสแต็ก

ขอบคุณสำหรับ @ user23013 ที่ชี้เรื่องนี้เป็นหนึ่งในคำตอบของฉันวันนี้


ฉันคิดว่าควรใช้ชื่อว่า "เรียนรู้ GolfScript" ซึ่งมีตัวอย่างที่ดีกว่าในเอกสารประกอบ
jimmy23013

@ user23013 แต่เราไม่เคยแน่ใจว่าสิ่งที่คล้ายกับ GS และสิ่งที่ไม่
เครื่องมือเพิ่มประสิทธิภาพ

2

ใช้การพับ / ลดขนาดเป็นมัดหน้า

เรามี:xชวเลขสำหรับ{x}%และหรือ{x}*(ขึ้นอยู่กับว่าxเป็นเอกภาพหรือไบนารี) {x}/แต่น่าเสียดายที่ไม่มีผู้ประกอบการมัดเทียบเท่ากับร่น แต่มักจะมากเมื่อเราทำ{x}/, xเป็นจริงผู้ประกอบการไบนารีที่ซ้ำ ๆ ปรับเปลี่ยนรายการที่โกหกใต้ในกอง หากเป็นเช่นนั้นและรายการที่กล่าวมานั้นไม่ใช่อาร์เรย์เราสามารถบันทึกไบต์ด้วยการใช้การพับ / ย่อเป็น foreach:

5 [1 2 3 4]{-}/  e# Gives -5
5 [1 2 3 4]+:-

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


2

พิมพ์และ println

CJam มีผู้ประกอบการ:print oใช้งานได้ แต่สแต็คกำลังพิมพ์ทันทีหลังจากประมวลผลรหัสทั้งหมด คุณสามารถหยุดมันได้หากคุณล้างสแต็กเมื่อสิ้นสุดโปรแกรม เพียงวางที่ส่วนท้าย:

];

หากต้องการพิมพ์คุณสามารถใช้oNoหรือp(ทำงานเป็น`oNo)


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