Чарівні квадрати модуля


11

Я великий фанат теорії чисел. Велика річ у теорії чисел - це модульна арифметика; визначення є тоді і тільки тоді, коли . Забавна річ - це підняття повноважень: особливо, коли модуль є простим числом. Зокрема, було доведено, що якщо a і m є відносно простими (не мають загальних факторів, крім 1 ), то існує число e таке, що a ^ e \ equiv 1 \ mod m .abmodmmabam1eae1modm

Я поясню, що таке вправа на прикладі. Візьмемо модуль 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,,36 , що еквівалентно 3,2,6,4,5,1 модуль 7 . Другий ряд квадрата вгорі - це потужності 2 , etcetera, аж до останнього ряду, які є лише повноваженнями 1 .

Це магічний квадрат модуля, оскільки:

  • Квадрат симетричний; тобто i й стовпець такий самий, як i й рядок.
  • Усі значення від 1 до m1 з'являються принаймні один раз.

Нижче представлений єдиний інший дійсний вихід для , починаючи з потужностей :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
" Я поясню, що таке вправа на прикладі. " Не варто. Поясніть це своїми словами, а потім наведіть приклад для ілюстрації. Я думаю, що те, що ви просите, це матриця така, що є примітивним кореневим модулем і , але потрібно докласти чимало зусиль, щоб витягнути цю специфікацію з питання, як вона є. A 1 , 1 p A i , j = A 1 , 1AA1,1pAi,j=A1,1ijmodp
Пітер Тейлор

2
@PeterTaylor правда, і саме це я маю на увазі, але, по-перше, це псує частину розвідувальних розваг, по-друге, вона покладається на знання про примітивні корені та модульну арифметику. Я хотів, щоб це питання відповідало ширшій аудиторії, ніж це, тому я спробував пояснити, що я маю на увазі, простіше.
вругтегагель

Відповіді:


5

Желе , 13 10 байт

-3 завдяки Ніку Кеннеді

За відчуттю як повторний код повинен бути в гольф-стані, але я б не вдавалися d це ...

*€Ṗ%µ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


Ага, зараз я відчуваю себе повільно; p дякую!
Джонатан Аллан

3

Вугілля деревне , 36 байт

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Примітка: простір. Пояснення:

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

Створення з p-1допомогою p-1масиву повноважень по 1..p-1індексах 1..p-1( по модулю p).

E⊟Φη⁼¹№ι¹

Зіставте карту на одному з рядків, в якому є рівно один 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)

Спробуйте в Інтернеті!

Як?

Знаходження першого ряду

1к<pгак(н)=кнмодp1н<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()

кнак(н)=11

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

Це працює навіть у лексикографічному порядку - що є поведінкою за замовчуванням sort()- тому що:

  • 1
  • 11

Приклад:

p=17

  • к=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,1,1]
  • к=2
    • а2=[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]
  • к=3
    • а3=[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]

Побудова матриці

кг(к)гг(к)

Цю частину можна просто записати так:

g(k).map(g)

.indexOf(1)>p-3економить 3 байти .every.
Ніл

@Neil Дякую Але я знайшов коротший шлях після доброго сну. :)
Арнольд

2

Zsh , 117 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)@}}підраховує унікальні елементи в позиційних параметрах (тобто: чи існує цикл / чи є 1?)

Коментарі, що стосуються відповіді на 117 байт нижче.


Проблеми, які ми маємо подолати:

  • Немає багатовимірних або вкладених масивів. Замість цього ми роздруковуємо рядки, отримуючи їх у циклі.
  • Варіанти тестування, якщо в даному рядку є декілька 1:
    • ${#${(M)a:#1}: :#видаляє відповідність і (M)скасовує відповідність. Отже, це розшириться до числа ( ${# }) 1s у масиві. На жаль, це розширення не дуже добре відповідає арифметиці для циклу, яку ми використовуємо тут. Якщо це зробити, це потенційно може зберегти байт.
    • ${${:-1}:*a}: Це перетин множин між синглоном 1та безліччю a. Це розшириться до одиничного, 1якщо він знайдеться в масиві. Використовуючи цю опцію, ми зберігаємо тут один символ, але втрачаємо 1 загальний з необхідності відкласти додавання 1s в останньому рядку та стовпці до кінця.
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

05AB1E , 19 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 Дякую! Не усвідомлював, що буде достатньо замість того, що 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 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.