Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Draw lines between every pair of distinct points for n points arranged in a circle, producing something like the below result. Shortest code (in bytes) wins! Your lines don't have to be transparent, but it looks better that way. The output must be a vector graphic, or be an image at least 600 pixels by 600 pixels (either saved to a file or displayed on the screen). To complete the challenge you must draw at least 20.

enter image description here

share|improve this question
6  
It'd be cool if you had to take in a number n and draw lines for n points. – Yodle 13 hours ago
2  
I second this idea. Change it before someone gets the first answer. – shooqie 13 hours ago
2  
@shooqie Then the title wouldn't make sense though, unless that can be edited by the mods? – Yodle 13 hours ago
2  
I don't think changing 37 to an arbitrary n would add much to the challenge as I expect most solutions to work with any number anyway, especially because 37 is odd and hence there are no mirror symmetries. – Laikoni 13 hours ago
3  
Do we take n as input or just pick an arbitrary n over 20? – Easterly Irk 13 hours ago

15 Answers 15

Mathematica, 13 bytes

CompleteGraph

lined-up-circle-37-points

Looks like this only fails to give a circular embedding for n=4, but the question states n>=20

share|improve this answer
1  
...and there was me trying to find the correct way to make a function to take n (I had the answer ready from the fixed 37) :( – Jonathan Allan 13 hours ago
    
Why is that a built in?! That language is crazy good at graphing. – carusocomputing 12 hours ago
3  
@carusocomputing This function has nothing to do with "graphing" in the sense of plotting. Mathematica is also very good for graph theory problems and having a built-in to generate a complete graph seems like the first thing I would add if I added support for graphs to my language. The only reason this function happens to be useful for this challenge is that complete graphs are by default rendered with all vertices arranged in a circle. – Martin Ender 12 hours ago
1  
If you're gonna support graphs, you better have a built in complete graph function, IMO. – ngenisis 12 hours ago
    
@carusocomputing Welcome to Mathematica, the language that has a built-in for every existing function. :-P – Alex L. 5 hours ago

MATL, 16 14 bytes

As I'm not terribly fluent with MATL I expect that this is somewhat more golfable. (Would be nice to at least beat Mathematica :-) I.e. the the flip w is not optimal, it could probably be avoided...

:G/4*Jw^2Z^!XG

Test it Online! (Thanks @Suever for this service, thanks @DrMcMoylex for -2 bytes.)

Explanation (for N=3):

  :               Generate Range 1:input:       [1,2,3]
   G/             Divide By the first input     [0.333,0.666,1]
     4*           Multiply by 4                 [1.33,2.66,4.0]
       Jw^        i ^ (the result so far)       [-0.49+ 0.86i,-.5-0.86i,1.00]
                  (This results in a list of the n-th roots of unity)
          2Z^     Take the cartesian product with itself (i.e. generate all 2-tuples of those points)
             !XG  Transpose and plot

It is worth noting that for generating the N-th roots of unity you can use the formula exp(2*pi*i*k/N) for k=1,2,3,...,N. But since exp(pi*i/2) = i you could also write i^(4*k/N) for k=1,2,3,...,N which is what I'm doing here.

share|improve this answer
    
You can change XH:H to :G – DrMcMoylex 9 hours ago
    
Aaah I forgot about G thank you very much! – flawr 9 hours ago
    
+1 for the multicolor. – darrylyeo 2 hours ago

Java, 346 338 322 301 Bytes

This solution works for all n>1, even though the original post didn't require that, it does.

My favorite is n=5, don't ask why, also, if you want a cooler GUI, use:

int a=Math.min(this.getHeight(),this.getWidth())/2;

In place of the hard-coded 300, it'll use the width or height of the frame as the diameter.

Saved 8 bytes thanks to Shooqie. Saved 21 bytes thanks to Geobits.

import java.awt.*;void m(final int n){new Frame(){public void paint(Graphics g){Point[]p=new Point[n];int a=300;for(int i=1;i<n+1;i++){p[i-1]=new Point(a+(int)(a*Math.cos(i*2*Math.PI/n)),a+(int)(a*Math.sin(i*2*Math.PI/n)));for(int j=0;j<i;j++){g.drawLine(p[i-1].x,p[i-1].y,p[j].x,p[j].y);}}}}.show();}

Output for n=37:

enter image description here

share|improve this answer
    
You can drop Frame x= and final (I think?) – shooqie 13 hours ago
    
@shooqie oops, Frame x was from another solution that involved a thread. You need the final though as it's an internal class reference to an external variable in the owning class. – carusocomputing 13 hours ago
    
It works just fine on my machine. BTW I think you can shave off some bytes by moving int declarations outside the for loops – shooqie 13 hours ago
    
@shooqie in Java 6 it's saying "Cannot refer to the non-final local variable n in an enclosing scope" at compile time. – carusocomputing 12 hours ago
    
It worked for me on Java 8, but after you edited your post I'm only getting white screen. – shooqie 12 hours ago

Mathematica, 42 bytes

Creates a set of 37 points arranged in a circle, and then draws lines between all possible subsets of two points. Someone posted a shorter answer that takes advantage of CompleteGraph, but I believe this is the shortest one aside from those relying on CompleteGraph.

Graphics@Line@Subsets[CirclePoints@37,{2}]

enter image description here

share|improve this answer
1  
There's no need to avoid drawing lines from a point to itself, so you could save 3 bytes by using Tuple. You also need to update this to accept arbitrary n, but conveniently that won't cost you any bytes. – ngenisis 11 hours ago
    
Meant to say Tuples – ngenisis 11 hours ago

Octave, 88 69 bytes

N=input('');t=0:2*pi/N:N;k=nchoosek(1:N,2)';line(cos(t)(k),sin(t)(k))

Output for N=37:

enter image description here

Output for N=19:

enter image description here

share|improve this answer
    
Oh, I didn't even notice that there was already another Octave answer:) – flawr 9 hours ago
    
Anyway, beat ya :-) – flawr 9 hours ago

HTML + JS (ES6), 34 + 177 164 162 = 196 bytes

Using the HTML5 Canvas API.

See it on CodePen.

f=n=>{with(Math)with(c.getContext`2d`)for(translate(S=300,S),O=n;O--;)for(rotate(a=PI*2/n),N=n;N--;)beginPath(stroke()),lineTo(0,S),lineTo(sin(a*N)*S,cos(a*N)*S)}


/* Demo */
f(20)
<canvas id=c width=600 height=600>

-13 bytes: Removed closePath(), moved stroke() inside beginPath()

-2 bytes: Defined variable a inside rotate()

share|improve this answer

Python 2, 258 235 229 Bytes

import itertools as T,math as M
from PIL import Image as I,ImageDraw as D
s=300
n=input()
t=2*M.pi/n
o=I.new('RGB',(s*2,)*2)
for x in T.combinations([(s*M.cos(t*i)+s,s*M.sin(t*i)+s)for i in range(n)],2):D.Draw(o).line(x)
o.show()

Output for n=37
n=37

share|improve this answer

Perl, 230 bytes

It uses the same formula as most languages that don't have convenient builtin for this challenge (even if I didn't look at them to find it, but that's a fairly easy to find formula). So not very interesting, but there are usually not a lot of Perl answers to this kind of challenges, so I just wanted to propose one.

$i=new Imager xsize=>700,ysize=>700;for$x(1..$_){for$y(1..$_){$i->line(color=>red,x1=>350+300*cos($a=2*pi*$x/$_),x2=>350+300*cos($b=2*pi*$y/$_),y1=>350+300*sin$a, y2=>350+300*sin$b)}}$i->write(file=>"t.png")

And you'll need -MImager (9 bytes), -MMath::Trig (providing pi, 13 bytes), and -n (1 byte) ==> + 23 bytes.

To run it :

perl -MImager -MMath::Trig -ne '$i=new Imager xsize=>700,ysize=>700;for$x(1..$_){for$y(1..$_){$i->line(color=>red,x1=>350+300*cos($a=2*pi*$x/$_),x2=>350+300*cos($b=2*pi*$y/$_),y1=>350+300*sin$a, y2=>350+300*sin$b)}}$i->write(file=>"t.png")' <<< 27

It will create a file named t.png which contains the image.

You'll need to install Imager though, but no worries, it's quite easy :

(echo y;echo) | perl -MCPAN -e 'install Imager'

(The echos will configure you cpan if you've never used it before. (actually that will only work if your perl is recent enough, I think for most of you it will be, and I'm sorry for the others!)).

And the more readable version (yes, it's fairly readable for a Perl script!) :

#!/usr/bin/perl -n
use Imager;
use Math::Trig;
$i=Imager->new(xsize=>700,ysize=>700);
for $x (1..$_){
    for $y (1..$_){
    $i->line(color=>red,x1=>350+300*cos($a=2*pi*$x/$_), x2=>350+300*cos($b=2*pi*$y/$_),
         y1=>350+300*sin($a), y2=>350+300*sin($b));
    }
}
$i->write(file=>"t.png");

enter image description here

share|improve this answer

PHP, 186 184 bytes

imagecolorallocate($i=imagecreate(601,601),~0,~0,~0);for(;$a<6;)for($b=$a+=$p=M_PI/10;$b;)imageline($i,(1+cos($a))*$r=300,$r+$r*sin($a),$r+$r*cos($b-=$p),$r+$r*sin($b),1);imagepng($i);

+14 bytes for parametrized n

imagecolorallocate($i=imagecreate(601,601),~0,~0,~0);for(;$a<$p=2*M_PI;)for($b=$a+=$q=$p/$argv[1];$b>0;)imageline($i,(1+cos($a))*$r=300,$r+$r*sin($a),$r+$r*cos($b-=$q),$r+$r*sin($b),1);imagepng($i);

writes the image to STDOUT

exact PI graph

Using exact PI/10 doesn´t cost a thing compared to .3142, because it reduces rounding errors: With .3142 I had to check $b>0; $b resulted in an indefinite loop - with PI/10 it does not.

The limit $a<6 is sufficiently exact for 20 points.

breakdown

// create image with white background
imagecolorallocate($i=imagecreate(601,601),~0,~0,~0);

// loop angle A from 0 to 2*PI
for(;$a<6;)
    // loop angle B from A down to 0
    for($b=$a+=$p=M_PI/10;$b;)  // ($a pre-increment)
        // draw black line from A to B
        imageline($i,                           // draw line
            (1+cos($a))*$r=300,$r+$r*sin($a),   // from A
            $r+$r*cos($b-=$p),$r+$r*sin($b),    // to B ($b pre-decrement)
            1                                   // undefined color=black
        );
// output
imagepng($i);

PHP, 176 174 bytes

imagecolorallocate($i=imagecreate(601,601),~0,~0,~0);for(;$a<360;)for($b=$a++;$b--;)imageline($i,(1+cos($a))*$r=300,$r+$r*sin($a),$r+$r*cos($b),$r+$r*sin($b),1);imagepng($i);

uses 360 points, which results in a filled circle with that resolution.

share|improve this answer
    
Good answer, but it seems you've hardcoded 20 instead of taking that as input? – Riking 8 hours ago

QBasic 4.5, 398 271 bytes

CLS:SCREEN 11:DEFSTR M-Z:DEFDBL A-L
INPUT"N",A:I=(360/A)*.0175:J=230
Q=",":FOR E=0 TO A
FOR F=E TO A
M=x$(COS(I*E)*J+J):N=x$(SIN(I*E)*J+J):O=x$(COS(I*F)*J+J):P=x$(SIN(I*F)*J+J):DRAW "BM"+M+Q+N+"M"+O+Q+P
NEXT:NEXT
FUNCTION x$(d):x$=LTRIM$(STR$(CINT(d))):END FUNCTION

The screen in QBasic can onl be 640x480, so the circle has a radius of only 230 px, unfortunately. Also, there's some artifacting because of float-to-int precision loss. Looks like this for N=36: enter image description here

EDIT: I didn't need the storage, the type declaration and all the looping. Calculating all Carthesians from Polars in place is 50% cheaper in byte count...

share|improve this answer

BBC BASIC, 98 ascii characters

Tokenised filesize 86 bytes

r=600V.5142;29,r;r;:I.n:t=2*PI/n:F.i=1TOn*n:a=i DIVn*t:b=i MODn*t:L.r*SINa,r*COSa,r*SINb,r*COSb:N.

Dowload interpreter at http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

There's nothing wrong with drawing every line twice, the appearance is identical :-P

Ungolfed

  r=600                              :REM Radius 600 units. 2 units per pixel, so 300 pixels
  VDU5142;29,r;r;                    :REM Set mode 20 (600 pixels high) and move origin away from screen corner
  INPUTn                             :REM Take input.
  t=2*PI/n                           :REM Step size in radians.
  FORi=1TOn*n                        :REM Iterate through all combinations.
    a=i DIVn*t                       :REM Get two angles a and b
    b=i MODn*t                       :REM by integer division and modlo
    LINEr*SINa,r*COSa,r*SINb,r*COSb  :REM calculate cartesian coordinates and draw line
  NEXT

Output n=21

This looks much better in the original rendering than in the browser.

<code>enter image description here</code>

share|improve this answer
    
Thanks for reminding me of the LINE function. Beats DRAW... – steenbergh 9 hours ago

Octave, 50 48 46 45 bytes

@(N)gplot((k=0:2*pi/N:N)+k',[cos(k);sin(k)]')

This is an anyonmous function that plots the graph we're looking for.

Explanation:

(k=0:2*pi/N:N)+k' Makes a full N+1 x N+1 adjecency matrix and simultaneously defines the vector k of angles, which we we use then for [cos(k);sin(k)]', a matrix of coordinates where each graph node is positioned. gplot just plots the graph that we want.

For N = 29 we get:

enter image description here

share|improve this answer

PICO-8, 131 bytes

I wasn't really sure if I'd be breaking any rules, but I did it anyway!

Golfed

p={}for i=0,19 do add(p,{64+64*cos(i/20),64+64*sin(i/20)})end for x in all(p)do for y in all(p)do line(x[1],x[2],y[1],y[2])end end

Ungolfed

points={}

for i=0,19 do 
  x=64+64*cos(i/20)
  y=64+64*sin(i/20)
  add(points,{x,y})
end

for x in all(points) do
  for y in all(points) do
    line(x[1],x[2],y[1],y[2])
  end
end

128x128 madness

PICO-8 is a Lua based fantasy console with a native resolution of 128x128. I made the circle as big as I could...

share|improve this answer

QBIC, 98 bytes

$SCREEN 11|:i=6.3/a j=230[0,a|[b,a|d=b*i e=c*i line(cos(d)*j+j,sin(d)*j+j)-(cos(e)*j+j,sin(e)*j+j)

I've converted my original QBasic answer @LevelRiverSt 's answer to QBIC. I thought this would rely too heavily on functions that are not built into QBIC to be feasible, but as it turns out, it saves another 90 bytes. Substituting the DRAW for LINE saves another 80 bytes. I knew I was forgetting something simple...

When run with a command line parameter of 36, it looks like this:

enter image description here

share|improve this answer

GeoGebra, 91 bytes

a=polygon((0,0),(1,0),20)
sequence(sequence(segment(vertex(a,i),vertex(a,j)),j,1,20),i,1,20)

Each line is separately entered into the input bar. Here is a gif showing the execution:

Execution

How it works

The polygon command creates a 20-sided polygon, with the vertices of the baseline at (0,0) and (1,0). The next command then iterates over each vertex of the polygon with index i, using the sequence and vertex commands, and for each vertex with index i, draws a line segment to every other vertex with index j using the segment command.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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