9
\$\begingroup\$

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
\$\endgroup\$

24 Answers 24

10
\$\begingroup\$

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
\$\endgroup\$
  • 1
    \$\begingroup\$ Can you do ⊢|⍳∘.+⍳, or did trains not work in the July 2014 version of ngn? \$\endgroup\$ – lirtosiast Dec 20 '15 at 2:12
3
\$\begingroup\$

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}/
\$\endgroup\$
  • \$\begingroup\$ Very nice job on these! \$\endgroup\$ – Ryan Jul 25 '14 at 14:30
3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ That *R,= is an odd construct... Does it only serve to convert range's output into a tuple? \$\endgroup\$ – Jonathan Frech Nov 12 '17 at 20:32
  • \$\begingroup\$ Can you explain the Python 3 code please? I haven't seen use of *R \$\endgroup\$ – tarit goswami Sep 16 '18 at 13:12
  • \$\begingroup\$ @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. \$\endgroup\$ – Jonathan Frech Jan 12 at 13:16
3
\$\begingroup\$

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]]  
\$\endgroup\$
  • 1
    \$\begingroup\$ 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. :) \$\endgroup\$ – Kevin Cruijssen Jan 14 at 8:22
  • \$\begingroup\$ @KevinCruijssen Thanks! It seems like I forgot to find a way to take advantage of implicit input. \$\endgroup\$ – Wisław Jan 14 at 9:27
2
\$\begingroup\$

Jelly, 4

Ḷṙ`G

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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]]])
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ You should update your answer to |+/~@i. , which should be acceptable by the standard rules here. \$\endgroup\$ – Jonah Jan 19 at 3:27
1
\$\begingroup\$

Octave, 23

@(n)mod((r=0:n-1)'+r,n)
\$\endgroup\$
1
\$\begingroup\$

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]
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Sp3000 Apr 21 '15 at 22:21
1
\$\begingroup\$

Matlab (28)

k=exp(0:n-1)
mod(log(k'*k),n)
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Pari/GP, 26 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Who initialized x,y to what? \$\endgroup\$ – RosLuP Jan 14 at 20:37
  • \$\begingroup\$ @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. \$\endgroup\$ – alephalpha Jan 15 at 2:44
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 9 bytes \$\endgroup\$ – Jo King Jan 12 at 14:02
  • \$\begingroup\$ @JoKing that's clever! Perhaps you could use q to remove the duplication? \$\endgroup\$ – maxb Jan 12 at 23:05
  • \$\begingroup\$ 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. \$\endgroup\$ – maxb Jan 12 at 23:14
  • \$\begingroup\$ Since the separator is optional 8 bytes should work \$\endgroup\$ – Jo King Jan 13 at 3:51
0
\$\begingroup\$

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);}}
\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ Nice! Although spaces between elements were not necessary, it can be helpful when we have elements of value >= 10 (i.e. when n >= 11). \$\endgroup\$ – Ryan Jul 24 '14 at 19:33
  • \$\begingroup\$ Can you please exlain your code? To me reading golfscript is worse than reading someone else's regex. (almost=) \$\endgroup\$ – flawr Jul 24 '14 at 19:49
  • \$\begingroup\$ @flawr: Hah sure, it's quite straightforward \$\endgroup\$ – Claudiu Jul 24 '14 at 20:12
0
\$\begingroup\$

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"]
\$\endgroup\$
  • \$\begingroup\$ Alternative 14 bytes: l~_,\{_(+N\}*;. I wonder if we can do better with this though. \$\endgroup\$ – Sp3000 Apr 20 '15 at 5:04
  • \$\begingroup\$ 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. \$\endgroup\$ – Martin Ender Apr 20 '15 at 11:47
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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),"""")
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.