魔术模平方


11

我是数论的忠实拥护者。数论中的一件大事是模块化算术。当且仅当m \ mid ab时,定义为。一个有趣的事情是提高幂:尤其是当模数是质数时。特别地,已经证明,如果am是相对质数(除了1之外没有其他共同因素),则存在一个数e,使得a ^ e \ equiv 1 \ mod mabmodmmabam1eae1modm

我将通过一个例子来说明什么是练习。取模数。程序或功能的可能输出为:m=7

3 2 6 4 5 1
2 4 1 2 4 1
6 1 6 1 6 1
4 2 1 4 2 1
5 4 6 2 3 1
1 1 1 1 1 1

每行是该行中第一个数字的幂的列表:第一行是,等效于模。上方正方形的第二行是的幂,以此类推,直到最后一行,都是幂。3,32,33,,363,2,6,4,5,1721

这是一个神奇的模平方,因为:

  • 正方形是对称的;也就是说,第列与第行相同。ii
  • 所有值到至少出现一次。1m1

以下是的唯一其他有效输出,从幂开始:m=75

5 4 6 2 3 1
4 2 1 4 2 1
6 1 6 1 6 1
2 4 1 2 4 1
3 2 6 4 5 1
1 1 1 1 1 1

挑战

创建一个给定素数的函数或程序,p输出一个神奇的模平方,即具有边长的平方p-1,这样,每一行都是该行中第一个元素的连续幂的列表,各列也是如此。0和之间的所有数字都p必须出现,并且正方形只能包含该范围内的数字。

输入是数字或字符串,输出可以是ascii,矩阵,数组数组(任何合理的格式)。

这是代码高尔夫球,因此最短的代码获胜。


相关的OEIS序列:A001918左上角的最低有效值)。
阿诺尔德

2
我将通过一个示例来说明练习是什么。 ” 用自己的术语解释它,然后给出一个示例进行说明。我认为您要的是矩阵,使得是原始根模而,但是要从当前问题中提取该规范需要付出很多努力。AA1,1pAi,j=A1,1ijmodp
彼得·泰勒

2
@PeterTaylor是真的,这就是我的意思,但是首先,这破坏了一部分探索乐趣,其次,它依赖于有关原始根和模块化算术的知识。我希望这个问题能得到更多听众的回答,所以我尝试用更简单的方式解释我的意思。
vrugtehagel,

Answers:


5

果冻13 10 字节

-3感谢尼克·肯尼迪

感觉像在重复的代码应该是高尔夫能干,但我没有管理ð它...

*€Ṗ%µQƑƇḢị

在线尝试!(页脚漂亮的格式为网格)

怎么样?

*€Ṗ%µQƑƇḢị - Link: integer, p
 €         - for each n in [1..p]
*          -   exponentiate with:
  Ṗ        -     pop = [1..p-1]
           - ...i.e [[1^1,1^2,...,1^(p-1)],[2^1,2^2,...,2^(p-1)],...,[....,p^(p-1)]]
   %       - modulo p
    µ      - start a new monadic chain (call that list of lists X)
       Ƈ   - keep those which:
      Ƒ    -   are invariant under:
     Q     -     de-duplicate
        Ḣ  - head
         ị - index into the list of lists X


啊哈,现在我感觉很慢;谢谢!
乔纳森·艾伦,

3

木炭,36字节

≔E…¹θ﹪Xι…¹θIθηE⊟Φη⁼¹№ι¹⪫E§η⊖ι◧IλL⊖θ 

在线尝试!链接是详细版本的代码。注意:尾随空格。说明:

≔E…¹θ﹪Xι…¹θIθη

创建一个p-1由to p-1的幂的by 数组(模数)。1..p-11..p-1p

E⊟Φη⁼¹№ι¹

映射到恰好为1的行之一1

⪫E§η⊖ι◧IλL⊖θ 

将行重新排列为所选行给定的顺序,并格式化输出。




2

JavaScript(ES7), 91  86字节

此版本尝试在应用模之前计算功效,并且由于精度损失而无法使用。否则,它将使用与下面的注释版本相同的逻辑。p11

f=(p,k)=>(g=k=>[...Array(i=p-1)].map(_=>k**++i%p))(k).sort()[1]>1?g(k).map(g):f(p,-~k)

在线尝试!


JavaScript(ES6), 92  87字节

此版本使用模幂运算来支持(很多)更高的输入值。

f=(p,k)=>(g=k=>[...Array(p-1)].map(_=>n=n*k%p,n=1))(k).sort()[1]>1?g(k).map(g):f(p,-~k)

在线尝试!

怎么样?

查找第一行

鉴于,我们使用辅助函数到计算为。1k<pgak(n)=knmodp1n<p

g = k =>              // k = input
  [...Array(p - 1)]   // generate an array of size p - 1
  .map(_ =>           // for each entry in there:
    n = n * k % p,    //   update n to (n * k) mod p
    n = 1             //   starting with n = 1
  )                   // end of map()

我们寻找使得只有一个值使得。我们通过对数组进行排序并测试第二个元素是否大于做到这一点。knak(n)=11

g(k).sort()[1] > 1

即使按字典顺序也可以工作-这是默认行为sort()-因为:

  • 如果有多个,它们将全部移到前面,就像数字顺序一样1
  • 如果只有一个,则第二个值将大于,无论它是否真的是数字顺序的第二个11

例:

对于:p=17

  • 对于,我们得到: k=1
    • a1=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
    • 排序为[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
  • 对于,我们得到: k=2
    • a2=[2,4,8,16,15,13,9,1,2,4,8,16,15,13,9,1]
    • 排序为[1,1,13,13,15,15,16,16,2,2,4,4,8,8,9,9]
  • 对于,我们得到: k=3
    • a3=[3,9,10,13,5,15,11,16,14,8,7,4,12,2,6,1]
    • 排序为[1,10,11,12,13,14,15,16,2,3,4,5,6,7,8,9]

建立矩阵

一旦找到,我们将再次调用(以检索数组的未排序版本),并在每个元素上调用以构建矩阵的行。kg(k)gg(k)

这部分可以简单地写成:

g(k).map(g)

.indexOf(1)>p-3节省3个字节.every
尼尔,

@尼尔谢谢。但是,我发现一夜安眠后,可以找到一种更短的方法。:)
Arnauld

2

Zsh117个 90字节

b=$1
c=(eval set -- '$[x**'{1..$[b-1]}%b\])
for ((;${#${(u)@}}-b+1;++x))$c
for x;$c&&<<<$@

在线尝试! 在线尝试!

愿上帝怜悯我的灵魂。这里有很多不好的做法,至少让我解释一下最大的罪犯:

c=(eval set -- '$[x**'{1..$[b-1]}%b\])
                      {1..$[b-1]}        # brace expansion, expands immediately
               '$[x**'           %b\]    # string literals, expand during eval
   eval set --                           # sets the positional parameters
c=(                                   )  # defines c to the words contained

示例b=4

c=(eval set -- '$[x**'{1..$[b-1]}%b\])
c=(eval set -- '$[x**'{1..3}%b\]     )                # $[b-1] => 3
c=(eval set -- '$[x**1%b]' '$[x**2%b]' '$[x**3%b]' )  # brace expansion

最后,在$c程序其余部分中出现的位置,将数组元素评估为eval set -- ....

最后,${#${(u)@}}计算位置参数中的唯一元素(即:是否存在循环/是否存在1s?)

与下面的117字节答案有关的注释。


我们必须克服的挑战:

  • 没有多维或嵌套数组。相反,当我们使它们循环时,我们将其打印出来。
  • 用于测试给定行是否具有多个1的选项:
    • ${#${(M)a:#1}:#删除匹配项,并(M)反转匹配项。因此,这将扩展为数组${# }1s 的数量。不幸的是,这种扩展不能与我们在此处使用的for循环算法很好地配合。如果这样做,可能会节省一个字节。
    • ${${:-1}:*a}:这是单例1和集合之间的集合交集a1如果在数组中找到它,它将扩展为单个。使用此选项,我们在此处保存了一个字符,但由于不得不推迟1在最后一行和最后一列中添加s而使总体损失了1个字符。
f(){ # f [element] [modular base], puts powers up to n-2 into array $a
    a=()
    for i ({1..$[$2-2]})
        a+=($[$1**i%$2])
}
a=(1)                     # put 1 in a to force first loop iteration
for ((;${${:-1}:*a};))    # test for 1 in array $a
    f $[++x] $1           # increment x, iterate through all elements mod $1
for y ($a 1){             # for all elements in the [last array, 1]
    f $y $1               # put that row in $a
    <<<$a\ 1              # print out $a with 1 appended (space-delimited string)
}

1

Perl 6的65 57个字节

{.[|.first(*.Set+2>$_)]}o{.&{@=(($++X**1..^$_)X%$_)xx$_}}

在线尝试!

可能有某种方法可以只输出平方本身,但是这样做的过程与问题中概述的过程相同,即按列表在第一个列表中的位置对列表进行排序,该列表只是输入1的1排列。返回为列表列表。

顺便说一句,有很多人试图解决Perl 6涉及序列,数组和匿名变量的烦人限制。

说明:

                               $++               xx$_    # Map 0 to i-1 to
                              (   X**1..^$_)             # n, n^2, n^3... n^(i-1)
                             (              X%$_)        # All modulo i
{                      }o{.&{                        }}  # Pass to the next function
 .[                   ]    # Index into that list of lists
   |.first(          )     # The list of the first list that
           *.Set+2>$_        # Has all the elements in the range 1 to i-1


1

05AB1E19 16 字节

LεI<LmI%}ÐΘOÏн<è

-3个字节,感谢@Emigna

在线尝试(页脚是漂亮打印2D列表)。

说明:

L          # Create a list in the range [1, (implicit) input]
 ε         # Map each number `y` in the list to:
  I<L      #  Create a list in the range [1, input-1]
     m     #  Get number `y` to the power of each number in this list
      I%   #  Take modulo-input on each number
         # After the map: triplicate this modified matrix
   ΘO      # Get the amount of 1s in each row
     Ï     # And only leave the rows with exactly one 1
      н    # Then only leave the first row which contains a single 1
       <   # Decrease each value by 1 to make it 0-indexed
        è  # And index each into the rows of the modified matrix to create a new matrix
           # (which is output implicitly as result)

1
LεI<LmI%}ÐΘOÏн<è16个字节
艾米尼亚(Emigna)

@Emigna谢谢!没有意识到会比UΣXyk我有足够的。
凯文·克鲁伊森



0

APL(NARS),29个字符,58个字节

{k←⍵∣⍺*⍳⍵-1⋄⊃{m∣k*⍵}¨⍳¯1+m←⍵}

测试:

  f←{k←⍵∣⍺*⍳⍵-1⋄⊃{m∣k*⍵}¨⍳¯1+m←⍵}
  3 f 7
3 2 6 4 5 1
2 4 1 2 4 1
6 1 6 1 6 1
4 2 1 4 2 1
5 4 6 2 3 1
1 1 1 1 1 1
  5 f 7
5 4 6 2 3 1
4 2 1 4 2 1
6 1 6 1 6 1
2 4 1 2 4 1
3 2 6 4 5 1
1 1 1 1 1 1 
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.