排队的圆圈,n点


39

在成对n排列的圆点的每对不同点之间绘制线,产生类似以下结果的结果。最短的代码(以字节为单位)获胜!您的线条不必透明,但是那样看起来更好。输出必须是矢量图形,或者是至少600像素乘600像素的图像(保存到文件或显示在屏幕上)。要完成挑战,您必须至少绘制20张。

在此处输入图片说明


7
如果您必须输入数字n并为点画线,那就太酷了n
2016年

2
我赞同这个想法。在有人得到第一个答案之前将其更改。
shooqie '16

2
@shooqie然后标题是没有意义的,除非可以由mods编辑?
Yodle

2
我认为将37更改为任意值n不会增加任何挑战,因为我希望大多数解决方案无论如何都可以使用任何数字,特别是因为37是奇数,因此没有镜像对称性。
Laikoni '16

3
我们n是作为输入还是仅选择n20个以上的任意一个?
Rɪᴋᴇʀ

Answers:


26

Mathematica,13个字节

CompleteGraph

排队的37点

看起来这只是无法给进行循环嵌入n=4,但问题指出n>=20


1
...而且我在尝试寻找正确的方法来使函数接受n(我已经从固定37得到了答案):(
Jonathan Allan

6
@carusocomputing从绘图的角度来看,此功能与“绘图”无关。Mathematica也非常适合图论问题,并且如果我在语言中添加了对图的支持,那么拥有内置生成完整图的功能似乎就是我要做的第一件事。此功能碰巧对这个挑战有用的唯一原因是,默认情况下会绘制完整的图形,并将所有顶点排列成一个圆形。
Martin Ender

2
如果要支持图形,则最好具有内置的完整图形功能IMO。
ngenisis '16

2
@carusocomputing欢迎使用Mathematica,它是每种现有功能的内置语言。:-P
HyperNeutrino,2016年

1
我之所以下载NetLogo,是因为我以为“多乌龟会使这事变短!” 然后记得您Mathematicans正在使用成人版。
wyldstallyns

13

MATL16 14字节

由于我对MATL的流利程度不高,因此我希望这会更适合打高尔夫球。(至少能胜过Mathematica会很不错:-)即翻转w不是最佳的,可以避免...

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

在线测试!(感谢@Suever提供此服务,感谢@DrMcMoylex提供了-2个字节。)

说明(针对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

值得一提的是,用于产生统一的第N根可以使用式exp(2*pi*i*k/N)k=1,2,3,...,N。但既然exp(pi*i/2) = i你也可以写i^(4*k/N)k=1,2,3,...,N这是我在这里做什么。


1
您可以更改XH:H:G
DJMcMayhem

1
我忘了G非常感谢你!
瑕疵的

11

PICO- 8,131字节

我不确定我是否会违反任何规则,但是我还是这么做了!

打高尔夫球

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

不打高尔夫球

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疯狂

PICO-8是基于Lua的幻想游戏机,其原始分辨率为128x128。我尽了最大的努力...


9

Mathematica,42个字节

创建一组布置成一个圆的37个点,然后在两个点的所有可能子集之间绘制线。有人发布了一个简短的答案,该答案利用了CompleteGraph的优势,但是我相信这是最短的答案,除了那些依赖CompleteGraph的人。

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

在此处输入图片说明


3
无需避免从点到自身绘制线,因此可以使用节省3个字节Tuple。您还需要对其进行更新以接受任意值n,但很方便,这不会花费您任何字节。
ngenisis '16

1
打算说Tuples
ngenisis

9

HTML + JS(ES6),34 + 177 164 162 = 196个字节

使用HTML5 Canvas API

在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字节:删除closePath(),移动的stroke()beginPath()

-2个字节a内部定义的变量rotate()


8

Java中,346 338 322 301个字节

该解决方案适用于所有人n>1,即使原始帖子不需要这样做,它也适用。

我最喜欢的是n=5,不要问为什么,如果您想要一个更酷的GUI,请使用:

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

代替硬编码的300,它将使用框架的宽度或高度作为直径。

由于Shooqie,节省了8个字节。 借助Geobits,节省了21个字节。

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();}

输出为n=37

在此处输入图片说明


您可以删除Frame x=final(我认为?)
shooqie

@shooqie oops,Frame x来自另一个涉及线程的解决方案。尽管您需要final,因为它是对拥有类中的外部变量的内部类引用。
魔术八达通n

它在我的机器上工作正常。顺便说一句,我认为您可以通过将int声明移到for循环外来节省一些字节
shooqie 2016年

Java 6中的@shooqie表示在编译时“无法在封闭范围内引用非最终局部变量n”。
魔术八达通n

它在Java 8上对我有用,但是在编辑帖子后,我只会出现白屏。
shooqie '16

7

Python 2中,258 235个 229字节

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

输出为 n=37
n = 37


1
不会from PIL import*更短吗?
罗曼·格拉夫(RomanGräf)

@RomanGräfPIL是一个奇怪的软件包,import *根据您的安装方式,您不能这样做,您可以跳过PIL并直接导入Image / ImageDraw
Rod

6

八度,88 69字节

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

输出为N=37

在此处输入图片说明

输出为N=19

在此处输入图片说明


哦,我什至没有注意到,已经有了另一个八度的答案:)
更加模糊的

无论如何,打败亚 :-)
瑕疵的

一英里!我的第一个想法也是gplot如此,但我没有设法使它简短一些……
Stewie Griffin

6

Perl,229个字节

它使用与大多数语言相同的公式,但大多数语言都没有方便的内置函数来应对这一挑战(即使我没有看过它们也无法找到它,但这很容易找到公式)。所以不是很有趣,但是通常Perl对于这种挑战没有很多答案,所以我只想提出一个。

$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")

并且您将需要-MImager(9个字节),-MMath::Trig(提供pi,13个字节)和-n(1个字节)==> + 23个字节。

运行它:

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

它将创建一个名为的文件t.png,其中包含图像。

Imager虽然您需要安装,但不用担心,这很容易:

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

echo如果您以前从未使用过s,它将为您配置cpan。(实际上,只有在您的perl足够新的情况下,它才能工作,我认为对于大多数人来说都可以,对不起其他人!)) 。

还有更具可读性的版本(是的,对于Perl脚本来说,它是相当可读的!):

#!/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");

在此处输入图片说明

-1个字节感谢Titus。


Perl是否需要在单个命令周围加括号?
泰特斯

@Titus如果在for循环后引用括号,则可以,它们是必需的。
达达

以前有空白y2。我敢打赌你不需要那个。而且您可以写信给STDOUT吗?
泰特斯(Titus)

@Titus嗯,的确,谢谢。我想我的终端在这里放了换行符,所以我没看到空格。
达达

5

GeoGebra,92个字节

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

每行分别输入到输入栏中。这是显示执行情况的gif:

执行

这个怎么运作

polygon命令创建一个20边的多边形,基线的顶点在(0,0)(1,0)。然后下一个命令的多边形的各顶点遍历索引i,使用sequencevertex命令,以及用于与索引中的每个顶点i,绘制一条线段到每个其它顶点与索引j使用segment命令。


4

PHP,186个 184 196字节

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

将图像写入STDOUT

分解

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

// loop angle A from 0 to 2*PI
for(;$a<$p=2*M_PI;)
    // loop angle B from A down to 0
    for($b=$a+=$p/=$argv[1];$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);

固定为-12个字节 n=20

替换$p=2*M_PI6(-8),/=$argv[1]=M_PI/10(-2),并$b>0$b(-2)

使用精确的PI / 10不会造成伤害。使用时.3142,参数化版本的舍入误差仍然存在,但是随着M_PI/10它们消失了,我可以检查$b(<> 0)而不是$b>0。我本可以.314用来保存两个字节,但是那样会使点偏移。

该极限$a<6足够精确到20点。

精确PI图

固定的174个字节 n=314

imagecolorallocate($i=imagecreate(601,601),~0,~0,~0);for(;$a<314;)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);

使用314点会产生该分辨率的实心圆(如136,140一样,其上的每个偶数以及317以上的所有值)。


1
好的答案,但是您似乎已经硬编码20,而不是将其作为输入?
2016年

1
@Riking:是的。但是我看不到参数化挑战的需求。
泰特斯


4

R,127123字节

plot((e=cbind(sin(t<-seq(0,2*pi,l=(n=21)))*2,cos(t)*2)));for(i in 2:n)for(j in 1:i)lines(c(e[i,1],e[j,1]),c(e[i,2],e[j,2]))

产生:

好轴的标签吧?

-4个字节感谢@Titus!


1
不会更短,但是使用可能会更快for(i in 2:n){for(j in 1:i)...}。是否R需要支架?
泰特斯

@Titus你是对的!不,那里不需要大括号。谢谢 !
弗雷德里克

3

BBC BASIC,98位ASCII字符

标记化文件大小为86个字节

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.

http://www.bbcbasic.co.uk/bbcwin/bbcwin.html上下载下载解释器

每行绘制两次没有错,外观是相同的:-P

不打高尔夫球

  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

输出n = 21

在原始渲染中,这比在浏览器中看起来要好得多。

<code>在此处输入图片描述</ code>


感谢您提醒我该LINE功能。节拍DRAW...
steenbergh '16

3

八度,50 48 46 45字节

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

这是一个绘制我们要查找的图形的函数。

说明:

(k=0:2*pi/N:N)+k'制作一个完整的N+1 x N+1邻接矩阵,并同时定义k角度向量,然后我们将其用于[cos(k);sin(k)]',这是每个图节点位于其中的坐标矩阵。gplot只是绘制我们想要的图形。

因为N = 29我们得到:

在此处输入图片说明


2

JavaScript(ES5)/ SVG(HTML5),181字节

document.write('<svg viewBox=-1e3,-1e3,2e3,2e3><path stroke=#000 fill=none d=M1e3,0')
with(Math)for(i=37;--i;)for(j=37;j--;)document.write('L'+1e3*cos(a=i*j*PI*2/37)+','+1e3*sin(a))

仅适用于质数,例如原来的建议37。您可以将的初始值减半(四舍五入)i以获得较暗的图像。您也可以将其始终调整1e3,2e3为其他值以进行品尝(我从开始300,600但认为它太粗糙了)。


2

MATLAB,36字节

@(n)plot(graph(ones(n),'Om'),'La','c')

这是一个创建图表的异常功能。

@(n)                                     Define an anonymous fuction of 𝘯
               ones(n)                   Create an 𝘯×𝘯 matrix of ones
         graph(       ,'Om')             Create a graph object with that adjacency
                                         matrix, omitting self-loops
    plot(                   ,'La','c')   Plot the graph with a circular layout

例:

在此处输入图片说明

在此处输入图片说明


我很惊讶graph这不是生物信息学工具箱的一部分...甚至都不知道它的存在...不错:)
Stewie Griffin

1

QBasic的4.5,398个 271字节

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

QBasic中的屏幕只能是640x480,因此不幸的是,圆的半径仅为230 px。另外,由于浮点数到整数精度的损失,还会产生一些假象。看起来像这样N=36在此处输入图片说明

编辑:我不需要存储,类型声明和所有循环。从原位计算所有笛卡尔笛卡尔的字节数便宜50%...


1

QBIC98 94字节

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

我已经将原来的QBasic答案 @LevelRiverSt的答案转换为QBIC。我认为这将过于依赖QBIC中未内置的功能,因此不可行,但事实证明,它又节省了90个字节。替换为 DRAWfor LINE可以节省另外80个字节。我知道我忘记了一些简单的事情...

使用36的命令行参数运行时,如下所示:

在此处输入图片说明


1

处理,274字节(239 + size调用和函数调用)

void d(int s){float a=2*PI/s,x=0,y=-400,m,n;float[][]p=new float[2][s];translate(400,400);for(int i=0;i<s;i++){m=x*cos(a)-y*sin(a);n=x*sin(a)+y*cos(a);x=m;y=n;p[0][i]=x;p[1][i]=y;for(int j=0;j<i;j++)line(p[0][j],p[1][j],p[0][i],p[1][i]);}}
void setup(){size(800,800);d(50);}

老实说,我不知道为什么,但是setup必须在第二行。我使用https://en.wikipedia.org/wiki/Rotation_matrix来帮助我计算旋转数学。该程序将计算点并将其推入一个数组,我们将使用该数组绘制线。

这是一张具有50条边的多边形的图片(100条边几乎是全黑的)

50分

您可以添加stroke(0,alpha);透明边缘,其中alpha线的不透明度为。下面是使用相同的多边形alpha20

在此处输入图片说明


1

Bash + Jelly + GraphViz,52个字符,52或63个字节

鉴于所讨论的程序在使用哪种字符编码上存在分歧,因此该程序充满了控制字符。这是xxdLatin-1编码(代表一个字节中的每个字符)下的样子:

00000000: 6a65 6c6c 7920 6520 2793 5213 636a 0c8e  jelly e '.R.cj..
00000010: 2d2d 59fe 9a3f 1d15 dc65 34d3 8442 7f05  --Y..?...e4..B..
00000020: 1172 80cf fb3b ff7d 277c 6369 7263 6f20  .r...;.}'|circo 
00000030: 2d54 7073                                -Tps

但是,由于某种原因,我实际上无法运行程序,而没有将输入转换为UTF-8(这会使它长63个字节)。从逻辑上讲,它应该像Latin-1一样工作-所有字符都不在0到255的范围之外-但是无论我如何配置字符编码环境变量,我都会不断收到“字符串索引超出范围”错误。因此,除非有人能找到一种无需重新编码就可以运行的方法,否则必须将其计为63个字节。

如果我们使用Jelly的编码来解释该程序,则该程序可能会更具可读性:

jelly e 'ƓRŒcj€⁾--Y“Ȥ?øßṇe4ạ⁴B¶¦×r°Ẇ»;”}'|circo -Tps

该程序在标准输入上获取点数,并在标准输出上输出PostScript图像。(可以通过-Tps在末尾更改来轻松地调整为以GraphViz支持的任何格式输出;只是PostScript的名称最短。可以说,您可以通过删除来保存五个字符-Tps,但随后您将以GraphViz的内部图像格式获取输出。没有其他的支持,这可能对问题不起作用。)

从根本上讲,这只是一个Jelly程序,它调用GraphViz进行绘制。但是,Jelly似乎没有运行外部程序的任何功能,因此我不得不使用bash将它们链接在一起。(这也意味着从stdin手动输入Jelly请求输入会更便宜;通常它从命令行获取输入,但这意味着bash包装器中需要额外的字节。)circo将自动将要绘制的所有点排列成一个圆圈,因此Jelly代码只需要求它绘制一个点列表,所有这些点都相互连接。运作方式如下:

ƓRŒcj€⁾--Y“Ȥ?øßṇe4ạ⁴B¶¦×r°Ẇ»;”}
Ɠ                               read number from stdin
 R                              produce range from 1 to that number
                                (here used to produce a list with
                                that many distinct elements)
  Œc                            select all unordered pairs from that
      ⁾--                       a string consisting of two hyphens
    j€                          join each pair via the string
         Y                      join on newlines
                            ;   prepend (in this context)
          “Ȥ?øßṇe4ạ⁴B¶¦×r°Ẇ»    "graph{node[shape=point]"
                             ”} follow output with a "}" character

使用Jelly,我们可以稍微压缩一下通过其内置字典配置GraphViz输出的字符串。这本字典有graphnodepoint。令人讨厌的是,它没有shape(它具有SHAPE,但是GraphViz区分大小写),因此我们必须逐个字符地对该字符进行编码。

这是输入21的输出(对程序进行了少许修改,使其以可以上载到Stack Exchange的格式输出):

21点的完整图


0

PHP + HTML SVG,316 263字节

具有硬编码n点且没有输入n参数的高尔夫球版:

<svg height="610" width="610"><?for($i=1;$i<33;$i++){$x[]=300*sin(2*M_PI/32*$i)+305;$y[]=300*cos(2*M_PI/32)+305;}foreach($x as$j=>$w){foreach($y as$k=>$z){echo'<line x1="'.$x[$j].'" y1="'.$y[$j].'" x2="'.$x[$k].'" y2="'.$y[$k].'" style="stroke:red;"/>';}}?></svg>

以前的高尔夫版本,带输入参数的n点数为316字节:

<svg height="610" width="610"><?$n=$_GET[n];$d=2*M_PI/$n;$r=300;$o=305;for($i=1;$i<=$n;$i++){$x[]=$r*sin($d*$i)+$o;$y[]=$r*cos($d*$i)+$o;}foreach($x as$j=>$w){foreach($y as$k=>$z){echo'<line x1="'.$x[$j].'" y1="'.$y[$j].'" x2="'.$x[$k].'" y2="'.$y[$k].'" style="stroke:rgba(0,0,0,.15);stroke-width:1;" />';}}?></svg>

用法:保存在文件中并从浏览器调用:

http://localhost/codegolf/circle.php?n=32

非高尔夫版本,带有用于n点和CSS的输入参数:

<style>
line {
    stroke: rgba(0,0,0,.15);
    stroke-width:1;
}
</style>
<svg height="610" width="610">
<?php
$n=$_GET[n]; // number of points
$d=2*M_PI/$n; // circle parts
$r=300; // circle radius
$o=305; // offset x,y
for ($i=1;$i<=$n;$i++){
    $x[]=$r*sin($d*$i)+$o; // store x,y coordinates in array
    $y[]=$r*cos($d*$i)+$o;
}
foreach($x as $j => $w){ // iterate all x,y points and connect to each other
    foreach($y as $k => $z) {
        echo '<line x1="'.$x[$j].'" y1="'.$y[$j].'" x2="'.$x[$k].'" y2="'.$y[$k].'" />'."\n";   
    }
}
?>
</svg>

由于单个帖子的字符数上限为30k,因此无法附加32点全功能代码段。这是屏幕截图:

在此处输入图片说明

由于30k单帖限制,附加的代码段限制为18点。


0

R,108个字节

plot(x<-cos(t<-seq(0,2*pi,l=21)),y<-sin(t),as=1);apply(expand.grid(1:21,1:21),1,function(e)lines(x[e],y[e]))

如果我放弃,as=1强制长宽比为1 的参数,可以减少5个字节。用于expand.grid创建具有所有可能的成对点的矩阵,并用于apply遍历该点。

N = 21

R + igraph,87个字节

另一种使用package的解决方案igraph

library(igraph);plot(make_full_graph(21),layout=cbind(cos(t<-seq(0,2*pi,l=21)),sin(t)))

N = 21

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.