Số là đồ họa tròn


36

Đầu tiên, nghiên cứu câu đố này để cảm nhận về những gì bạn sẽ sản xuất.

Thử thách của bạn là viết một chương trình hoặc hàm sẽ tạo ra một đồ họa hình tròn giống như các câu đố từ câu đố, được đưa ra một số (cơ sở 10) trong khoảng từ 1 đến 100 (đã bao gồm). Điều này tương tự với thử thách này , ngoại trừ việc bạn sẽ sản xuất một đồ họa chứ không phải là chữ số La Mã. Các vòng tròn sau đây đại diện cho các số 1-10, từ trái sang phải:

mô hình vòng tròn

Như câu trả lời cho các trạng thái câu đố, đồ họa của bạn sẽ đọc giống như một chữ số La Mã từ trong ra ngoài, trong đó độ dày của dòng biểu thị các ký hiệu chữ số La Mã và toàn bộ đồ họa đại diện cho số. Để bạn tham khảo, đây là độ dày đường mà bạn sẽ cần. Mỗi dòng nên có phần đệm 3px giữa nó và dòng tiếp theo.

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

Vui lòng gửi một hoặc hai mẫu đầu ra của bạn. Giả sử đầu vào là chính xác, sơ hở tiêu chuẩn , vv và vv. Đây là mã golf, vì vậy ít byte nhất giành chiến thắng. Trong trường hợp hòa, hầu hết phiếu bầu đều thắng. Chúc may mắn!


3
Là kích thước tuyệt đối chính xác của hình ảnh cần thiết, hoặc nó có đủ để có kích thước tương đối đúng?
David Zhang

@DavidZhang Có, xin vui lòng bám vào các kích thước dòng và đệm mà tôi đã liệt kê, vì công bằng.
Rip Leeb

Câu trả lời:


15

Toán học - 166 181 byte

Một chút ngắn gọn hơn so với câu trả lời Mathicala khác, một phần nhờ vào một phong cách không có điểm.

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] &

Tất cả khoảng trắng chỉ dành cho rõ ràng. Điều này xác định một chức năng ẩn danh trả về đồ họa mong muốn.

Hoạt hình

Vòng tròn hoạt hình

Tạo một GIF hoạt hình của các vòng tròn số là chuyện nhỏ trong Mathicala, có chức năng tích hợp sẵn để hoạt hình và xuất các chuỗi các đối tượng tùy ý. Giả sử đoạn mã trên vừa được thực thi,

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

Ví dụ đầu ra

Ví dụ đầu ra


Xin vui lòng gửi một vài kết quả. Xin lỗi vì đã không hỏi đây là nơi đầu tiên. Tôi cũng đã thay đổi câu hỏi để chấp nhận chức năng.
Rip Leeb

Cảm ơn những lời đề nghị @ MartinBüttner. Mã đã được cố định để xuất hình ảnh có kích thước chính xác và đầu ra ví dụ đã được thêm vào.
David Zhang

3
Hoạt hình của bạn ngọ nguậy. Không phải là tôi có thể làm tốt hơn.
corsiKa

Hmm, bạn nói đúng. Tôi thực sự không chắc tại sao nó lại như vậy, vì tôi đã chỉ định rõ ràng phạm vi cốt truyện cho Mathicala.
David Zhang

Có lẽ liên quan đến sự lung lay: mathematica.stackexchange.com/q/134272
coredump

15

Lisp thường gặp - 376 331 304 byte

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

Ví dụ

nhập mô tả hình ảnh ở đây(1) nhập mô tả hình ảnh ở đây(24)

nhập mô tả hình ảnh ở đây(104) nhập mô tả hình ảnh ở đây(1903) nhập mô tả hình ảnh ở đây(3999)

Hoạt hình

Đối với các số từ 1 đến 400:

Mới

NB: Đối với bản ghi, hoạt hình này được thực hiện như sau:

Tôi có một phiên bản sửa đổi của mã, được đặt tên rings trả về chiều rộng của hình ảnh được sản xuất. Do đó, kết quả của vòng lặp sau là kích thước tối đa, ở đây 182 :

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

Toàn bộ vòng lặp mất 9,573 giây. Điều đó mang lại khoảng 24ms cho mỗi số nguyên. Sau đó, trong một vỏ:

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

Ung dung

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

Giải thích

  • Hàm lấy một số nguyên N từ 1 đến 3999 và tên tệp

  • tôi sử dụng (format nil "~@R" N) để chuyển đổi từ thập phân sang roman. Ví dụ:

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

    Các ~@R điều khiển định dạng được chỉ định để hoạt động cho các số nguyên trong khoảng từ 1 đến 3999. Đó là lý do tại sao có giới hạn cho phạm vi đầu vào được phép.

  • Tôi lặp lại chuỗi kết quả để xây dựng một danh sách Pcó chứa(radius width) các cặp, cho mỗi chữ số C.

    • Chiều rộng là ánh xạ tuyến tính đơn giản: Tôi sử dụng chuỗi "IVXLCDM" không đổi để tính toán vị trí của C trong đó. Nhân hai và thêm một, chúng ta có được giá trị mong muốn:

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

      Tuy nhiên, điều này được thực hiện hơi khác nhau trong phiên bản chơi gôn:

             (position c " I V X L C D M")
      
    • Tính toán của mỗi bán kính có tính đến chiều rộng của mỗi vòng cũng như khoảng trống giữa các vòng. Không có bất kỳ tối ưu hóa tốc độ nào, các tính toán vẫn chính xác bởi vì chúng không dựa trên số float, mà là các số hữu tỷ.

      Chỉnh sửa : Tôi đã thay đổi các tham số để tuân thủ các quy tắc đệm.

  • Khi điều này được thực hiện, tôi biết kích thước yêu cầu của khung vẽ kết quả (gấp đôi bán kính tính toán mới nhất).

  • Cuối cùng, tôi vẽ một vòng tròn cho mỗi yếu tố Pvà lưu khung vẽ.

1
"Mã này hỗ trợ tất cả các chữ số La Mã (IVXLCDM)". Điều đó có nghĩa là chương trình của bạn lấy chữ số La Mã làm đầu vào? Đó không phải là những gì tôi dự định, nhưng khá tuyệt. Đạo cụ cho hoạt hình cũng vậy.
Rip Leeb

1
Không, không, xin lỗi nếu điều này không rõ ràng: nó hoạt động với bất kỳ số nguyên nào trong khoảng từ 1 đến 3999. Trong câu hỏi của bạn, bạn chỉ yêu cầu đầu vào từ 1 đến 100 và bảng của bạn không đề cập đến D hoặc M ... Tôi sẽ chỉnh sửa phần.
coredump

8

HTML + JQuery, 288

HTML

<canvas>

Mã não

    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}

Vĩ cầm


Không có đoạn trích ngăn xếp?
Tối ưu hóa

@Optimizer Hoàn toàn quên mất chúng ta có ngay bây giờ
TwiNight

5

Java, 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);}}

Ví dụ

15

15

84

84

93

93

Định dạng độc đáo:

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

Xin vui lòng gửi một vài kết quả. Xin lỗi vì đã không hỏi đây là nơi đầu tiên.
Rip Leeb

3

Toán học 9 - 301 249 byte

: D Cảm thấy gian lận khi sử dụng chuyển đổi tích hợp sang chữ số La Mã, nhưng hey.

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}])

(Khi tôi làm điều này tối qua tôi không có nhiều thời gian, nhưng tôi nhận ra rằng nó có thể bị đánh gôn nhiều hơn. Và tôi cũng đã nhận được một số gợi ý từ David Zhang ...: D Cảm ơn!)

Nói rõ hơn một chút:

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}]
    )

Đây là một chức năng mà bạn có thể gọi như thế này:

r[144]

nhập mô tả hình ảnh ở đây

Hoặc, bạn có thể hiển thị kết quả từ giá trị a đến b với:Table[r[i],{i,a,b}]

Lưu ý : Điều này chỉ hoạt động cho các giá trị lên tới 399.


1

Con trăn 2, 322 296

Kịch bản đọc số được chuyển đổi từ stdin và xuất hình ảnh dưới dạng đánh dấu SVG.

.. Tôi sử dụng 'đỏ' thay vì 'đen', vì nó tiết kiệm được 2 ký tự :)

Dưới đây là một số mẫu: cho 23: http://jsfiddle.net/39xmpq49/ cho 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);
}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.