円グラフを作成する


14

課題は簡単です。

多数の入力値に基づいて円グラフを作成します。

入力は正の数、10進数または整数のリストになり、出力は円グラフになります。各入力値は別々の色で表され、各領域の外側のパーセンテージ値になります。

ルール:

  • 色は視覚的に区別できる必要があります(正確な色はオプションです)
  • 少なくとも2つ、最大10の入力値があります
  • 円の半径は[100 300]ピクセル 範囲内である必要があります
    • デフォルトの出力が[100, 300]ピクセルの半径を与える限り、ベクターグラフィックスは問題ありません
  • パーセント値は整数でなければならない
    • パーセント値をどこに配置するかという厳密な規則はありませんが、どの領域に属するかを簡単に確認する必要があります
    • 最も近い文字と円の外縁の間の距離は、[5, 40]ピクセル範囲内である必要があります
    • フォントはオプションです
  • プロットには、各領域を分離する黒い線がある場合とない場合があります
  • 円グラフを作成するために作成された関数、たとえば、MATLAB:pie、Python:matplotlib.pyplot.pieおよびMathematica:PieChartは使用できません
  • 通常の丸め規則(の場合は上(1.00, 0.5]、の場合は下(0.5, 0.00)
  • スライスのパーセント値がより小さい場合0.5%、output 0%。スライスはまだプロットに含まれている必要があります。
  • 試験用のプロット(または通訳へのリンク)を提供してください。10個の入力値を持つプロットのみを表示するだけで十分です(非常に長い回答を避けるため)

以下のサンプル値を使用してください。数値リストコンバータを使用して、リストを適切な形式に変換できます。たとえば、jimmy23013によるこの27バイトです

x = [0.3, 1.2] 

ここに画像の説明を入力してください

x = [3, 6, 2, 10]

ここに画像の説明を入力してください

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

ここに画像の説明を入力してください


「円の半径は[100 300]ピクセルの範囲内でなければなりません。」ベクターグラフィックも許可されていますか?
マーティンエンダー

@MartinBüttner、はい。プログラムからの出力がデフォルトで[100、300]の間であるように見える限り、それは問題ありません。それで十分な答えですか?
スチューウィーグリフィン

Rは0.5を0に丸めます。それは問題ですか?
マスクリン

0.5デフォルトの場合、ゼロに丸めても問題ありません。ただし0.50001、1に丸める必要があります。
Stewie Griffin

回答:


12

Mathematicaの、186の 183 164バイト

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

さらにゴルフできます。現在、Graphicsオブジェクトを生成します。テストケース:




7

JavaScript(ES6)、311 310 302 298バイト

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

@Neilの助けを借りて1バイトを保存しました!

説明

現在のページのHTMLにSVGを書き込みます。135 x 150半径の中心点と中心から半径の100pxテキストでチャートを作成します135px

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


を使用して数バイト節約できると思いますwith(Math)c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150]
ニール

うーん、次のように記述する必要があるかもしれませんwith(Math)var solution = a=>など
ニール・

うーん、実際に使用できますwith。最後に試してみたとき、私はストリクトモードになっていたと思います
...-user81655

@ニールそこにそれを得た、ありがとう。私はそれを書いたときに少し急いでいたので、これで行うことができるかなり多くのゴ​​ルフがあると確信しています。
-user81655

1バイトのみ保存しますか?始まりだと思う
ニール

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

ここに画像の説明を入力してください

最大のサンプルリストの結果:

ここに画像の説明を入力してください


Python 2では、Python 2とeval(raw_input())同等ではありませんinput()か?

@catはい、そうです!
ディーター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.