数字作为圆形图形


36

首先,研究这个难题以了解您将要产生的东西。

您面临的挑战是编写一个程序或函数,该程序或函数将输出一个圆形图形(类似于拼图中的图形),并给出(以10为基数)介于1和100(含)之间的数字。这类似于此挑战,除了您将生成图形而不是罗马数字。以下圆圈从左到右代表数字1-10:

圆圈纹

作为对谜题状态的答案,您的图形应该从内到外看起来像罗马数字,其中线条粗细代表罗马数字符号,整个图形代表数字。供您参考,这是您需要的线宽。每行和下一行之间应有3px的填充。

Number  Roman Numeral   Line Width
1       I               1px
5       V               3px
10      X               5px
50      L               7px
100     C               9px

请发布您的输出中的一两个示例。假设输入正确,标准漏洞等等。这是代码高尔夫,所以最少的字节获胜。如果出现平局,大多数选票将获胜。祝好运!


3
图像的正确绝对尺寸是否必要,或者具有正确的相对尺寸是否足够?
David Zhang

@DavidZhang是的,为公平起见,请坚持我列出的线条和填充尺寸。
Rip Leeb 2014年

Answers:


15

数学- 166个 181字节

比其他Mathematica答案要简洁一些,这在某种程度上要归功于更加自由的风格。

c = Characters; r = Riffle;
Graphics[r[{0, 0}~Disk~# & /@ Reverse@Accumulate[
    l = {3} ~Join~ r[2 Position[c@"IVXLC", #][[1, 1]] - 1 & /@ 
        c@IntegerString[#, "Roman"], 3]], {White, Black}],
    ImageSize -> 2 Total@l] &

所有空格仅是为了清楚起见。这定义了一个匿名函数,该函数返回所需的图形。

动画

动画圈

在Mathematica中,生成数字圆的GIF动画很简单,它具有内置的功能,可以对任意对象的序列进行动画处理和导出。假设上面的代码刚刚执行完,

Table[Show[%@n, PlotRange -> {{-100, 100}, {-100, 100}}, 
    ImageSize -> 200], {n, 1, 399, 1}];
Export["animcircles.gif", %]

示例输出

输出示例


请发布一些结果。抱歉,不问这是第一位。我还更改了接受功能的问题。
里普·里布

感谢@MartinBüttner的建议。该代码已固定为输出正确大小的图像,并添加了示例输出。
张大卫

3
您的动画摇摆不定。并不是说我可以做得更好。
corsiKa 2014年

嗯,你是对的。考虑到我为Mathematica明确指定了绘图范围,我真的不确定为什么要这样做。
张大卫


15

普通Lisp- 376 331 304字节

(use-package(car(ql:quickload'vecto)))(lambda(n o &aux(r 3)l p)(map()(lambda(c)(setf l(position c" I V X L C D M")p(append`((set-line-width,l)(centered-circle-path 0 0,(+(/ l 2)r))(stroke))p)r(+ r l 3)))(format()"~@R"n))(with-canvas(:width(* 2 r):height(* 2 r))(translate r r)(map()'eval p)(save-png o)))

例子

在此处输入图片说明(1) 在此处输入图片说明(24)

在此处输入图片说明(104) 在此处输入图片说明(1903) 在此处输入图片说明(3999)

动画

对于1到400之间的数字:

新

注意:为了记录,此动画的完成方式如下:

我有一个修改后的代码版本,名为rings返回生成图像的宽度。因此,以下循环的结果是最大大小,此处为182

 (loop for x from 1 to 400
       maximize (rings x (format nil "/tmp/rings/ring~3,'0d.png" x)))

整个循环需要9.573秒。每个整数大约需要24ms。然后,在外壳中:

 convert -delay 5 -loop 0 -gravity center -extent 182x182 ring*png anim.gif

不打高尔夫球

(ql:quickload :vecto)
(use-package :vecto)

(lambda (n o)
  (loop with r = 3
        for c across (format nil "~@R" n)
        for l = (1+ (* 2(position c"IVXLCDM")))
        for h = (/ l 2)
        collect `(,(incf r h),l) into p
        do (incf r (+ h 3))
        finally (with-canvas(:width (* 2 r) :height (* 2 r))
                  (loop for (x y) in p
                        do (set-line-width y)
                           (centered-circle-path r r x)
                           (stroke))
                  (save-png o))))

说明

  • 该函数采用N1到3999之间的整数和文件名

  • (format nil "~@R" N)习惯将十进制转换为罗马。例如:

     (format nil "~@R" 34) => "XXXIV"
    

    ~@R 格式控制字符串被指定为工作1和3999这就是为什么有是允许的输入范围的限制之间的整数。

  • 我遍历结果字符串为每个数字C 建立一个P包含对的列表(radius width)

    • 宽度是一个简单的线性映射:我使用常量字符串“ IVXLCDM”来计算C在其中的位置。乘以2并加1,我们得到所需的值:

             (1+ (* 2 (position c "IVXLCDM")))
      

      但是,在高尔夫球版本中,此操作略有不同:

             (position c " I V X L C D M")
      
    • 每个半径的计算考虑了每个环的宽度以及环之间的空白空间。如果没有任何速度优化,则计算将保持精确,因为它们不是基于浮点数,而是基于有理数。

      编辑:我更改了参数以符合填充规则。

  • 完成此操作后,我知道生成的画布所需的大小(最新计算的半径的两倍)。

  • 最后,我为的每个元素绘制一个圆圈P并保存画布。

1
“此代码支持所有罗马数字(IVXLCDM)”。这是否意味着您的程序将罗马数字作为输入?那不是我想要的,但是很酷。动画道具。
Rip Leeb 2014年

1
不,不,如果不清楚,对不起:它适用于1到3999之间的任何整数。在您的问题中,您只需要1到100的输入,并且您的表中没有提及D或M ...我将对其进行编辑部分。
coredump 2014年

8

HTML + JQuery,288

的HTML

<canvas>

JS

    r=3;w=9;c=$('canvas').get(0).getContext('2d')
    for(i=prompt(),e=100;e-.1;e/=10){
    if((x=Math.floor(i/e)%10)==4)d(w)+d(w+2)
    else if(x==9)d(w)+d(w+4)
    else{if(x>4)d(w+2)
    for(j=x%5;j;j--)d(w)}
    w-=4}
    function d(R){c.lineWidth=R
    c.beginPath()
    c.arc(150,75,r+=R/2,0,7)
    c.stroke()
    r+=R/2+3}

小提琴


没有堆栈代码段?
Optimizer

@Optimizer完全忘记了我们现在拥有的
TwiNight 2014年

5

爪哇565

import java.awt.*;class Z{public static void main(String[]s){int i=new Byte(s[0]),j=i/10,k=i%10;String t="",u;if(j>8)t="59";if(j>9)t="9";if(j==4)t="57";else if(j<9){t=j>4?"7":"";j-=j>4?5:0;if(j>0)t+="5";if(j>1)t+="5";if(j>2)t+="5";}if(k>8)t+="15";if(k==4)t+="13";else if(k<9){t+=k>4?"3":"";k-=k>4?5:0;if(k>0)t+="1";if(k>1)t+="1";if(k>2)t+="1";}u=t;Frame f=new Frame(){public void paint(Graphics g){g.setColor(Color.BLACK);int x=0;for(char c:u.toCharArray()){int z=c-48,q=x;for(;x<q+z;)g.drawOval(99-x,99-x,x*2,x++*2);x+=3;}}};f.setSize(200,200);f.setVisible(1>0);}}

例子

15

15

84

84

93

93

格式很好:

import java.awt.*;    
class Z {    
    public static void main(String[] s) {
        int i = new Byte(s[0]), j = i / 10, k = i % 10;
        String t = "", u;
        if (j > 8)
            t = "59";
        if (j > 9)
            t = "9";
        if (j == 4) {
            t = "57";
        } else if (j < 9) {
            t = j > 4 ? "7" : "";
            j -= j > 4 ? 5 : 0;
            if (j > 0)
                t += "5";
            if (j > 1)
                t += "5";
            if (j > 2)
                t += "5";
        }
        if (k > 8)
            t += "15";
        if (k == 4) {
            t += "13";
        } else if (k < 9) {
            t += k > 4 ? "3" : "";
            k -= k > 4 ? 5 : 0;
            if (k > 0)
                t += "1";
            if (k > 1)
                t += "1";
            if (k > 2)
                t += "1";
        }
        u = t;
        Frame f = new Frame() {
            public void paint(Graphics g) {
                g.setColor(Color.BLACK);
                int x = 0;
                for (char c : u.toCharArray()) {
                    int z = c - 48, q = x;
                    for (; x < q + z;) {
                        g.drawOval(99 - x, 99 - x, x * 2, x++ * 2);
                    }
                    x += 3;
                }
            }
        };
        f.setSize(200, 200);
        f.setVisible(1 > 0);
    }
}

请发布一些结果。抱歉,不问这是第一位。
Rip Leeb 2014年

3

数学9 - 301个 249字节

:D使用内置的转换成罗马数字的感觉很欺骗,但是,嘿。

l=Length;k=Characters;r@n_:=(w=Flatten[Position[k@"IVXLC",#]*2-1&/@k@IntegerString[n,"Roman"]];Show[Table[Graphics@{AbsoluteThickness@w[[i]],Circle[{0,0},(Join[{0},Accumulate[3+w]]+3)[[i]]+w[[i]]/2]},{i,Range@l@w}],ImageSize->{(Total@w+(l@w)*3)*2}])

(当我昨晚这样做的时候,我没有太多时间,但是我意识到它可以打得更多。而且我也从David Zhang那里得到了一些提示...:D谢谢!)

更清楚一点:

l=Length;
k=Characters;
r@n_:=
    (
    w=Flatten[Position[k@"IVXLC",#]*2-1&/@k@IntegerString[n,"Roman"]];
    Show[Table[Graphics@{AbsoluteThickness@w[[i]],Circle[{0,0},(Join[{0},Accumulate[3+w]]+3)[[i]]+w[[i]]/2]},{i,Range@l@w}],ImageSize->{(Total@w+(l@w)*3)*2}]
    )

您可以像这样调用此函数:

r[144]

在此处输入图片说明

或者,您可以使用以下命令显示值ab的结果:Table[r[i],{i,a,b}]

注意:仅适用于最大399的值。


1

python 2,322 296

该脚本从stdin读取要转换的数字,并将图像输出为SVG标记。

..我使用“红色”代替“黑色”,因为它节省了2个字符:)

以下是一些示例:对于23:http : //jsfiddle.net/39xmpq49/ 对于42:http : //jsfiddle.net/7Ls24q9e/1/

i=input();r=9
def R(n,p):
 global r,i;i-=n;print '<circle r="{0}" stroke-width="{1}"/>'.format(r,p);r+=p+3
print '<svg viewBox="-50 -50 99 99" fill="none" stroke="red">',[[R(n,int(p)) for p in s*int(i/n)] for n,s in zip([100,90,50,40,10,9,5,4,1],'9/59/7/57/5/15/3/13/1'.split('/'))]and'','</svg>'

1

的JavaScript 342 334 308

function R(n){var v=document,o=[],x=1,c=v.body.appendChild(v.createElement('canvas')).getContext('2d')
while(n)v=n%10,y=x+2,o=[[],[x],[x,x],[x,x,x],[x,y],[y],[y,x],[y,x,x],[y,x,x,x],[x,x+=4]][v].concat(o),n=(n-v)/10
v=3
while(x=o.shift())c.lineWidth=x,c.beginPath(),c.arc(150,75,v+x/2,0,7),c.stroke(),v+=x+3}

for (var i = 1; i <= 100; i++) {
  R(i);
}

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.