Generate the group table for Z_n

9

2

Groups are a widely used structure in Mathematics, and have applications in Computer Science. This code challenge is about the fewest # of characters to create a group table for the additive group Zn.

How the table is constructed: For Zn, the elements are {0, 1, 2, ..., n-1}. The table will have n rows and n columns. For the ij-th entry of the table, the value is i+j mod n. For example, in Z3, the 1-2nd entry (2nd row, 3rd column if you count the starting row/column as 1) is (1+2)%3 = 0 (see sample output).

Input: a positive integer, n

Output: a table that is a textual presentation of Zn, constructed as described above, and displayed as shown below in the sample outputs. Spaces are optional

Sample input: 3

Sample output:

0 1 2
1 2 0
2 0 1

Sample input: 5

Sample output:

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

Ryan

Posted 2014-07-24T19:12:15.180

Reputation: 527

3Since the separator is optional, will there be an input above 10? – Jo King – 2019-01-13T03:51:51.147

Answers

10

APL (10)

(Assuming ⎕IO=0. It works on ngn/apl by default, other APLs tend to need an ⎕IO←0 first.)

{⍵|∘.+⍨⍳⍵}

Explanation:

  • ⍳⍵: the numbers [0..⍵)
  • ∘.+⍨: create a sum table
  • ⍵|: numbers in the table mod

marinus

Posted 2014-07-24T19:12:15.180

Reputation: 30 224

1Can you do ⊢|⍳∘.+⍳, or did trains not work in the July 2014 version of ngn? – lirtosiast – 2015-12-20T02:12:45.797

3

05AB1E, 10 8 bytes

ݨDδ+I%»

Try it online!

Explanation

         # 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       

Previous answer: 10 bytes

ݨDvDðý,À}

Try it online!

My first try at golfing in 05AB1E.

Explanation of previous answer

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

Wisław

Posted 2014-07-24T19:12:15.180

Reputation: 554

1

Nice first answer, and welcome! I have the feeling it can be shorter, but here are two 9-byte alternatives: FݨN._ðý, and ݨsGDÀ})» Feel free to ask any questions in the 05AB1E chat, and take a look at the 05AB1E tip page if you haven't yet. :)

– Kevin Cruijssen – 2019-01-14T08:22:23.617

@KevinCruijssen Thanks! It seems like I forgot to find a way to take advantage of implicit input. – Wisław – 2019-01-14T09:27:06.410

3

GolfScript (13 chars)

I understand from your comment on Claudiu's answer that whitespace between the elements of a row is not necessary. On that understanding:

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

Online demo

Dissection:

~        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

If whitespace is necessary, for 20 chars:

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

Peter Taylor

Posted 2014-07-24T19:12:15.180

Reputation: 41 901

Very nice job on these! – Ryan – 2014-07-25T14:30:44.103

3

Python 2, 66 bytes

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

Rotates the list by popping and re-appending.

Python 3, 53 bytes

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

Uses the same method as @mbomb007, but abusing print as a function.

Sp3000

Posted 2014-07-24T19:12:15.180

Reputation: 58 729

That *R,= is an odd construct... Does it only serve to convert range's output into a tuple? – Jonathan Frech – 2017-11-12T20:32:23.920

Can you explain the Python 3 code please? I haven't seen use of *R – tarit goswami – 2018-09-16T13:12:14.833

@taritgoswami It is degenerated unpacking; range is an iterable object which one can unpack and re-pack, collecting everything in R. It should be equivalent to R=list(range(n)), the former being more concise. – Jonathan Frech – 2019-01-12T13:16:17.760

2

Jelly, 4

Ḷṙ`G

Try it online!

Erik the Outgolfer

Posted 2014-07-24T19:12:15.180

Reputation: 38 134

1

Pari/GP, 26 bytes

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

Try it online!

alephalpha

Posted 2014-07-24T19:12:15.180

Reputation: 23 988

Who initialized x,y to what? – RosLuP – 2019-01-14T20:37:11.473

@RosLuP matrix(m,n,X,Y,expr) generates an mXn matrix of expression expr, the row variable X going from 1 to m and the column variable Y going from 1 to n. – alephalpha – 2019-01-15T02:44:29.117

1

MathGolf, 10 8 bytes

r░y\Åo╫;

Try it online!

-2 bytes thanks to Jo King

Explanation

I'll use example input 3 for the explanation

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)

You could also do r░y\(Åo╫, which decreases the number of loops by 1 and skips the discard after the loop.

maxb

Posted 2014-07-24T19:12:15.180

Reputation: 5 754

9 bytes – Jo King – 2019-01-12T14:02:11.513

@JoKing that's clever! Perhaps you could use q to remove the duplication? – maxb – 2019-01-12T23:05:40.490

I meant o. Though the best I could figure out that way was this. It could be 10 bytes too, but I'm on mobile.

– maxb – 2019-01-12T23:14:28.300

Since the separator is optional 8 bytes should work

– Jo King – 2019-01-13T03:51:02.517

1

x86-64 Machine Code (Linux), 80 64 bytes

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

I was hoping for this solution to be just a few bytes shorter to be able to beat some of the other submissions on this post. There's a possibility if I use some of the 32 or 16 bit versions of the registers I could shave a few bytes off. Converting a lot of the registers to the 32 bit addressing versions saved 16 bytes.

Basically this function is called from a C/C++ program which passed n through rdi, and a pointer to an allocation through rsi. The pointer that rsi has is actually 1 byte from the end of the allocation, since the table is built backwards. This makes it easier to convert an integer to printable ASCII characters (done by taking some number x mod 10 and converting the result to ASII).

To see the C++ wrapper code and comments on the assembly, check out my repo.

davey

Posted 2014-07-24T19:12:15.180

Reputation: 321

1

Matlab (28)

k=exp(0:n-1)
mod(log(k'*k),n)

flawr

Posted 2014-07-24T19:12:15.180

Reputation: 40 560

1

Pyth, 16

JVQXQjdJ=J+tJ]hJ

Prints the table with proper whitespace.

./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

Explanation:

                   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

Posted 2014-07-24T19:12:15.180

Reputation: 39 268

1

J, 20

Reading from stdin and producing a 2D array (which renders the same as the sample in the question).

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

If a function taking a string suffices, (|+/~@i.)@".. If a function taking an integer suffices, |+/~@i. should be sufficient.

Explanation: f g in J (for functions f, g) denotes a "hook", which is a composite function that runs the input through g (a unary function) and then the input and the result of g through f (a binary function). The answer is a fork with components | (modulus) and +/~@i.. The latter part is "table-of sums composed-with list-of-indices-upto" (i. is a bit like range in Python).

FireFly

Posted 2014-07-24T19:12:15.180

Reputation: 7 107

You should update your answer to |+/~@i. , which should be acceptable by the standard rules here. – Jonah – 2019-01-19T03:27:12.380

1

Octave, 23

@(n)mod((r=0:n-1)'+r,n)

alephalpha

Posted 2014-07-24T19:12:15.180

Reputation: 23 988

1

Python 2, 67

Try them both here

I use list splitting to "rotate" the list n times, printing it each time. (68 chars)

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

I managed to get it one character shorter than the above with a weird trick. (67 chars)

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

mbomb007

Posted 2014-07-24T19:12:15.180

Reputation: 21 944

Seems like this method is still shorter in Python 3: def f(n):*R,=range(n);[print(*R[i:]+R[:i])for i in R]. I didn't think the splat would actually work without parens. – Sp3000 – 2015-04-21T22:21:01.743

0

MATL, 6 bytes

:q&+G\

Try it online!

    # 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

Posted 2014-07-24T19:12:15.180

Reputation: 21 077

0

Excel VBA, 77 Bytes

Anonymous VBE immediate window function that takes input, as integer,n, from range [A1] and outputs to the range A2.Resize(n,n).

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

Taylor Scott

Posted 2014-07-24T19:12:15.180

Reputation: 6 709

0

Perl 6, 23 bytes

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

Try it online!

Anonymous code block that takes a number and prints the matrix in the given format with spaces. If we can just return something instead, then the .put can be removed.

Explanation:

                   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

Jo King

Posted 2014-07-24T19:12:15.180

Reputation: 38 234

0

APL(NARS), 15 chars, 30 bytes

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

test:

  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 

here the language has need no comments...

RosLuP

Posted 2014-07-24T19:12:15.180

Reputation: 3 036

0

Charcoal, 13 bytes

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

Try it online! Link is to verbose version of code. Note: Trailing space. Explanation:

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

Neil

Posted 2014-07-24T19:12:15.180

Reputation: 95 035

0

Japt -R, 5 bytes

ÆZéXn

Try it

If using a comma as a separator isn't valid then add a byte for no separator:

ÆZ¬éXn

Try it

Or 2 bytes to use a space:

ÆZéXn)¸

Try it

Shaggy

Posted 2014-07-24T19:12:15.180

Reputation: 24 623

0

R, 37 bytes

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

Creates a vector from 0 to n-1, and sequentially adds 1, then 2... then n, and modulates the matrix by the length of the vector, which is n.

Try it online!

Sumner18

Posted 2014-07-24T19:12:15.180

Reputation: 1 334

0

Forth (gforth), 53 bytes

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

Try it online!

Explanation

Nested loop that outputs a newline every n numbers

Code Explanation

: 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

Posted 2014-07-24T19:12:15.180

Reputation: 1 361

0

Golfscript, 20 characters

A terribly lazy job.

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

Run it here. (First line is to simulate stdin).

Explanation:

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

When the program ends, the stack contains each of the arrays with newlines between them. The interpreter outputs what's left on the stack, giving the desired result.

Claudiu

Posted 2014-07-24T19:12:15.180

Reputation: 3 870

1Nice! Although spaces between elements were not necessary, it can be helpful when we have elements of value >= 10 (i.e. when n >= 11). – Ryan – 2014-07-24T19:33:52.837

Can you please exlain your code? To me reading golfscript is worse than reading someone else's regex. (almost=) – flawr – 2014-07-24T19:49:24.437

@flawr: Hah sure, it's quite straightforward – Claudiu – 2014-07-24T20:12:21.473

0

C - 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

Posted 2014-07-24T19:12:15.180

Reputation: 339

0

CJam, 14 characters

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

Test it here.

Explanation

The idea is to repeat the string from 0 to N-1, but split it into blocks of N+1. This mismatch shifts the row to the left each time. Lastly, we need to get rid of the extraneous character and join everything with newlines.

Here is the exploded code, together with the stack contents for input 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"]

The result is printed automatically at the end of the program. (Note, the stack contents for the final step are technically a mixed array containing numbers and newline characters, not a string containing only characters.)

Alternatively, 11 characters

With the recent addition ew (this is newer than the challenge - it returns all overlapping substrings of given length), one could do 11 bytes:

l~,2*))ewN*

Here is how this one works:

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"]

Martin Ender

Posted 2014-07-24T19:12:15.180

Reputation: 184 808

Alternative 14 bytes: l~_,\{_(+N\}*;. I wonder if we can do better with this though.

– Sp3000 – 2015-04-20T05:04:17.867

Yes but that's essentially a port of Peter's answer, and I thought I'd rather present a different approach. ew might work but it's newer than the challenge. – Martin Ender – 2015-04-20T11:47:06.007