改进工作 "Bulgarian Solitaire" J 动词
Improve a working "Bulgarian Solitaire" J verb
"Bulgarian Solitaire" 是一种数学好奇心。它是用一副 45 张(任何三角形数字都可以)未标记的牌来玩的。将它们放入随机大小的堆中。然后,要玩一轮,从每堆中取出一张牌,并用取出的牌创建一个新牌堆。重复此步骤最终得到配置 1 2 3 4 5 6 7 8 9
(对于 45 张牌),这显然是游戏的固定点,因此单人纸牌游戏结束。我想在J中模拟这个游戏。
经过几天的思考和对 J 动名词的一些期待已久的洞察,我想出了一个解决方案,我想听听一些意见。它以这个动词开头:
bsol =: ((#~ ~:&0) , #)@:(-&1)^:(<_)
给定一个正整数向量,其总和为三角形,这个动词 returns 一个 2 阶数组,显示产生的单人纸牌轮数。我也想出了这个动词来生成初始配置,但我对此不太满意:
t =: 45 & - @ (+/) NB. Would work with any triangular number
cards =: (]`(]@,>:@?&t@]))@.(0&<@t)^:_
给定一个由正整数组成的向量 y
,t
returns 45 的缺陷,即 45 - +/ y
的牌数未计入所代表的牌堆中由论据。使用 t
,动词 cards
向这样的向量 y
重复添加来自 >: i. t y
的整数,直到缺陷为 0。
显式扩展t
,我得到
cards =: (]`(]@,>:@?&(45 & - @ (+/))@]))@.(0&<@(45 & - @ (+/)))^:_
我觉得这不是很简短,而且括号可能过分了。但它确实有效,完整的解决方案现在看起来像这样:
bsol @ cards @ >: @ ? 44 NB. Choose the first pile randomly from >: i. 44
没有命名动词:
(((#~ ~:&0) , #)@:(-&1)^:(<_)) @: ((]`(]@,>:@?&(45 & - @ (+/))@]))@.(0&<@(45 & - @ (+/)))^:_)@>:@? 44
对J习语了解不多,我对此也有同感:不是很简短,肯定是多余的(这里用t
这样的地方动词会不会更好,因为它重复了,例如?),并且可能过度括号。我有什么机会改进这个程序?
您可以通过
改进 t
t =: 45 - +/
使用 46 - +/
会节省一些 >:
。
您可以用递归定义替换cards
:
cards =: }.`(($:@] , -) ?)@.(0&<)
现在,cards n
生成总和为 n
的初始配置。
在 bsol
中,如果删除 (-.
) 零并重新排列,则不需要 -&1
:
bsol =: (0 -.~ [: (, #) <:)^:(<_)
"Bulgarian Solitaire" 是一种数学好奇心。它是用一副 45 张(任何三角形数字都可以)未标记的牌来玩的。将它们放入随机大小的堆中。然后,要玩一轮,从每堆中取出一张牌,并用取出的牌创建一个新牌堆。重复此步骤最终得到配置 1 2 3 4 5 6 7 8 9
(对于 45 张牌),这显然是游戏的固定点,因此单人纸牌游戏结束。我想在J中模拟这个游戏。
经过几天的思考和对 J 动名词的一些期待已久的洞察,我想出了一个解决方案,我想听听一些意见。它以这个动词开头:
bsol =: ((#~ ~:&0) , #)@:(-&1)^:(<_)
给定一个正整数向量,其总和为三角形,这个动词 returns 一个 2 阶数组,显示产生的单人纸牌轮数。我也想出了这个动词来生成初始配置,但我对此不太满意:
t =: 45 & - @ (+/) NB. Would work with any triangular number
cards =: (]`(]@,>:@?&t@]))@.(0&<@t)^:_
给定一个由正整数组成的向量 y
,t
returns 45 的缺陷,即 45 - +/ y
的牌数未计入所代表的牌堆中由论据。使用 t
,动词 cards
向这样的向量 y
重复添加来自 >: i. t y
的整数,直到缺陷为 0。
显式扩展t
,我得到
cards =: (]`(]@,>:@?&(45 & - @ (+/))@]))@.(0&<@(45 & - @ (+/)))^:_
我觉得这不是很简短,而且括号可能过分了。但它确实有效,完整的解决方案现在看起来像这样:
bsol @ cards @ >: @ ? 44 NB. Choose the first pile randomly from >: i. 44
没有命名动词:
(((#~ ~:&0) , #)@:(-&1)^:(<_)) @: ((]`(]@,>:@?&(45 & - @ (+/))@]))@.(0&<@(45 & - @ (+/)))^:_)@>:@? 44
对J习语了解不多,我对此也有同感:不是很简短,肯定是多余的(这里用t
这样的地方动词会不会更好,因为它重复了,例如?),并且可能过度括号。我有什么机会改进这个程序?
您可以通过
改进t
t =: 45 - +/
使用 46 - +/
会节省一些 >:
。
您可以用递归定义替换cards
:
cards =: }.`(($:@] , -) ?)@.(0&<)
现在,cards n
生成总和为 n
的初始配置。
在 bsol
中,如果删除 (-.
) 零并重新排列,则不需要 -&1
:
bsol =: (0 -.~ [: (, #) <:)^:(<_)