Draw me the (weird) unit circle!

20

2

Introduction

You may know and love your normal unit circle. But mathematicans are crazy and thus they have abstracted the concept to any point that satisfies x*x+y*y=1. Because Cryptographers1 are also weird, they love finite fields and sometimes finite rings (it is not like they have much choice though), so let's combine this!

The Challenge

Input

A positive integer larger than one in your favorite encoding. Let's call this number n.

Output

You will output the "picture" (which consists of n times n characters) of the unit circle modulo the input integer as ASCII-Art using "X" (upper-case latin X) and " " (a space). Trailing spaces and newlines are allowed.

More Details

You have to span a coordinate system from bottom-left to top-right. Whenever a point fulfills the circle equation, place an X at the position, otherwise place a space.

The condition for a point to be considered part of the circle border is:
mod(x*x+y*y,n)==1.

Here a quick illustration of the coordinate-system:

(0,4)(1,4)(2,4)(3,4)(4,4)
(0,3)(1,3)(2,3)(3,3)(4,3)
(0,2)(1,2)(2,2)(3,2)(4,2)
(0,1)(1,1)(2,1)(3,1)(4,1)
(0,0)(1,0)(2,0)(3,0)(4,0)

If it helps you, you may also invert the direction of any of the axes, but the examples assume this orientation.

Who wins?

This is so the shortest code in byte wins! Only the default I/O methods are allowed and all standard loopholes are banned.

Examples

Input: 2

X 
 X

Input: 3

X  
X  
 XX

Input: 5

X    


X    
 X  X

Input: 7

X      
  X  X 


  X  X 
X      
 X    X

Input: 11

X          

     XX    

   X    X  
   X    X  

     XX    

X          
 X        X

Input: 42

X                                         
         X                       X        


            X                 X           
       X                           X      
      X                             X     
                     X                    
  X             X         X             X 


     X             X   X             X    
X                                         
               X           X              
              X             X             
         X                       X        


            X                 X           
                     X                    
        X           X X           X       
                     X                    
            X                 X           


         X                       X        
              X             X             
               X           X              
X                                         
     X             X   X             X    


  X             X         X             X 
                     X                    
      X                             X     
       X                           X      
            X                 X           


         X                       X        
X                                         
 X           X               X           X

1 I suggest you take a look at my profile if you're wondering here.

SEJPM

Posted 2017-04-01T18:18:43.230

Reputation: 3 203

Looks much better if you use the domain [0,n] in my opinion. Here is an example with input 42.

– R. Kap – 2017-04-01T19:11:22.813

By "standard I/O" do you mean default I/O methods, or do you mean actual STDIN/STDOUT? I'm assuming the former, but I think someone below has interpreted it as the latter. – Ørjan Johansen – 2017-04-02T00:02:02.583

@ØrjanJohansen indeed the former. – SEJPM – 2017-04-02T00:07:58.553

Are preceding newlines allowed? – fergusq – 2017-04-02T09:13:24.917

@fergusq as they would (drastically) alter the output figure in a visible way, no. – SEJPM – 2017-04-02T09:23:56.897

Answers

6

Bash + GNU Utilities, 59

x={0..$[$1-1]}d*
eval echo $x$x+$1%1-0r^56*32+P|dc|fold -$1

Input n given as a command-line parameter. The y-axis is inverted.

Try it online.

Digital Trauma

Posted 2017-04-01T18:18:43.230

Reputation: 64 644

4

Octave, 45 44 bytes

@(n)[(mod((x=(0:n-1).^2)+x',n)==1)*56+32,'']

Try it online!

flawr

Posted 2017-04-01T18:18:43.230

Reputation: 40 560

This also works: @(n)[(mod((x=(0:n-1).^2)+x',n)==1)*88,'']. In certain systems Octave treats character 0 as a space – Luis Mendo – 2017-04-02T02:35:39.943

3

Mathematica, 56 48 bytes

Edit: Thanks to Greg Martin and Martin Ender for saving 8 bytes.

Grid@Array[If[Mod[#^2+#2^2,x]==1,X]&,{x=#,#},0]&

Original solution:

Grid@Table[If[Tr[{i-1,j-1}^2]~Mod~#==1,X,],{i,#},{j,#}]&

ngenisis

Posted 2017-04-01T18:18:43.230

Reputation: 4 600

Amusing remark: you don't need the comma after X :) – Greg Martin – 2017-04-01T19:31:17.610

1I think you're better off with Array and Norm: Grid@Array[If[Mod[Norm@{##}^2,x]==1,X]&,{x=#,#},0]& – Martin Ender – 2017-04-01T19:34:52.150

2Still overthinking it... #^2+#2^2 is shortest. – Martin Ender – 2017-04-01T19:45:27.273

@GregMartin So if the first argument to If is neither True or False, you need the fourth argument or it remains unevaluated, but If[False,_] returns Null. Weird. – ngenisis – 2017-04-03T19:00:29.243

@MartinEnder I initially tried Array but didn't think to set the argument to a variable. – ngenisis – 2017-04-03T19:01:19.983

3

Haskell, 68 bytes

f n|r<-[0..n-1]=unlines[[last$' ':['X'|mod(x*x+y*y)n==1]|y<-r]|x<-r]

Try it online! The y-axis is flipped. Usage: f 42 returns a newline delimited string.

This is a nested list comprehension where both x and y are drawn from the range [0..n-1]. last$' ':['X'|mod(x*x+y*y)n==1] is a shorter form of if mod(x*x+y*y)n==1 then 'X' else ' '. The list comprehension evaluates to a list of strings which is turned into a single newline separated string by unlines.

Laikoni

Posted 2017-04-01T18:18:43.230

Reputation: 23 676

2

CJam, 23 bytes

ri:X,2f#_ff{+X%(S'X?}N*

Try it online!

ri:X    e# Read input, convert to integer, store in X.
,       e# Turn into range [0 1 ... X-1].
2f#     e# Square each value in the range.
_ff{    e# 2D map over all pairs from that list.
  +     e#   Add the two values in the current pair.
  X%    e#   Take the sum modulo X.
  (     e#   Decrement, so that x^2+y^2==1 becomes 0 (falsy) and everything
        e#   else becomes truthy.
  S'X?  e#   Select space of 'X' accordingly.
}
N*      e# Join rows with linefeeds.

Martin Ender

Posted 2017-04-01T18:18:43.230

Reputation: 184 808

2

JavaScript (ES6), 81 bytes

f=
n=>[...Array(n)].map((_,x,a)=>a.map((_,y)=>(x*x+y*y)%n-1?` `:`X`).join``).join`
`
<input type=number oninput=o.textContent=f(+this.value)><pre id=o>

The Y-axis is the reverse of the OP.

Neil

Posted 2017-04-01T18:18:43.230

Reputation: 95 035

2

Röda, 74 bytes

f n{seq n-1,0|{|y|seq 0,n-1|{|x|["X"]if[(x^2+y^2)%n=1]else[" "]}_;["
"]}_}

Try it online!

Ungolfed:

function f(n) {
    seq(n-1, 0) | for y do
        seq(0, n-1) | for x do
            if [ (x^2 + y^2) % n = 1 ] do
                push("X")
            else
                push(" ")
            done
        done
        print("")
    done
}

fergusq

Posted 2017-04-01T18:18:43.230

Reputation: 4 867

2

Python 3, 87 83 bytes

lambda n:"\n".join("".join(" X"[(y*y+x*x)%n==1]for x in range(n))for y in range(n))

Try it online!

The y-axis is inverted

ovs

Posted 2017-04-01T18:18:43.230

Reputation: 21 408

2

Jelly, 14 13 bytes

R²+þ`%=1ị⁾X Y

The x-axis is inverted.

Try it online!

How it works

R²+þ`%=1ị⁾X Y  Main link. Argument: n

R              Range; yield [1, ..., n].
 ²             Square; yield [1², ..., n²].
  +þ`          Self table addition; compute x+y for all x and y in [1², ..., n²],
               grouping by the values of y.
     %         Take all sums modulo n.
      =1       Compare them with 1, yielding 1 or 0.
        ị⁾X    Index into "X ".
            Y  Separate by linefeeds.

Dennis

Posted 2017-04-01T18:18:43.230

Reputation: 196 637

1

dc, 79 bytes

?dsRsQ[88P]sl[32P]sH[0sM[lM2^lR2^+lQ%d1=l1!=HlM1+dsMlQ>c]dscx10PlR1-dsR0<S]dsSx

The y-axis is inverted whereas the x-axis is not.

Try it online!

R. Kap

Posted 2017-04-01T18:18:43.230

Reputation: 4 730

1

Python 3, (102 98 95 bytes)

y-axis inverted

n=int(input());r=range(n);p=print
for i in r:
 for j in r:p(end=' 'if(i*i+j*j)%n-1else'X')
 p()

Try it online!

  • saved 4 bytes: omitted variable c in c=' 'if(ii+jj)%n-1else'X'
  • saved 3 bytes: Thanks to ovs (modified print statement)

officialaimm

Posted 2017-04-01T18:18:43.230

Reputation: 2 739

1p(end=' 'if(i*i+j*j)%n-1else'X') for 95 bytes – ovs – 2017-04-02T10:15:49.900

1

MATL, 13 bytes

:qU&+G\1=88*c

Origin is at top left. So the output is flipped upside down compared with the examples in the challenge.

Try at MATL online!

Explanation

:      % Input n implicitly. Push [1 2 ... n]
q      % Subtract one (element-wise)
U      % Square (element-wise)
&+     % Matrix of pairwise sums
G      % Push n
\      % Modulo
1=     % Equal to 1? (element-wise)
88*    % Multiply by 88 (ASCII code of 'X')
c      % Convert to char. Char 0 will be displayed as a space
       % Display implicitly

Luis Mendo

Posted 2017-04-01T18:18:43.230

Reputation: 87 464

1

Lithp, 125 bytes

#N::((join(map(seq(- N 1)0)(scope #Y::((join(map(seq 0(- N 1))(scope #X::
((?(== 1(@(+(* X X)(* Y Y))N))"X" " "))))""))))"\n")

Linebreak for readability.

Try it online!

Not the shortest. I think I need some sort of shorthand module. See the Try it Online link for further explanation, ungolfed version, and some tests. For best results, expand the output window to see more.

Andrakis

Posted 2017-04-01T18:18:43.230

Reputation: 361

1

Python 3, 82 bytes

f=lambda n,k=0:k<n>f(n,k+1)!=print(''.join(' X'[(k*k+j*j)%n==1]for j in range(n)))

Try it online!

Dennis

Posted 2017-04-01T18:18:43.230

Reputation: 196 637

1

GNU APL, 41 chars, 59 bytes

Reads an integer and displays the circle.

N←⎕◊⌽{(⍵+1)⊃' ' 'X'}¨{1=(N|(+/⍵*2))}¨⍳N N

Ungolfed

N←⎕
⌽                           ⍝ flip the X axis so 0,0 is bottom left
{
    (⍵+1) ⊃ ' ' 'X'         ⍝ substitute space for 0, X for 1
} ¨ {
    1=(N|(+/⍵*2))           ⍝ mod(x*x+y*y, 1)==1
} ¨ ⍳N N                    ⍝ generate an NxN grid of coordinates

Megashroom

Posted 2017-04-01T18:18:43.230

Reputation: 11

0

Haskell, 115 bytes

n#(a,b)|mod(a*a+b*b)n==1='X'|1>0=' '
m n=map(n#)<$>zipWith(zipWith(,))(replicate n[0..n-1])(replicate n<$>[0..n-1])

The y axis is inverted.

Try it online!

All those parentheses are kind of annoying me...

Explanation

n#(a,b)|mod(a*a+b*b)n==1='X'|1>0=' '
n#(a,b)                                 --Operator #, takes a number n and a tuple (a,b)
       |mod(a*a+b*b)n==1                --Test if the mod equals 1
                        ='X'            --If so, return 'X'
                            |1>0=' '    --Otherwise, return ' '

m n=map(n#)<$>zipWith(zipWith(,))(replicate n[0..n-1])(replicate n<$>[0..n-1])
m n=                                                                           --Make a new function m with argument n
                                 (replicate n[0..n-1])                         --Make a list of [[0,1,2,3..n-1],[0,1,2,3..n-1],(n times)]
                                                      (replicate n<$>[0..n-1]) --Make a list of [[0,0,0(n times)],[1,1,1(n times)]..[n-1,n-1,n-1(n times)]
              zipWith(zipWith(,))                                              --Combine them into a list of list of tuples
    map(n#)<$>                                                                 --Apply the # operator to every tuple in the list with the argument n

Generic Display Name

Posted 2017-04-01T18:18:43.230

Reputation: 365

You can replace the last map with a <$>, right? – k_g – 2017-04-01T23:20:28.703

Unless I'm misinterpreting the question rules, I don't think you need all that I/O - golfing I/O on PPCG has special defaults to allow as many languages as possible to participate. For example, your main function can take an integer argument and return a string.

– Ørjan Johansen – 2017-04-02T00:07:01.467

@k_g yes thank you – Generic Display Name – 2017-04-02T00:43:25.250

@ØrjanJohansen duly noted :) – Generic Display Name – 2017-04-02T00:44:39.383

0

J, 20 bytes

' x'{~1=[|+/~@:*:@i.

Try it online!

Leaky Nun

Posted 2017-04-01T18:18:43.230

Reputation: 45 011

0

GolfScript, 34 bytes

~:c,{.*}%:a{:b;a{b+c%1=' x'=}%}%n*

Try it online!

I really don't like using variables...

Leaky Nun

Posted 2017-04-01T18:18:43.230

Reputation: 45 011