คุณมีเคล็ดลับอะไรบ้างสำหรับการเล่นกอล์ฟใน Tcl? ฉันกำลังมองหาแนวคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะ Tcl (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คุณมีเคล็ดลับอะไรบ้างสำหรับการเล่นกอล์ฟใน Tcl? ฉันกำลังมองหาแนวคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะ Tcl (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คำตอบ:
ในคำตอบของฉัน/codegolf//a/107557/29325ฉันสามารถสาธิต:
มักset j 0;while \$j<$n;{...;incr j}จะสั้นกว่าที่เทียบเท่ากันfor {set j 0} {$j<$n} {incr j} {...}
เมื่อตัวแปรลูปเริ่มต้นที่ 1 เราสามารถทำการเพิ่มขึ้นเป็นส่วนหนึ่งของwhileเงื่อนไขการทดสอบหลีกเลี่ยงการเขียนก่อนset i 1โดยไม่จำเป็น: while {[incr i]<=$n} {...}แทนset i 1;while \$i<=$n;{...;incr i}
ความสนใจ : หนึ่งสามารถทำได้ 2. ในกรณีของการวนรอบนอก! ฉันไม่สามารถใช้มันกับjตัวแปรของฉันเพราะมันจะต้องถูกรีเซ็ตเป็น 1 ในด้านนอกของวงในของตัวเอง! และincr jจะได้รับค่าที่ตั้งไว้ในขั้นตอนสุดท้ายของลูปด้านในแทนที่จะจับตัวแปรที่ไม่ได้กำหนดjเพื่อคาดเดา0และเพิ่มมันเป็น1!
บางครั้งมันก็คุ้มค่าที่จะใช้โดยtime {script} nที่nมีจำนวนการวนซ้ำมากกว่าปกติwhileหรือforวนซ้ำ แม้ว่าtimeจุดประสงค์ของมันจะไม่วนซ้ำ แต่ผลที่ได้ก็ยังเหมือนเดิม
ฉันเพิ่งเปลี่ยนแปลงคำตอบของตัวเองตามทิศทางนี้
UPDATE:ฉันได้ค้นพบเพียงแค่เรื่องง่ายที่จะตกอยู่อันตราย: คุณไม่สามารถเปลี่ยนforหรือwhileโดยtimeบล็อกถ้ามันมีหรือbreakcontinue
ใช้เปลือกโต้ตอบ สิ่งนี้ช่วยให้คุณสามารถย่อชื่อคำสั่งตราบเท่าที่มีเพียง 1 คำสั่งเริ่มต้นด้วยตัวอักษรที่เหลือ
ตัวอย่าง:
gets -> gelassign -> lasexpr -> expputs -> puและโซลูชั่นแบบอินเทอร์แอคทีฟฟรี: P
พื้นหลัง :
เมื่อtclshทำงานกับขั้วเป็นอุปกรณ์ป้อนจะกำหนดตัวแปรเพื่อtcl_interactive 1สาเหตุนี้unknown(โพรซีเดอร์เริ่มต้นที่จะถูกเรียกหากไม่พบคำสั่ง) เพื่อค้นหาคำสั่งที่ขึ้นต้นด้วยชื่อนั้น
ข้อเสีย: มันจะพิมพ์ผลลัพธ์ของทุกบรรทัดใช้;แทนการขึ้นบรรทัดใหม่
โอ๋และมันอาจจะเรียกคำสั่งภายนอกเช่นซึ่งเป็นตัวย่อที่ดีของwwhile
คำสั่งย่อยและตัวเลือกสามารถ (โดยปกติ) เป็นตัวย่อ สิ่งนี้สามารถประหยัดได้ไม่มากนัก แต่คุณต้องทดสอบเพราะไม่ใช่ทุกสิ่งที่สามารถทำให้สั้นลงได้ ( regsubตัวอย่างเช่นตัวเลือกไม่สามารถทำได้)
จากนั้นคุณสามารถใช้สิ่งนี้กับความมหัศจรรย์ของnamespaceการทำสิ่งชั่วร้ายอย่างแท้จริง พิจารณาสิ่งนี้:
namespace exp *;namespace en cr -c ?
หลังจากนั้น?ตอนนี้เป็นคำสั่งที่มีมนต์ขลังที่ช่วยให้คุณย่อ Tcl คำสั่งใด ๆ ทั่วโลกและโดยไม่ต้องมีความไม่แน่นอนที่น่ารังเกียจของ messing unknownรอบด้วย
ฉันใช้ Tcl 8.0.5 แต่ฉันเชื่อว่าสิ่งต่อไปนี้สามารถใช้กับเวอร์ชันล่าสุดทั้งหมด
ใช้renameเพื่อเปลี่ยนชื่อrename:
rename rename &
&สามารถระบุใด ๆ &แค่ทำให้ฉันนึกถึง "การอ้างอิง" ในภาษาซี
ใช้การเปลี่ยนชื่อrenameเพื่อเปลี่ยนชื่อset:
& set =
อีกครั้ง=สามารถเป็นตัวระบุใด ๆ ; =เป็นเรื่องง่ายสำหรับฉัน
ตอนนี้เปลี่ยนชื่อคำสั่งอื่น ๆ ที่มีมูลค่าการเปลี่ยนชื่อเช่น
& regsub R
& string S
& while W
คำสั่งที่มีมูลค่าการเปลี่ยนชื่อถ้าได้รับความยาวnและเกิดขึ้นk , k (n-1) - (n + 4)> 0 แก้สำหรับkk > (n+4)/(n-1)สูตรจะกลายเป็น นี่คือตารางอ้างอิงที่ทำให้ง่าย:
length of minimum example(s)
command occurrences
------------------------------------------------
2 6 if (consider renaming to "?")
3 4 for, set (consider renaming to "=")
4 3 eval, expr, incr (consider renaming to "+"), info, join, proc, puts, scan
5 3 break, catch, lsort, split, subst, trace, unset, while
6 3 format, lindex, lrange, regexp, regsub, rename, return, string, switch
7 2 foreach, lappend, linsert, llength, lsearch, unknown
. 2 lreplace
. 2 continue
. 2
ถัดไปคอมแพคย่อยที่ใช้บ่อยเช่น
= I index
= L length
เพื่อให้คุณสามารถทำสิ่งต่าง ๆ เช่น
S $I $x 7
S $L $x
บางเรื่องที่เห็นได้ชัด:
lappend สามารถกำหนดองค์ประกอบแรกของรายการหากยังไม่มี (ไม่จำเป็นต้องเริ่มต้น)array, เช่น set doesNotExist(7) 43"a b c") [list a b c]แทนfoo${a}barคุณสามารถสอดแทรกในสตริงชอบโดย:two\ words "two words"(จำไว้โดยทั่วไปว่าสำหรับสตริงที่ต่อเนื่องกันโดยไม่มีช่องว่างสามารถใส่เครื่องหมายคำพูดคู่ได้!)fors เป็นwhiles เพื่อบันทึกอักขระหนึ่งหรือสองตัวได้ตลอดเวลาเนื่องจาก a whileสามารถตรวจสอบและเพิ่มได้พร้อมกันในขณะที่forใช้บล็อกแยกต่างหากสำหรับโปรแกรมขนาดใหญ่ต่อไปนี้เป็นเคล็ดลับที่ฉันคิด แต่ยังไม่ได้ใช้:
proc unknown {c args} {eval [info commands $c*] $args}
สิ่งนี้เลียนแบบคำสั่งแบบโต้ตอบ! มีค่าใช้จ่าย 54 ตัวอักษร แต่ตอนนี้คุณสามารถใช้jสำหรับjoin, spสำหรับsplit, stสำหรับstring, wสำหรับwhile, และอื่น ๆ
unknownเส้นทาง: ดูที่นี่และที่นี่
ในฐานะที่ได้มีการกล่าวบนถ้าหน้าคู่มือ , elseเป็นนัยเกี่ยวกับการifสร้างบล็อก ดังนั้นคืออะไร
if ... {} else {}
สามารถกลายเป็น
if ... {} {}
อย่างที่คุณเห็นในคำตอบของฉัน
อาจจะควรรวมอยู่ในคำตอบอื่น แต่ที่นี่มันไป:
เมื่อ a procมีเพียงหนึ่งพารามิเตอร์มันสามารถเขียนเป็น
proc p a {DO THINGS}
แทน
proc p {a} {DO THINGS}
เช่นเดียวกับพารามิเตอร์สองตัวที่procใช้แบ็กสแลช มันสามารถเขียนเป็น
proc p a\ b {DO THINGS}
แทน
proc p {a b} {DO THINGS}
สำหรับพารามิเตอร์จำนวนที่สูง{}กว่าการเรนเดอร์โค้ดที่สั้นกว่า
บางครั้งมันก็คุ้มค่าที่จะแทนที่ทั้งสองsetประโยคเพื่อเชื่อมโยงสตริงด้วยlappendคำสั่งเดียวเท่านั้น ในการก่อสร้างเช่นเดียวสามารถทดแทน
set s ""
loop {
# ...
set s $s\X
}
โดย
loop {
# ...
append s X
}
appendคำสั่งมีincrพฤติกรรมชอบซึ่งเริ่มต้นตัวแปรยังไม่ได้กำหนดไว้
ดูแลเพื่อไม่ให้ผิดพลาดappendโดยlappend
หากคุณกำลังจัดการรายการที่มีการดำเนินการที่ syntactically interleaving ระหว่างแต่ละองค์ประกอบบางครั้งคุณสามารถjoinองค์ประกอบที่จะทำการดำเนินการเฉพาะแทนการข้ามมัน
ใน/codegolf//a/127042/29325มีตัวอย่าง:
puts \n[expr [join [split [read stdin]] +]]
มันread stdinจะช่วยให้แยกแล้วจะให้รายการ23 214 52 หลังจากนั้นจะกลับสตริง ในที่สุดก็ทำงานของข้อสรุป{23 214 52}[join {23 214 52} +]23+214+52expr 23+214+52
splitในกรณีนี้คุณสามารถละเว้น
หากคุณมีรหัสที่มีขนาดใหญ่ก็เป็นไปได้ที่จะหลีกเลี่ยงการใช้งานหลายexprใช้namespace pat tcl::mathopที่จุดเริ่มต้น มันมีการดำเนินการคำนำหน้าไวยากรณ์เป็น Tcl fonction ปกติ ตัวอย่างเช่น:
namespace pat tcl::mathop
set sum [+ 1 2 3]
set prod [* {*}{1 2 3 4}]
puts $sum\ $prod
เมื่อคุณมีตัวแปรหลายตัวที่อยู่setในบรรทัดถัดมาคุณสามารถใช้หนึ่งตัวlassignแทนที่จะใช้หลายsetคำสั่งเพื่อให้ได้ผลเหมือนกัน
ตัวอย่างหนึ่งคือคำตอบของฉันเอง/codegolf//a/105789/29325
ในการตัดสินใจเพียงแค่ต้องการน้ำหนักจำนวนตัวแปร (สมมติว่ามีตัวแปรตัวอักษร 1 ตัวตามที่คาดไว้เมื่อเล่นกอล์ฟ):
<5 setคือนักกอล์ฟ
= 5 setและlassignสร้างจำนวนไบต์เดียวกัน
> 5 lassignคือนักกอล์ฟ
info script {};set tcl_interactive 1