N行动者:我可以达到多少个无限局面?


48

单招

棋盘是无限的二维方格,就像无限的棋盘一样。值为N的零件(一个N移动器)可以移动到与N的平方根正好等于其当前平方的距离(欧几里德测得的中心到中心)的距离的任何平方。

例如:

  • 1移动器可以移动到水平或垂直相邻的任何正方形
  • 2移动器可以移动到对角线相邻的任何正方形
  • 五人棋棋子骑士一样的动作

请注意,并非所有的N型移动器都可以移动。3块移动器永远不会离开其当前正方形,因为板上的正方形都不与当前正方形的根3完全相同。

多招

如果允许其反复移动,某些碎片可以到达板上的任何正方形。例如,1移动器和5移动器都可以做到这一点。2移动器只能对角移动,并且只能达到正方形的一半。一块不能移动的棋子(例如3步移动棋子)不能到达任何方格(如果不发生移动,则起始方格不算作“到达”)

1人 2人 3人 4人 5人 8人 9人 10人 20人 25人 40人 64人 65人 68人

图像显示可以到达的正方形。有关悬停的更多详细信息。点击查看大图。

  • 1步或以上移动可达到的正方形用黑色标记
  • 用红色方块显示正好可以移动1的方格
    (3移动器除外,该方格不能移动)

给定的N移动者可以达到董事会的哪个比例?

输入项

  • 正整数N

输出量

  • N移动者可以达到的董事会比例
  • 这是从0到1(包括两端)的数字
  • 对于此挑战,允许以最低的分数(例如1/4)输出分数

因此对于input 101/20.5都是可接受的输出。作为单独的分子和分母的输出也可以接受,包括不支持浮点数和分数的语言。例如,1 2[1, 2]

对于整数输出(0和1),以下任何格式都是可接受的:

  • 对于0: ,00.0,,0/10 1[0, 1]
  • 为1: ,11.0,,1/11 1[1, 1]

计分

这是代码高尔夫。分数是代码的长度(以字节为单位)。对于每种语言,以最短的代码为准。

测试用例

格式 input : output as fraction : output as decimal

  1 : 1     : 1
  2 : 1/2   : 0.5
  3 : 0     : 0
  4 : 1/4   : 0.25
  5 : 1     : 1
  6 : 0     : 0
  7 : 0     : 0
  8 : 1/8   : 0.125
  9 : 1/9   : 0.1111111111111111111111111111
 10 : 1/2   : 0.5
 13 : 1     : 1
 16 : 1/16  : 0.0625
 18 : 1/18  : 0.05555555555555555555555555556
 20 : 1/4   : 0.25
 25 : 1     : 1
 26 : 1/2   : 0.5
 64 : 1/64  : 0.015625
 65 : 1     : 1
 72 : 1/72  : 0.01388888888888888888888888889
 73 : 1     : 1
 74 : 1/2   : 0.5
 80 : 1/16  : 0.0625
 81 : 1/81  : 0.01234567901234567901234567901
 82 : 1/2   : 0.5
144 : 1/144 : 0.006944444444444444444444444444
145 : 1     : 1
146 : 1/2   : 0.5
148 : 1/4   : 0.25
153 : 1/9   : 0.1111111111111111111111111111
160 : 1/32  : 0.03125
161 : 0     : 0
162 : 1/162 : 0.006172839506172839506172839506
163 : 0     : 0
164 : 1/4   : 0.25
241 : 1     : 1
242 : 1/242 : 0.004132231404958677685950413223
244 : 1/4   : 0.25
245 : 1/49  : 0.02040816326530612244897959184
260 : 1/4   : 0.25
261 : 1/9   : 0.1111111111111111111111111111
288 : 1/288 : 0.003472222222222222222222222222
290 : 1/2   : 0.5
292 : 1/4   : 0.25
293 : 1     : 1
324 : 1/324 : 0.003086419753086419753086419753
325 : 1     : 1
326 : 0     : 0
360 : 1/72  : 0.01388888888888888888888888889
361 : 1/361 : 0.002770083102493074792243767313
362 : 1/2   : 0.5
369 : 1/9   : 0.1111111111111111111111111111
370 : 1/2   : 0.5
449 : 1     : 1
450 : 1/18  : 0.05555555555555555555555555556
488 : 1/8   : 0.125
489 : 0     : 0
490 : 1/98  : 0.01020408163265306122448979592
520 : 1/8   : 0.125
521 : 1     : 1
522 : 1/18  : 0.05555555555555555555555555556
544 : 1/32  : 0.03125
548 : 1/4   : 0.25
549 : 1/9   : 0.1111111111111111111111111111
584 : 1/8   : 0.125
585 : 1/9   : 0.1111111111111111111111111111
586 : 1/2   : 0.5
592 : 1/16  : 0.0625
593 : 1     : 1
596 : 1/4   : 0.25
605 : 1/121 : 0.008264462809917355371900826446
610 : 1/2   : 0.5
611 : 0     : 0
612 : 1/36  : 0.02777777777777777777777777778
613 : 1     : 1
624 : 0     : 0
625 : 1     : 1

10
我张贴在Math.SE这样一个问题:math.stackexchange.com/questions/3108324/...
infmagic2047

有趣的猜想!
trichoplax

1
“一块不能移动的物体,例如3步移动器,不能到达任何正方形”。有趣的是,即使您计算起始正方形,由于木板是无限的,它仍然会按比例收敛到0。
Beefster

@Beefster好点。我采用了这种方法,可以轻松找到极限,而不必一直到无穷远……
trichoplax

2
@ infmagic2047的有关素数分解方法的math.se问题现在有了完整的证明
与Orjan约翰森

Answers:


19

的JavaScript(Node.js的)144个 138 125 74 73 70字节

f=(x,n=2,c=0)=>x%n?x-!c?f(x,n+1)/(n%4>2?n/=~c&1:n%4)**c:1:f(x/n,n,c+1)

在线尝试!

-4字节,谢谢@Arnauld!

原始方法,125字节

a=>(F=(x,n=2)=>n*n>x?[x,0]:x%n?F(x,n+1):[n,...F(x/n,n)])(a).map(y=>r-y?(z*=[,1,.5,p%2?0:1/r][r%4]**p,r=y,p=1):p++,z=r=p=1)&&z

在线尝试!

受到3Blue1Brown 在主要规律中隐藏的视频Pi的启发。

对于数字分解中的每个素数因子,计算:pnf(pn)

  • 如果为奇数并且 -。因为没有地方可以去。np3 (mod 4)f(pn)=0
  • 如果为偶数且 -。np3 (mod 4)f(pn)=1pn
  • 如果 -。p=2f(2n)=12n
  • 如果 -。p1 (mod 4)f(pn)=1

将所有这些函数值相乘,就得到了。

更新资料

由于Math.SE的贡献者的努力,该算法现在得到了证明的支持


视频是否包含证明?我已经尝试证明这个结果了几个小时,但我无法弄清楚。
infmagic2047

1
@ infmagic2047并非如此,但是它提供了一种方法来计算圆上的点数。当介绍n移动器的运行方式时,这很有用。ñ
Shieru Asakoto

3
@ infmagic2047我认为证明但是其余的案件很难正式证明……q=pPp{23} (mod 4)pËp
Shieru Asakoto

1
@ infmagic2047的有关此方法的math.se问题现在有了完整证明的答案
与Orjan约翰森

11

Mathematica,80个字节

d[n_]:=If[#=={},0,1/Det@LatticeReduce@#]&@Select[Tuples[Range[-n,n],2],#.#==n&];

此代码主要依赖于数学定理。基本思想是代码在给定某些生成集的情况下要求晶格的密度。

更准确地说,我们得到了一些向量集合-即长度平方为N的向量,并要求与所有整数向量相比,计算这些向量的可能总和集合的密度。数学上的作用是,我们总是可以找到两个与原始集合“生成”(即它们的总和)相同集合的向量(及其相反)。LatticeReduce正是这样做的。

如果只有两个向量,可以想象绘制一个以每个可到达点为中心的相同的平行四边形,但是其边长是给定的向量,从而使平面由这些平行四边形完全平铺。(例如,想象一下n = 2的“菱形”形状的晶格)。每个平行四边形的面积是两个生成矢量的行列式。平面的期望比例是该面积的倒数,因为每个平行四边形只有一个可到达的点。

该代码是一个非常简单的实现:生成向量,使用LatticeReduce,获取行列式,然后取倒数。(虽然打高尔夫球可能会更好)


76个字节:d@n_:=Boole[#!={}]/Det@LatticeReduce@#&@Select[Range[-n,n]~Tuples~2,#.#==n&]
u54112

11

干净189个 185 172 171字节

import StdEnv
$n#r=[~n..n]
#p=[[x,y]\\x<-r,y<-r|x^2+y^2==n]
=sum[1.0\\_<-iter n(\q=removeDup[k\\[a,b]<-[[0,0]:p],[u,v]<-q,k<-[[a+u,b+v]]|all(\e=n>=e&&e>0)k])p]/toReal(n^2)

在线尝试!

n在第一个象限的原点处的-边长正方形中找到每个可到达的位置,然后除以n^2得到所有可到达的像元部分。

之所以有效,是因为:

  • 整个可到达平面都可以看作是此边n长正方形的重叠副本,每个副本都在从原点到达的可到达点上折角,就好像它是原点一样。
  • 所有运动以带符号的四个为一组,++ +- -+ --通过镜像和旋转允许重叠的图块扩展到其他三个象限。

抱歉,我正在查看从N = 10到N = 13的测试用例,而您的测试用例也包括N = 11和N = 12。对于N = 13,您确实是正确的。从我+1 :)
trichoplax

1
@trichoplax我已更改测试以与问题相对应,以避免再次出现相同的困惑
urous

我进一步测试了N = 145,并且都正确。由于60秒超时,我无法在TIO上测试146。我期望答案的运行时间非常长...
trichoplax

1
因为我花了一段时间才意识到这一点:如果至少有一个动作(a,b),那么方角就可以到达的原因是复数方程(a + bi)(a-bi)= a ^ 2 + b ^ 2,其向量形式为(N,0)= a(a,b)+ b(b,-a)。
与Orjan约翰森

5

视网膜0.8.2126个 82字节

.+
$*
+`^(1(1111)+)(?<!^\3+(11+))(\1)*$
1$#4$*
^(?!((^1|11\2)+)\1?$)1+
0
11+
1/$.&

在线尝试!链接包括测试用例。说明:

.+
$*

转换为一元。

+`^(1(1111)+)(?<!^\3+(11+))(\1)*$
1$#4$*

反复除以形式的素因子4k+1

^(?!((^1|11\2)+)\1?$)1+
0

如果结果既不是正方形也不是正方形的两倍,则结果为零。

11+
1/$.&

将倒数计算为小数部分。


5

正则表达式(ECMAScript中,倒数出),256个 163 157 94 83 82字节

-93字节归因于Neil
-6字节归因于Neil
-63字节,归因于除法而不捕获除数
-11字节归功于Grimy通过移动结束匹配条件同时进行的常数除法和平方根
-1字节并通过Grimy将值捕获作为第二种选择返回到循环中

它使用与Shieru Asakoto的JavaScript答案相同的数学方法。

输入为一元。由于纯正则表达式只能从输入返回子字符串(即小于或等于输入的自然数)或“不匹配”作为输出,因此该正则表达式返回N移动器所占比例的板的倒数可以到达。由于0的倒数是无穷大,因此在这种情况下它将返回“ no match”。

SPOILER警告:对于平方根,此正则表达式使用广义乘法算法的变体,该算法不明显,可能是您自己解决的一个难题。有关更多信息,请参阅“ 查找Rocco编号”中对此算法形式的说明。

pp1个 (mod 4)3 (mod 4)/2

/2p3 (mod 4)

^(?=((?=(x+)(?!(\2+)(\2\3)+$)((\2{4})+$))\5|((xx?)(\8*))(?=(\7*)\9+$)\7*$\10)+$)\1

在线尝试!
在线尝试!(只是测试用例)

^
(?=
    (                          # Capture return value, which will just be the value
                               # matched by the last iteration of this loop.
    # Divide tail by every one of its prime factors that's ≡1 mod 4, as many times as
    # possible.
        (?=
            (x+)               # \2 = quotient
            (?!(\2+)(\2\3)+$)  # Assert divisor is prime
            ((\2{4})+$)        # Assert divisor ≡1 mod 4; \5 = tool to make tail = \2
        )\5                    # tail = \2
    |
    # When the above alternative has been done as many times as possible:
    # Test if tail or tail/2 is a perfect square. If this test fails, the regex engine
    # will backtrack into the division loop above, and run the same perfect square
    # test on every previous number (effectively "multiplying" it by each previous P
    # in reverse, one at a time). This will not cause a failure of the test to change
    # into a success, however, because the odd power of a prime ≡3 mod 4 will see be
    # present in the number at every step. Allowing this backtracking to happen is a
    # golf optimization, and it does make the regex slower.
    # Failure of this perfect square test results in returning "no match" and indicates
    # a return value of zero.
        (                      # \7 = \8 * sqrt(tail / \8)
            (xx?)              # \8 = control whether to take sqrt(tail)
                               #                         or 2*sqrt(tail/2)
            (\8*)              # \9 = \7 - \8
        )
        (?=
            (\7*)\9+$          # Iff \8 * (\7 / \8)^2 == our number, then the first match
                               # here must result in \10==0
        )
        \7*$\10                # Test for divisibility by \7 and for \10==0
                               # simultaneously
    )+
    $                          # Require that the last iteration of the above loop was
                               # the perfect square test. Since the first alternative,
                               # the division, always leaves >=1 in tail, this guarantees
                               # that the last step is a successful perfect square test,
                               # or else the result will be "no match".
)
\1                             # Return value (which is a reciprocal)

正则表达式(ECMAScript的+(*),倒数输出),207个 138 132字节

因进行除法而不捕获除数而被淘汰(即,现在与上面相同)。

正则表达式(ECMAScript的2018,倒数输出),212个 140 134字节

因进行除法而不捕获除数而被淘汰(即,现在与上面相同)。

正则表达式(ECMAScript,分数输出),80字节

在此版本中,分子以形式返回\10(如果未设置,则返回零/ NPCG),分母以形式返回\7

与互惠输出版本不同:

  • 零输入未正确处理(就像该版本一样,它返回“ no match”,但与之不同的是,它不对应于零输出值)。
  • 如果完全平方测试失败,则不会回溯到除法循环中,因此此版本的执行时间更加高效。

这样的输出规范的一个很大的缺点是它本身不包含在程序本身中。

((?=(x+)(?!(\2+)(\2\3)+$)((\2{4})+$))\5)*((((x)x?)(\9*))(?=(\8*)\11+$)\8*$\12|x)

在线尝试!
在线尝试!(只是测试用例)

# No need to anchor, since we return a match for all inputs in the domain.
# Divide tail by every one of its prime factors that's ≡1 mod 4
(
    (?=
        (x+)               # \2 = quotient
        (?!(\2+)(\2\3)+$)  # Assert divisor is prime
        ((\2{4})+$)        # Assert divisor ≡1 mod 4; \5 = tool to make tail = \2
    )\5                    # tail = \2
)*
# Test if tail or tail/2 is a perfect square. If this test succeeds, return tail as
# the denominator and 1 as the numerator.
(                          # \7 = denominator output
    (                      # \8 = \9 * sqrt(tail / \9)
        ((x)x?)            # \9 = control whether to take sqrt(tail) or 2*sqrt(tail/2);
                           # \10 = numerator output (NPCG to represent zero)
        (\9*)              # \11 = \8 - \9
    )
    (?=
        (\8*)\11+$         # Iff \9 * (\8 / \9)^2 == our number, then the first match
                           # here must result in \12==0
    )
    \8*$\12                # Test for divisibility by \8 and for \12==0
                           # simultaneously
|
# Failure of the perfect square test results in returning 0/1 as the answer, so here
# we return a denominator of 1.
    x
)

1
抱歉,我显然没有在足够的测试用例上尝试过。
尼尔

1
@trichoplax您是否可以将答案视为两个特定捕获组的长度之比?(这实际上会使答案更短,因为要花很多时间才能使整个比赛成为结果。)
Neil

1
在@Neil的评论之后,我进行了编辑,以允许将输出作为单独的分子和分母,因为这似乎是允许纯正则表达式的最小更改。让我知道这是否仍然是一个问题
trichoplax

1
-11字节,(((xx?)(\9*))(?=(\8*)\10+$)\8*$\11)用于检查N或N / 2是否为正方形。
Grimmy

1
@Deadcode指针指向backrefs应给予字节的成本,因为他们是默认不允许的
犯罪

4

果冻 25  24 字节

ÆFµ%4,2CḄ:3+2Ịị,*/ʋ÷*/)P

使用素数因子路径的单子链接。

在线尝试!

怎么样?

ÆFµ%4,2CḄ:3+2Ịị,*/ʋ÷*/)P - Link: integer, n               e.g. 11250
ÆF                       - prime factor, exponent pairs        [[2,1], [3,2], [5,4]]
  µ                   )  - for each pair [F,E]:
    4,2                  -   literal list [4,2]
   %                     -   modulo (vectorises)                [2,1]  [3,0]  [1,0]
       C                 -   complement (1-x)                  [-1,0] [-2,1]  [0,1]
        Ḅ                -   from base 2                         -2     -3      1      
         :3              -   integer divide by three             -1     -1      0
           +2            -   add two (call this v)                1      1      3
                  ʋ      -   last four links as a dyad, f(v, [F,E])
             Ị           -     insignificant? (abs(x)<=1 ? 1 : 0)   1      1      0
                */       -     reduce by exponentiation (i.e. F^E)  2      9     625
               ,         -     pair v with that                   [1,2]  [1,9]  [3,625]
              ị          -     left (Ị) index into right (that)     1      1     625
                    */   -   reduce by exponentiation (i.e. F^E)    2      9     625
                   ÷     -   divide                                1/2    1/9  625/625
                       P - product                                 1/18 = 0.05555555555555555

前25个是:

ŒRp`²S⁼ɗƇ⁸+€`Ẏ;Ɗ%³QƊÐLL÷²

完整的程序暴力破解; 可能比主要因素路由更长的代码(我可能稍后再尝试)。

在线尝试!

首先创建单个移动作为然后坐标反复从累加的结果均达到位置移动时,采取模n坐标(以限制到每个nn象限)和保持那些直到达到一个固定点,其是不同的; 然后最后将计数除以n^2


4

05AB1E27 26 25 字节

ÓεNØ©<iozë®4%D≠iyÈ®ymz*]P

@ShieruAsakoto的JavaScript答案端口,因此请确保也对他进行投票

在线尝试验证所有测试用例

说明:

Ó                   # Get all prime exponent's of the (implicit) input's prime factorization
                    #  i.e. 6 → [1,1]      (6 → 2**1 * 3**1)
                    #  i.e. 18 → [1,2]     (18 → 2**1 * 3**2)
                    #  i.e. 20 → [2,0,1]   (20 → 2**2 * 3**0 * 5**1)
                    #  i.e. 25 → [0,0,2]   (25 → 2**0 * 3**0 * 5**2)
 ε                  # Map each value `n` to:
  NØ                #  Get the prime `p` at the map-index
                    #   i.e. map-index=0,1,2,3,4,5 → 2,3,5,7,11,13
    ©               #  Store it in the register (without popping)
     <i             #  If `p` is exactly 2:
       oz           #   Calculate 1/(2**`n`)
                    #    i.e. `n`=0,1,2 → 1,0.5,0.25
      ë             #  Else:
       ®4%          #   Calculate `p` modulo-4
                    #    i.e. `p`=3,5,7,11,13 → 3,1,3,3,1
          D         #   Duplicate the result (the 1 if the following check is falsey)
           i       #   If `p` modulo-4 is NOT 1 (in which case it is 3):
             yÈ     #    Check if `n` is even (1 if truthy; 0 if falsey)
                    #     i.e. `n`=0,1,2,3,4 → 1,0,1,0,1
             ®ymz   #    Calculate 1/(`p`**`n`)
                    #     i.e. `p`=3 & `n`=2 → 0.1111111111111111 (1/9)
                    #     i.e. `p`=7 & `n`=1 → 0.14285714285714285 (1/7)
              *     #    Multiply both with each other
                    #     i.e. 1 * 0.1111111111111111 → 0.1111111111111111
                    #     i.e. 0 * 0.14285714285714285 → 0
 ]                  # Close both if-statements and the map
                    #  i.e. [1,1] → [0.5,0.0]
                    #  i.e. [1,2] → [0.5,0.1111111111111111]
                    #  i.e. [2,0,1] → [0.25,1.0,1]
                    #  i.e. [0,0,2] → [1.0,1.0,1]
  P                 # Take the product of all mapped values
                    #  i.e. [0.5,0.0] → 0.0
                    #  i.e. [0.5,0.1111111111111111] → 0.05555555555555555
                    #  i.e. [0.25,1.0,1] → 0.25
                    #  i.e. [1.0,1.0,1] → 1.0
                    # (and output implicitly as result)

4

APL(Dyalog扩展),21字节

该程序使用素数因子路径。我要感谢Adám,dzaima,H.PWiz,J.Sallé和ngn。APL果园是学习APL的好地方,他们总是乐于助人

(×/÷,34|*∘≢⌸)⍭*14|⍭

在线尝试!

开球

该代码的第2部分与下面的Dyalog Unicode版本相同,因此在此说明中,我将重点介绍 ⍭*1≠4|⍭

⍭*14|⍭

        Gives us a list of the prime factors of our input.
           Example for 45: 3 3 5
  14|   Checks if each prime is of the form 4k+1.
⍭*       Takes each prime to the power of 1 or 0,
           turning all the 4k+1 primes into 1s.
           Example for 45: 3 3 1

APL(Dyalog Unicode)41 40 36 35 字节SBCS

该程序使用素数因子路径。在撰写本文时学到了一些技巧,我对Adám,dzaima,H.PWiz,J.Sallé和ngn感激不尽。APL果园是学习APL的好地方,他们总是乐于助人(否则这篇文章永远都不会付诸实践:)

编辑:-1字节从ngn。来自Adám的-2个字节,来自ngn的-2个字节。从ngn开始-1个字节。

{(×/÷,34|*∘≢⌸)p*14|p←¯2÷/∪∧\⍵∨⍳⍵}

在线尝试!

开球

这是一个分为两部分的程序:

p*14|p←¯2÷/∪∧\⍵∨⍳⍵  Part 1

      p             We can define variables mid-dfn (a function in {} brackets).
               ⍵∨⍳⍵  We take the GCD of our input 
                       with every member of range(1, input).
            ∪∧\      This returns all the unique LCMs of every prefix
                       of our list of GCDs.
                       Example for 31500: 1 2 6 12 60 420 1260 6300 31500
        ¯2÷/         We divide pairwise (and in reverse)
                       by using a filter window of negative two 2).
                       Example for 31500: 2 3 2 5 7 3 5 5
  14|p              Check if the primes are 1 modulo 4 or not
p*                   And take each prime to the power of the result (1 or 0),
                       turning the 4k+3 primes into 1s
                       and leaving any 2s and 4k+3 primes.
                       Example for 31500: 2 3 2 1 7 3 1 1

(×/÷,34|*∘≢⌸)  Part 2

(            )  We apply all this to the filtered array of primes.
         *∘≢⌸   This takes all of our primes to their exponents
                  (the number of times those primes appear in the factorization).
                  Example for 31500: 4 9 1 7
     34|       Then we take each prime modulo 4 and check if not equal to 3.
                  We will only get a falsey if any 4k+3 primes, as an even number of
                  4k+3 primes multiplied together will result in some 4m+1.
                  Example for 31500: 1 1 1 0
   ÷,           We append the results of the above condition check
                  to the reciprocals of the primes in p.
                  Example for 31500: (1/2) (1/3) (1/2) 1 (1/7) (1/3) 1 1 1 1 1 0
 ×/             We multiply it all together, resulting in a positive fraction or 0
                  depending on our condition check.
                  Example for 31500: 0
                We return the results of all our checks implicitly.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.