您在Tcl打高尔夫球有哪些一般秘诀?我正在寻找可以应用于编码高尔夫问题的想法,这些想法至少在某种程度上特定于Tcl(例如,“删除评论”不是答案)。请为每个答案发布一个提示。
您在Tcl打高尔夫球有哪些一般秘诀?我正在寻找可以应用于编码高尔夫问题的想法,这些想法至少在某种程度上特定于Tcl(例如,“删除评论”不是答案)。请为每个答案发布一个提示。
Answers:
在我的答案上 /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
!
使用交互式外壳。只要只有1个命令以其余字母开头,就可以缩写命令名称。
例:
gets
-> ge
lassign
-> las
expr
-> exp
puts
-> pu
交互式解决方案是免费的:P
背景:
当tclsh
使用终端作为输入设备运行时,它将变量设置tcl_interactive
为1
。这将导致unknown
(如果找不到命令,则将调用默认过程)搜索以该名称开头的命令。
缺点:它将打印每行的结果,使用;
而不是换行符。
哦,它可能会调用外部命令,例如w
,这是的很好的缩写while
。
我正在使用Tcl 8.0.5,但我相信以下内容适用于所有最新版本。
使用rename
重命名rename
:
rename rename &
的 &
可以是任何标识符; &
只是让我想起了C语言中的“引用”。
使用rename
重命名来重命名set
:
& set =
同样, =
可以是任何标识符;=
对我来说只是直觉
现在,重命名其他值得重命名的命令, 例如
& regsub R
& string S
& while W
如果给定命令的长度n和出现k,k(n-1)-(n + 4)> 0,则值得重命名该命令。求解k,公式变为k > (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
可以同时检查和递增,而a for
使用单独的块。对于大型程序,这是我想到但尚未应用的技巧:
proc unknown {c args} {eval [info commands $c*] $args}
这模拟了交互式命令的缩写!它的成本54个字符,但现在你可以使用j
的join
,sp
对split
,st
对string
,w
对while
,等等。
如果您要使用一个在语法上交错在每个元素之间的操作来处理列表,则有时您可以让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功能。例如:
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