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

9

Группы являются широко используемой структурой в математике и имеют приложения в области компьютерных наук. Эта проблема кода заключается в наименьшем количестве символов для создания таблицы групп для аддитивной группы Z n .

Как строится таблица: для Z n элементами являются {0, 1, 2, ..., n-1}. Таблица будет иметь n строк и n столбцов. Для i-й записи таблицы это значение равно 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?
Джо Кинг,
@JoKing на основе codegolf.stackexchange.com/questions/35038/... Я думаю да
qwr

Ответы:

10

APL (10)

(Предполагается ⎕IO=0. По умолчанию он работает в ngn / apl , другие APL, как правило, нуждаются в ⎕IO←0первом.)

{⍵|∘.+⍨⍳⍵}

Объяснение:

  • ⍳⍵: числа [0..⍵)
  • ∘.+⍨: создать таблицу сумм
  • ⍵|: цифры в таблице mod
Мэринус
источник
1
Можете ли вы это сделать ⊢|⍳∘.+⍳, или поезда не работали в версии ngn от июля 2014 года?
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как функция.

Sp3000
источник
Это *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

Pyth , 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]]])
isaacg
источник
1

J, 20

Чтение из стандартного ввода и создание двумерного массива (который отображает образец в вопросе).

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

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

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

Светляк
источник
Вы должны обновить свой ответ на |+/~@i., который должен быть приемлемым по стандартным правилам здесь.
Иона
1

Python 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]
mbomb007
источник
Похоже , этот метод еще короче в 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 ++ и комментарии к сборке, посмотрите мой репозиторий .

Davey
источник
1

Пари / ГП , 26 байт

n->matrix(n,n,x,y,x+y-2)%n

Попробуйте онлайн!

alephalpha
источник
Кто инициализировал x, y для чего?
РосЛюП
@RosLuP matrix(m,n,X,Y,expr)генерирует mXnматрицу выражений expr, переменная строки Xидет от 1к mи переменная столбца Yидет от 1к n.
алефальфа
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 и пропускает сброс после цикла.

maxb
источник
9 байтов
Джо Кинг
@ Шучу, это умно! Возможно, вы могли бы использовать, qчтобы удалить дублирование?
maxb
Я имел в виду o. Хотя лучшее, что я мог понять таким образом, было это . Это тоже может быть 10 байт, но я на мобильном.
максимум
Поскольку разделитель является необязательным, 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);}}
LemonBoy
источник
0

Golfscript, 20 символов

Ужасно ленивая работа.

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

Запустите это здесь . (Первая строка для имитации стандартного ввода).

Пояснение :

~                     # 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

MATL , 6 байтов

:q&+G\

Попробуйте онлайн!

    # implicit input, say n = 3
:   # range
    # stack: [1, 2, 3]
q   # decrement
    # stack: [0, 1, 2]
&+  # sum with itself and transpose with broadcast
    # stack:
    # [0 1 2
    #  1 2 3
    #  2 3 4]
G   # paste input
    # stack: [0 1 2; 1 2 3; 2 3 4], 3
\   # elementwise modulo
    # implicit output with spaces
Giuseppe
источник
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 

здесь язык не нуждается в комментариях ...

RosLuP
источник
0

R , 37 байт

sapply(x<-1:scan()-1,`+`,x)%%sum(x|1)

Создает вектор от 0 до n-1 и последовательно добавляет 1, затем 2 ..., затем n и модулирует матрицу по длине вектора, равной n.

Попробуйте онлайн!

Sumner18
источник
0

Forth (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
reffu
источник