Mathematica,166137字节
l:={i,j};s=Sign;f[p_,q_,h_,w_]:=Grid@Table[(1-Max[s[p-l]s[q-l],0])Boole[Abs@Mean[s@Det@{p-l+#,p-q}&/@Tuples[.5{1,-1},2]]<.6],{i,h},{j,w}]
更具可读性的版本:
l := {i, j}; s = Sign;
f[p_, q_, h_, w_] :=
Grid@Table[(1 - Max[s[p - l] s[q - l], 0]) Boole[
Abs@Mean[
s@Det@{p - l + #, p - q} & /@
Tuples[.5 {1, -1}, 2]] < .6], {i, h}, {j, w}]
这定义了一个名为的函数f
。我相当自由地解释了输入和输出规范。该函数f
以格式输入f[{x0, y0}, {x1, y1}, height, width]
,并且网格从左上角开始为1索引。输出看起来像
该行显示为1
s,背景显示为0
s(此处显示f[{2, 6}, {4, 2}, 5, 7]
)。转弯的数学矩阵的任务1
S和0
s转换的字符串#
S和.
S在许多其他挑战已经golfed之前,所以我可以只使用一个标准的方法,但我不认为增加了什么有趣的事。
说明:
一般的想法是,如果线穿过某个像素,则该像素的四个角中的至少一个在该线上方,而至少一个在其下方。我们通过检查向量({x0,y0}
至)和({x0,y0}
至{x1,y1}
)之间的角度来检查拐角是在直线上方还是下方:如果该角度为正,则拐角位于上方;如果角度为负,则拐角位于下方。
如果我们有两个向量{a1,b1}
和{a2,b2}
,则可以通过找到矩阵行列式的符号来检查它们之间的夹角是正还是负{{a1,b1},{a2,b2}}
。(我的旧方法是使用复数算法,这太复杂了……嗯,很复杂。)
在代码中的工作方式如下:
{p-l+#,p-q}&/@Tuples[.5{1,-1},2]
会从四个矢量{x0,y0}
和像素的四个角(带l:={i,j}
,所述像素的坐标,前面所定义的),并且还之间的矢量{x0,y0}
和{x1,y1}
。
s@Det@...
查找直线和四个角之间的角度符号(使用s=Sign
)。这些将等于-1、0或1。
Abs@Mean[...]<.6
检查某些角度为正,某些角度为负。具有此属性的4个符号的均值的均值在-0.5到0.5(含)之间,因此我们将其与0.6进行比较,以使用<
代替来保存一个字节<=
。
仍然存在一个问题:此代码假定直线永远在两个方向上延伸。因此,我们需要通过乘以1-Max[s[p-l]s[q-l],0]
(通过反复试验得出)来裁剪线1
,该线位于线的端点定义的矩形之内和0
之外。
其余的代码组成了这些像素的网格。
(此外,这是更早的尝试,使用了完全不同的方法,为181个字节:)
Quiet@Grid@Table[(1-Max[Sign[{i,j}-#3]Sign[{i,j}-#4],0])Boole[#3==#4=={i,j}||2Abs@Tr[Cross@@Thread@{{i,j},#3,#4}]/Norm[d=#3-#4]<2^.5Cos@Abs[Pi/4-Mod[ArcTan@@d,Pi/2]]],{i,#},{j,#2}]&