您在朱莉娅打高尔夫球有哪些一般提示?我正在寻找可以应用于编码高尔夫球问题的想法,这些想法至少在某种程度上是特定于Julia的(例如,“删除评论”不是答案)。
您在朱莉娅打高尔夫球有哪些一般提示?我正在寻找可以应用于编码高尔夫球问题的想法,这些想法至少在某种程度上是特定于Julia的(例如,“删除评论”不是答案)。
Answers:
注意:以下内容可能包含一些过时的技巧,因为Julia在结构上还不太稳定。
一些保存一些字符的技巧
\ =div
,然后键入即可a\b
代替div(a,b)
。请注意空格-这是避免将其解析为“ \ =”运算符所必需的。另请注意,如果在REPL提示级别过载,请使用(\)=Base.(\)
或\ =Base. \
重置它。注意:一些功能已预先定义了现有的UTF-8运算符,例如÷
for div
,如Alex A所指出。a>0?"Hi":""
,使用"Hi"^(a>0)
,保存一个字节,或者一个布尔值,使用"Hi"^a
保存3个字节。a=split("Hi there"," ")
,你可能能够避免a[1]
和a[2]
利用a,b=split("Hi there"," ")
,它可以作为引用a
和b
,节省了每次使用三个字节,在短短两年多的字符在分配成本。显然,如果可以使用向量运算,则不要这样做。[]
-用于数组访问Array的第一个元素,表达式A[]
等效于A[1]
。请注意,如果您想获取第一个字符,则此方法不适用于String或Tuples。==[]
对数组和==()
元组使用;同样,对于负数,请使用!=[]
和!=()
。对于字符串,请将其==""
用于空值,但将其>""
用于非空值,因为按字母顺序,“”在任何其他字符串之前。x<=1&&"Hi"
可以写成x>1||"Hi"
,以保存字符(只要返回布尔值并不重要)。in('^',s)
而不是contains(s,"^")
。如果可以使用其他字符,则可以使用节省更多'^'∈s
,但请注意,∈
UTF-8 中为3个字节。minimum(x)
或maximum(x)
,使用min(x...)
或max(x...)
来从代码中删除一个字符x
。另外,如果您知道的所有元素x
都是非负数,请使用minabs(x)
或maxabs(x)
r"(?m)match^ this"
,键入r"match^ this"m
,并保存三个字符。reverse(x)
比长度长一字节,flipud(x)
并且将执行相同的操作,因此后者更好。{[1,2]}
,不是{1,2}
)-对于Julia 0.4,则需要Any[[1,2]]
。end
在数组索引中使用时,它会自动转换为数组/字符串的长度。因此,不要k=length(A)
使用A[k=end]
来保存3个字符。请注意,如果您想立即使用k,这可能没有好处。这在多维情况下也适用- A[k=end,l=end]
将获得- 的每个维度的大小,A
但是(k,l)=size(A)
在这种情况下将缩短一个字节,因此仅当您要立即访问最后一个元素时才使用它。A[k=1:end]
,在这种情况下,k
该迭代器将保留匹配的迭代器1:length(A)
。当您想同时使用数组A
时,这可能会很有用。collect(A)
使用use [A...]
,它会做同样的事情并节省4个字节。"$(s[i])"
或dec(s[i])
用于表达式或多字符变量,以及"$i"
用于单字符变量。?:
替代的&&
或||
有条件的任务 -那是,如果你想只在某些条件下执行任务,你可以通过编写保存一个字节cond?A=B:1
,而不是cond&&(A=B)
,或cond?1:A=B
不是cond||(A=B)
。请注意1
,此处是一个虚拟值。union
或∪
代替unique
- union(s)
将执行与相同的操作unique(s)
,并在该过程中保存一个字节。如果可以使用非ASCII字符,∪(s)
则将执行相同的操作,并且∪
仅花费3个字节,而不是中的5个字节union
。split("Hi there")
因为pattern参数默认为空格。
重新定义运算符可以在括号和逗号中节省很多字节。
举一个简单的例子,比较斐波那契数列的以下递归实现:
F(n)=n>1?F(n-1)+F(n-2):n # 24 bytes
!n=n>1?!~-n+!(n-2):n # 20 bytes
!n=n>1?!~-n+!~-~-n:n # 20 bytes
重新定义的运算符保留其初始优先级。
请注意,我们不能简单地换出!
赞成的~
,因为~
已经为整数定义,而!
只对布尔定义。
即使没有递归,重新定义运算符也比定义二进制函数要短。比较简单除数测试的以下定义。
f(x,y)=x==0?y==0:y%x==0 # 23 bytes
(x,y)->x==0?y==0:y%x==0 # 23 bytes
x->y->x==0?y==0:y%x==0 # 22 bytes
x\y=x==0?y==0:y%x==0 # 20 bytes
下面说明了如何重新定义二进制运算符以计算Ackermann函数:
A(m,n)=m>0?A(m-1,n<1||A(m,n-1)):n+1 # 35 bytes
^ =(m,n)->m>0?(m-1)^(n<1||m^~-n):n+1 # 36 bytes
| =(m,n)->m>0?m-1|(n<1||m|~-n):n+1 # 34 bytes
m\n=m>0?~-m\(n<1||m\~-n):n+1 # 28 bytes
注意,这^
比使用常规标识符更长,因为其优先级太高。
正如先前所说
m|n=m>0?m-1|(n<1||m|~-n):n+1 # 28 bytes
对于整数参数将不起作用,因为|
在这种情况下已经定义了。整数的定义可以用
m::Int|n::Int=m>0?m-1|(n<1||m|~-n):n+1 # 38 bytes
但这太长了。但是,如果我们将float作为左参数传递而将整数作为右参数传递,则它确实起作用。
不要轻易被factor(n)所吸引诱人的库函数factor(n)
具有致命缺陷:它以无序Dict
类型返回整数的因式分解。因此,要从中获取所需的数据,将需要付出昂贵的代价collect(keys())
,collect(values())
并且可能还需要a cat
和a sort
。在许多情况下,按审判分庭考虑可能更便宜。伤心,但真实。
使用映射 map
是循环的一种很好的选择。请注意和之间的区别,map
并map!
在可能的情况下利用后者的就地功能。
使用mapreduce mapreduce
可以进一步扩展map的功能,并且可以节省大量字节。
匿名功能很棒!..尤其是传递给上述map
功能时。
累积数组函数 cumprod
,cumsum
中,美味cummin
和其它类似命名的功能使沿着n维阵列的规定尺寸的累积操作。(或* un *指定数组是否为1-d)
任何的简称当您要选择多维数组(或Dict)的所有特定维时,例如A[Any,2]
,可以使用以下命令保存字节A[:,2]
使用单行符号表示功能function f(x) begin ... end
通常,您可以简化为f(x)=(...)
使用三元运算符对于单表达式If-Then-Else构造,它可以是一个空间节省程序。注意事项:尽管在某些其他语言中可能会出现,但您不能忽略Julia中冒号之后的部分。另外,运算符在Julia中是表达式级的,因此您不能将其用于有条件地执行整个代码块。
if x<10 then true else false end
与
x<10?true:false
在其他语言中也可以这样做,但是通常比直接方法更长。但是,Julia重新定义其一元和二进制运算符的能力使其颇具挑战性。
例如,要生成从1到10的自然数的加,减,乘和除表,可以使用
[x|y for x=1:10,y=1:10,| =(+,-,*,÷)]
该重新定义的二进制运算符|
为+
,-
,*
和÷
,然后计算x|y
每个操作和x
和y
在所期望的范围。
一元运算符也适用。例如,要计算复数1 + 2i,3-4i,-5 + 6i和-7-8i,它们的负数,它们的复共轭和它们的乘法逆,可以使用
[~x for~=(+,-,conj,inv),x=(1+2im,3-4im,-5+6im,-7-8im)]
其中重新定义了一元运算符~
是+
,-
,conj
和inv
,然后计算~x
所有所需复数。
关键字有时可以立即跟随常量,而无需使用空格或分号。例如:
n->(for i=1:n n-=1end;n)
请注意,1
和之间没有空格end
。这对于end
在封闭括号之后发生也是如此)end
。
使用÷
而不是div()
或重载运算符执行整数除法。请注意,÷
在UTF-8中值得2个字节。
使用vec()
或A[:]
(对于某些数组A
)而不是reshape()
尽可能使用。
当挑战规则允许时,创建函数而不是完整程序。定义一个接受输入的函数比通过从stdin读取来定义变量要短。例如:
n->(n^2-1)
n=read(STDIN,Int);n^2-1
变量可以在函数的参数内递增。例如,以下是我对“ 查找下一个1-稀疏二进制数”挑战的答案:
n->(while contains(bin(n+=1),"11")end;n)
这比n
在循环内部递增要短。