คุณมีเคล็ดลับอะไรบ้างสำหรับการเล่นกอล์ฟใน 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
บล็อกถ้ามันมีหรือbreak
continue
ใช้เปลือกโต้ตอบ สิ่งนี้ช่วยให้คุณสามารถย่อชื่อคำสั่งตราบเท่าที่มีเพียง 1 คำสั่งเริ่มต้นด้วยตัวอักษรที่เหลือ
ตัวอย่าง:
gets
-> ge
lassign
-> las
expr
-> exp
puts
-> pu
และโซลูชั่นแบบอินเทอร์แอคทีฟฟรี: P
พื้นหลัง :
เมื่อtclsh
ทำงานกับขั้วเป็นอุปกรณ์ป้อนจะกำหนดตัวแปรเพื่อtcl_interactive
1
สาเหตุนี้unknown
(โพรซีเดอร์เริ่มต้นที่จะถูกเรียกหากไม่พบคำสั่ง) เพื่อค้นหาคำสั่งที่ขึ้นต้นด้วยชื่อนั้น
ข้อเสีย: มันจะพิมพ์ผลลัพธ์ของทุกบรรทัดใช้;
แทนการขึ้นบรรทัดใหม่
โอ๋และมันอาจจะเรียกคำสั่งภายนอกเช่นซึ่งเป็นตัวย่อที่ดีของw
while
คำสั่งย่อยและตัวเลือกสามารถ (โดยปกติ) เป็นตัวย่อ สิ่งนี้สามารถประหยัดได้ไม่มากนัก แต่คุณต้องทดสอบเพราะไม่ใช่ทุกสิ่งที่สามารถทำให้สั้นลงได้ ( 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"
(จำไว้โดยทั่วไปว่าสำหรับสตริงที่ต่อเนื่องกันโดยไม่มีช่องว่างสามารถใส่เครื่องหมายคำพูดคู่ได้!)for
s เป็นwhile
s เพื่อบันทึกอักขระหนึ่งหรือสองตัวได้ตลอดเวลาเนื่องจาก 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+52
expr 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