Tạo một biểu đồ hình tròn


14

Thử thách rất đơn giản:

Tạo biểu đồ hình tròn dựa trên một số giá trị đầu vào.

Đầu vào sẽ là danh sách các số dương, số thập phân hoặc số nguyên và đầu ra sẽ là biểu đồ hình tròn trong đó mỗi giá trị đầu vào được thể hiện bằng các màu riêng biệt và giá trị phần trăm bên ngoài mỗi khu vực.

Quy tắc:

  • Các màu sắc phải được phân biệt trực quan (các màu chính xác là tùy chọn)
  • Sẽ có ít nhất hai và tối đa 10 giá trị đầu vào
  • Bán kính của vòng tròn phải nằm trong phạm vi [100 300]pixel
    • Đồ họa vectơ vẫn ổn miễn là đầu ra mặc định cho bán kính [100, 300]pixel
  • Các giá trị phần trăm sẽ là số nguyên
    • Không có quy tắc nghiêm ngặt nào nói giá trị phần trăm sẽ được đặt ở đâu, nhưng phải dễ dàng nhìn thấy nó thuộc về khu vực nào
    • Khoảng cách giữa ký tự gần nhất và cạnh ngoài của vòng tròn phải nằm trong phạm vi [5, 40]pixel
    • Phông chữ là tùy chọn
  • Cốt truyện có thể có hoặc không có các vạch đen ngăn cách từng vùng
  • Các hàm được tạo để tạo biểu đồ hình tròn, ví dụ, MATLAB : pie, Python: matplotlib.pyplot.pievà Mathicala: PieChartkhông được phép
  • Quy tắc làm tròn thông thường (lên nếu nó (1.00, 0.5], xuống nếu nó (0.5, 0.00))
  • Nếu giá trị phần trăm của một lát nhỏ hơn 0.5%, đầu ra 0%. Các lát cắt vẫn phải được bao gồm trong cốt truyện.
  • Vui lòng cung cấp các ô để kiểm tra (hoặc một liên kết đến một thông dịch viên). Chỉ hiển thị cốt truyện với 10 giá trị đầu vào là đủ (để tránh câu trả lời rất dài)

Ví dụ

Vui lòng sử dụng các giá trị ví dụ dưới đây. Bạn có thể chuyển đổi danh sách sang định dạng phù hợp bằng cách sử dụng trình chuyển đổi danh sách số , ví dụ như 27 byte này bởi jimmy23013 .

x = [0.3, 1.2] 

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

x = [3, 6, 2, 10]

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

x = [0.4387, 0.3816, 0.7655, 0.7952, 0.1869, 0.4898, 0.4456, 0.6463, 0.7094, 0.7547]

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


"Bán kính của vòng tròn phải nằm trong phạm vi [100 300] pixel." Đồ họa vector có được phép quá không?
Martin Ender

@ MartinBüttner, vâng. Không sao, miễn là đầu ra từ chương trình trông giống như trong khoảng [100, 300] theo mặc định. Đó có phải là một câu trả lời đầy đủ?
Stewie Griffin

R làm tròn 0,5 đến 0. Đó có phải là vấn đề không?
Masclins

Sẽ ổn khi làm tròn 0.5thành 0 nếu đó là mặc định. Nhưng 0.50001phải được làm tròn thành 1.
Stewie Griffin

Câu trả lời:


12

Toán học, 186 183 164 byte

Graphics[{Hue@#,Disk[{0,0},{1,1},a=2Pi{##}],Black,Text[ToString@Round[100(#2-#)]<>"%",5Through@{Cos,Sin}@Mean@a/4]}&@@@Partition[Accumulate[#/Tr@#]~Prepend~0,2,1]]&

Có thể được đánh gôn hơn nữa. Hiện đang tạo một Graphicsđối tượng. Các trường hợp thử nghiệm:




7

JavaScript (ES6), 311 310 302 298 byte

a=>{with(Math)document.write(`<svg height=300>`+a.map(n=>`<path fill=#${(p*4e3|0).toString(16)} d=M135,150L${c(o=100,v=0)}A${[o,o,0,(v=n/=s)+.5|0,0,c(o)]}Z /><text x=${(z=c(135,v/=2))[0]} y=${z[p+=n,1]}>${n*o+.5|0}%</text>`,c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150],p=s=0,a.map(n=>s+=n)).join``)}

Đã lưu một byte với sự trợ giúp từ @Neil!

Giải trình

Viết một số SVG vào HTML của trang hiện tại. Xây dựng biểu đồ với điểm trung tâm 135 x 150bán kính 100pxvà văn bản tại bán kính 135pxtừ tâm.

var solution =

a=>{
  with(Math)
  document.write(       // write to HTML body
    `<svg height=300>`+ // create 300px x 300px SVG canvas (width defaults to 300px)
    a.map(n=>           // for each number
      
      // Get the hex colour by multiplying the current position by (roughly) 0xfff
      `<path fill=#${(p*4e3|0).toString(16)
      
      // Calculate the path of the pie slice
      } d=M135,150L${c(o=100,v=0)}A${[o,o,0,(v=n/=s)+.5|0,0,c(o)]
      
      // Text
      }Z /><text x=${(z=c(135,v/=2))[0]} y=${z[p+=n,1]}>${n*o+.5|0}%</text>`,
      
      // Returns [ x, y ] for a certain radius at position v around the pie
      c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150],
      p=s=0,             // p = current position around pie (0 - 1)
      a.map(n=>s+=n)     // s = sum of all numbers
    ).join``
    
    +`</svg>` // <- this is just here for the test, so multiple charts can be displayed
  )
}

// Test
;[
  [0.3, 1.2],
  [3, 6, 2, 10],
  [0.4387, 0.3816, 0.7655, 0.7952, 0.1869, 0.4898, 0.4456, 0.6463, 0.7094, 0.7547]
].map(c=>solution(c));


Tôi nghĩ bạn có thể lưu một vài byte bằng cách sử dụng with(Math)c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150].
Neil

Hmm, bạn có thể phải viết, with(Math)var solution = a=>v.v.
Neil

Hmm, thực sự tôi có thể sử dụng with. Tôi nghĩ rằng tôi có thể đã ở chế độ nghiêm ngặt khi tôi thử nó lần cuối ...
user81655

@Neil Có nó trong đó, cảm ơn. Tôi khá chắc chắn rằng có một chút chơi golf công bằng hơn có thể được thực hiện trên này, vì tôi đã vội vã một chút khi tôi viết nó.
dùng81655

Chỉ lưu 1 byte? Tôi đoán đó là một sự khởi đầu ...
Neil

6

Python + PIL, 365 355

from math import*;from random import*
from PIL import Image,ImageDraw
L,a,r=256,0,0.8;l,p,c=L/2,L/6,(L,L,L);I=Image.new('RGB',(L,L),c);D=ImageDraw.Draw(I)
x=input()
for i in x:b=a+ceil(360.0*i/sum(x));D.pieslice((p,p,L-p,L-p),int(a),int(b),tuple(map(randrange,c)));t=(a+b)*0.00872;D.text((l+cos(t)*l*r,l+sin(t)*l*r),str(int((b-a)/3.6))+'%',0);a=b
I.show()

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

Kết quả cho danh sách ví dụ lớn nhất:

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


Trong Python 2, không eval(raw_input())tương đương với Python 2 input()?
con mèo

@cat đúng rồi!
ăn kiêng
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.