Створіть групову таблицю для Z_n


9

Групи є широко використовуваною структурою в математиці та мають додатки в галузі інформатики. Цей виклик коду стосується найменшої кількості символів для створення групової таблиці для групи добавок Z n .

Як побудовано таблицю: Для Z n елементами є {0, 1, 2, ..., n-1}. У таблиці буде n рядків і n стовпців. Для ij-го запису таблиці значення i + j mod n. Наприклад, у Z 3 1-2-й запис (2-й рядок, 3-й стовпець, якщо ви рахуєте початковий рядок / стовпець як 1), є (1 + 2)% 3 = 0 (див. Вихідний зразок).

Введення: натуральне число, n

Вихідні дані: таблиця, що являє собою текстову презентацію Z n , побудована так, як описано вище, і відображається так, як показано нижче у зразках вибірок. Пробіли необов’язкові

Зразок введення: 3

Вибірка зразка:

0 1 2
1 2 0
2 0 1

Зразок введення: 5

Вибірка зразка:

0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3

3
Оскільки роздільник необов’язковий, чи буде вхід вище 10?
Jo King

@JoKing на основі codegolf.stackexchange.com/questions/35038/… Я здогадуюсь так
qwr

Відповіді:


10

APL (10)

(Припустимо ⎕IO=0. Він працює за ngn / apl за замовчуванням, інші APL , як правило, потребують ⎕IO←0першого.)

{⍵|∘.+⍨⍳⍵}

Пояснення:

  • ⍳⍵: числа [0..⍵)
  • ∘.+⍨: створити таблицю підсумків
  • ⍵|: числа в таблиці mod

1
Чи можете ви зробити ⊢|⍳∘.+⍳, чи поїзди не працювали у липневій версії ngn?
lirtosiast

3

GolfScript (13 символів)

З вашого коментаря до відповіді Клавдіу я розумію, що пробіл між елементами ряду не потрібен. З цього розуміння:

~.,{.n\(+}@(*

Демонстрація в Інтернеті

Розсічення:

~        Parse the input into an integer
.,       Duplicate it, turn the second into an array [0,...,n-1]
{        Loop: top of stack is the previous row
  .n\    Push a newline and a copy of the previous row
  (+     Rotate the first element to the end to get the new row
}@(*     Perform loop n-1 times

Якщо пробіл необхідний, на 20 символів:

~.,{.(+}@(*]{' '*n}/

Дуже приємна робота на цих!
Райан

3

Python 2, 66 байт

def f(n):R=range(n);exec"print''.join(map(str,R));R+=R.pop(0),;"*n

Повертає список, виводячи та повторно додаючи.

Python 3, 53 байти

def f(n):*R,=range(n);[print(*R[i:]+R[:i])for i in R]

Використовує той самий метод, що і @ mbomb007, але зловживає printфункцією.


Це *R,=дивна конструкція ... Чи служить вона лише для перетворення rangeрезультатів на кордон?
Джонатан Фрех

Чи можете ви пояснити, будь ласка, код Python 3? Я не бачив використання*R
tarit goswami

@taritgoswami Це вироджене розпакування; rangeце ітерабельний об'єкт, який можна розпакувати та перепакувати, зібравши все R. Це повинно бути рівнозначним R=list(range(n)), колишній - більш стислим.
Джонатан

3

05AB1E , 10 8 байт

ݨDδ+I%»

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

Пояснення

         # Implicit input n = 3                  [3]
Ý        # Push range(0,3)                       [[0,1,2,3]]
 ¨       # Pop last element                      [[0,1,2]]
  D      # Duplicate                             [[0,1,2],[0,1,2]]
   δ     # Apply next operation double vectorized
    +    # Vectorized addition                   [[[0,1,2],[1,2,3],[2,3,4]]]
     I   # Push input                            [[[0,1,2],[1,2,3],[2,3,4]],3]
      %  # Elementwise modulo 3                  [[[0,1,2],[1,2,0],[2,0,1]]]
       » # " ".join(x) followed by newline       ["0 1 2\n1 2 0\n2 0 1\n"]
           for every x in list       

Попередня відповідь: 10 байт

ݨDvDðý,À}

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

Моя перша спробу гольфу в 05AB1E.

Пояснення попередньої відповіді

           # Implicit input n = 3                   [3]
Ý          # Push range(0,3)                        [[0,1,2,3]]
 ¨         # Pop last element.                      [[0,1,2]]
  D        # Duplicate                              [[0,1,2],[0,1,2]]
   v     } # Pop list and loop through elements     [[0,1,2]]
    D      # Duplicate                              [[0,1,2],[0,1,2]]
     ð     # Push space char                        [[0,1,2],[0,1,2], " "]
      ý    # Pop list a and push string a.join(" ") [[0,1,2],"0 1 2"]
       ,   # Print string with trailing newline     [[0,1,2]] Print: "0 1 2"
        À  # Rotate list                            [[1,2,0]]  

1
Приємна перша відповідь, і ласкаво просимо! Я відчуваю, що це може бути коротше, але ось два 9-байтові варіанти: FݨN._ðý,і сміливоݨsGDÀ})» задайте будь-які запитання в чаті 05AB1E , і подивіться на сторінку підказки 05AB1E, якщо ви ще цього не зробили. :)
Кевін Кройсейсен

@KevinCruijssen Дякую! Здається, я забув знайти спосіб скористатися неявним введенням даних.
Віслав


1

Піта , 16

JVQXQjdJ=J+tJ]hJ

Друкує таблицю з належним пробілом.

./pyth.py -c "JVQXQjdJ=J+tJ]hJ" <<< 5
0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3

Пояснення:

                   Automatic: Q=eval(input())
JVQ                J = range(Q)
XQ                 repeat Q times
  jdJ              print J, joined on " "
  =J               J =
    +tJ]hJ             tail(J) + [head(J)] (J[1:] + [J[-1]]])

1

J, 20

Читання з stdin та створення двовимірного масиву (який робить те саме, що і зразок у запитанні).

(|+/~@i.)@".}:1!:1]3

Якщо функція приймає рядкові суфікси, (|+/~@i.)@".. Якщо функції, що приймає ціле число, достатньо, її |+/~@i.має бути достатньо.

Пояснення: f g у J (для функцій f, g) позначається "гачок", що є складовою функцією, яка виконує вхід через g (одинарна функція), а потім вхід і результат g через f (двійкова функція). Відповідь - вилка з компонентами |(модулем) та +/~@i.. Остання частина - «таблиця сум, складених - зі списком індексів-upto» ( i.трохи схоже rangeна Python).


Ви повинні оновити свою відповідь |+/~@i., що має бути прийнятним тут стандартними правилами.
Йона


1

Пітон 2, 67

Спробуйте їх обидва тут

Я використовую розділення списку для "повороту" списку nразів, друкуючи його щоразу. (68 символів)

def f(n):
 l=range(n)
 for i in l:print''.join(map(str,l[i:]+l[:i]))

Мені вдалося отримати його на один символ коротше, ніж вище, дивною хитрістю. (67 символів)

def f(n):
 l=range(n)
 for i in l:print''.join(`l[i:]+l[:i]`)[1::3]

Схоже , цей метод ще коротше в Python 3: def f(n):*R,=range(n);[print(*R[i:]+R[:i])for i in R]. Я не думав, що сплеск насправді працюватиме без парен.
Sp3000


1

машинний код x86-64 (Linux), 80 64 байт

0000000000000000 <zn_asm>:
   0:   6a 0a                   pushq  $0xa
   2:   89 f9                   mov    %edi,%ecx
   4:   ff c9                   dec    %ecx

0000000000000006 <zn_asm.l1>:
   6:   c6 06 0a                movb   $0xa,(%rsi)
   9:   48 ff ce                dec    %rsi
   c:   89 fb                   mov    %edi,%ebx
   e:   ff cb                   dec    %ebx

0000000000000010 <zn_asm.l2>:
  10:   89 c8                   mov    %ecx,%eax
  12:   01 d8                   add    %ebx,%eax
  14:   31 d2                   xor    %edx,%edx
  16:   f7 f7                   div    %edi
  18:   89 d0                   mov    %edx,%eax

000000000000001a <zn_asm.l3>:
  1a:   31 d2                   xor    %edx,%edx
  1c:   48 f7 34 24             divq   (%rsp)
  20:   83 c2 30                add    $0x30,%edx
  23:   88 16                   mov    %dl,(%rsi)
  25:   48 ff ce                dec    %rsi
  28:   85 c0                   test   %eax,%eax
  2a:   75 ee                   jne    1a <zn_asm.l3>
  2c:   ff cb                   dec    %ebx
  2e:   85 db                   test   %ebx,%ebx
  30:   7d de                   jge    10 <zn_asm.l2>
  32:   ff c9                   dec    %ecx
  34:   85 c9                   test   %ecx,%ecx
  36:   7d ce                   jge    6 <zn_asm.l1>
  38:   58                      pop    %rax
  39:   48 89 f0                mov    %rsi,%rax
  3c:   48 ff c0                inc    %rax
  3f:   c3                      retq

Я сподівався, що це рішення буде лише на кілька байт коротше, щоб можна було перемогти деякі інші публікації на цій посаді. Існує можливість, якщо я використовую деякі з 32 або 16 бітових версій регістрів, я можу поголити кілька байтів. Перетворення багатьох регістрів в 32-бітні версії адресації зберегло 16 байт.

В основному ця функція викликається з програми C / C ++, яка пройшла n через rdi, і вказівника на розподіл через rsi. Покажчик, який має rsi, насправді становить 1 байт від кінця виділення, оскільки таблиця побудована назад. Це полегшує перетворення цілого числа на друковані символи ASCII (робиться за допомогою деякого числа x mod 10 і перетворення результату в ASII).

Щоб побачити код обгортки C ++ та коментарі до складання, перегляньте мою репо .



1

MathGolf , 10 8 байт

r░y\Åo╫;

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

-2 байти завдяки Джо Кінгу

Пояснення

Я буду використовувати приклад 3для пояснення

r          range(0, n) ([0, 1, 2])
 ░         convert to string (implicit map) (['0', '1', '2'])
  y        join array without separator to string or number ('012')
   \       swap top elements ('012', 3)
    Å      start block of length 2 (for-loop, loops 3 times ('012'))
     o     print TOS without popping
      ╫    left-rotate bits in int, list/str ('012' => '120' => '201' => '012')
       ;   discard TOS (prevents final print)

Ви також можете зробити це r░y\(Åo╫, що зменшує кількість циклів на 1 і пропускає скасування після циклу.



@JoKing це розумно! Можливо, ви могли б використати qдля видалення дублювання?
maxb

Я мав на увазі o. Хоча найкращим, що я міг зрозуміти, було саме це . Це може бути і 10 байт, але я на мобільному.
maxb

Оскільки роздільник необов’язковий, 8 байт повинні працювати
Джо Кінг,

0

С - 96

void g(int k){int i;for(i=0;i<k*k;i++){if(i&&!(i%k))puts("\n");printf("%i ",((i/k)+(i%k))%k);}}

0

Гольфскрипт, 20 символів

Страшенно ледача робота.

~:j,{:x;j,{x+j%}%n}/

Виконати його тут . (Перший рядок - це імітувати stdin).

Пояснення :

~                     # evaluate input (turn string "5" into number 5)
:j                    # store into variable j
,                     # turn top of stack into range(top), e.g. 5 --> [0, 1, 2, 3, 4]
{...}/                # for each element in the array... 
  :x;                 # store the element into x and pop from the stack
  j,                  # put range(j) on the stack ([0, 1, 2, 3, 4] again)
  {...}%              # map the array with the following:
      x+j%            # add x and mod the resulting sum by j
  n                   # put a newline on the stack

Коли програма закінчується, стек містить кожен масив з новими рядками між ними. Інтерпретатор виводить те, що залишилося в стеку, даючи бажаний результат.


1
Приємно! Хоча пробіли між елементами були не потрібні, це може бути корисно, коли ми маємо елементи значення> = 10 (тобто коли n> = 11).
Райан

Чи можете ви пояснити свій код? Для мене читання гольфскрипту гірше, ніж читання чужої виразки. (майже =)
flawr

@flawr: Звичайно, це досить просто
Клавдіу,

0

CJam, 14 символів

l~_)_@,*/Wf<N*

Тестуйте це тут.

Пояснення

Ідея полягає в тому, щоб повторити рядок від 0до N-1, але розділити його на блоки N+1. Це невідповідність зміщує рядок вліво кожного разу. Нарешті, нам потрібно позбутися стороннього персонажа і приєднати все до нових рядків.

Ось розкритий код разом із вмістом стеку для введення 3.

l~              "Read and eval input."; [3]
  _             "Duplicate.";           [3 3]
   )            "Increment.";           [3 4]
    _           "Duplicate.";           [3 4 4]
     @          "Rotate.";              [4 4 3]
      ,         "Get range.";           [4 4 [0 1 2]]
       *        "Repeat.";              [4 [0 1 2 0 1 2 0 1 2 0 1 2]
        /       "Split.";               [[[0 1 2 0] [1 2 0 1] [2 0 1 2]]
         Wf<    "Truncate each line.";  [[[0 1 2] [1 2 0] [2 0 1]]
            N*  "Join with newlines.";  ["012
                                          120
                                          201"]

Результат друкується автоматично в кінці програми. (Зауважте, вміст стеку для останнього кроку технічно є змішаним масивом, що містить числа та символи нового рядка, а не рядок, що містить лише символи.)

Як варіант, 11 символів

З останнім доповненням ew(це новіше, ніж виклик - він повертає всі перекриваються підрядки заданої довжини), можна було б зробити 11 байт:

l~,2*))ewN*

Ось як це працює:

l~           "Read and eval input."; [3]
  ,          "Get range.";           [[0 1 2]]
   2*        "Repeat twice.";        [[0 1 2 0 1 2]]
     )       "Pop last.";            [[0 1 2 0 1] 2]
      )      "Increment.";           [[0 1 2 0 1] 3]
       ew    "Get substrings.";      [[[0 1 2] [1 2 0] [2 0 1]]
         N*  "Join with newlines.";  ["012
                                       120
                                       201"]

Альтернативні 14 байт: l~_,\{_(+N\}*;. Цікаво, чи зможемо ми краще зробити це з цим .
Sp3000

Так, але це, по суті, відповідь Петрової відповіді, і я подумав, що краще запропонувати інший підхід. ewможе спрацювати, але це новіше, ніж виклик.
Мартін Ендер


0

Excel VBA, 77 байт

Функція негайного вікна анонімного VBE, яка приймає введення, як ціле число, n, з діапазону [A1]та виводить у діапазон A2.Resize(n,n).

[A2:IU255]="=IF(MAX(ROW()-1,COLUMN())-1<$A$1,MOD(ROW()+COLUMN()-3,$A$1),"""")

0

Perl 6 , 23 байти

{.rotate(.all).put}o|^*

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

Блок анонімного коду, який приймає число і друкує матрицю у заданому форматі з пробілами. Якщо ми можемо щось замість цього повернути, тоді його .putможна буде видалити.

Пояснення:

                   o|^*    # Transform the input into the range 0..input-1
{                 }        # And pass it into the function
 .rotate                   # Rotate the range by
        (.all)             # Each of the range
              .put         # And print each of them separated by spaces

0

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

NθEθ⪫Eθ﹪⁺ιλθ 

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

Nθ              Input `n` as a number into variable
   θ            `n`
  E             Map over implicit range
      θ         `n`
     E          Map over implicit range
         ι      Current row
        ⁺       Plus
          λ     Current column
       ﹪        Modulo
           θ    `n`
    ⪫           Cast row to string and join with spaces
                Implicitly print each row on its own line

0

APL (NARS), 15 символів, 30 байт

{⊃{⍵⌽k}¨k←0..⍵}

тест:

  f←{⊃{⍵⌽k}¨k←0..⍵}
  f 4
0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3
  f 3
0 1 2 3
1 2 3 0
2 3 0 1
3 0 1 2
  f 2
0 1 2
1 2 0
2 0 1
  f 1
0 1
1 0
  f 0
0 

тут мова не потребує коментарів ...




0

Четвертий (gforth) , 53 байти

: f dup 0 do cr dup 0 do i j + over mod . loop loop ;

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

Пояснення

Вкладений цикл, який видає новий рядок кожні n чисел

Пояснення коду

: f             \ start new word definition
  dup 0 do      \ set loop parameters and loop from 0 to n-1
    cr          \ output a newline
    dup 0 do    \ loop from 0 to n-1 again
      i j +     \ get the sum of the row and column number
      over mod  \ modulo with n
      .         \ print (with space)
    loop        \ end inner loop
  loop          \ end outer loop
;               \ end word definition
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.