色付きグラフの合計


9

場合によっては、物理学では、グラフを合計する必要があります。課題は、選択した言語で、複数のグラフを画像として受け取り、すべての可能な合計を計算し、結果を出力するプログラムまたは関数を記述することです。

グラフ

グラフはrgb(255, 255, 255)、各列に白以外のピクセルがある白()の背景を含む画像です。例:

グラフの例 グラフの例 グラフの例

スクリプトの値は、カラーピクセルのY位置として表されます。特定のX座標の値は、その列の一番上の色付きピクセルのY位置に等しく、座標は左下の0から始まります。美的な理由から、これらのピクセルの下に追加の色付きピクセルがある場合とない場合があります。

仕事

あなたの仕事は、選択した言語で、複数のグラフを画像として取り、すべての可能な2^n - 1合計を計算し、結果を出力するプログラムまたは関数を書くことです。

グラフの合計は、各列の値が各入力グラフの対応する列の値の合計と等しいグラフです。

グラフは複数の色で表示されます。結果の画像には、元のグラフを含み、ゼロの合計を除いた他のグラフと同様に、グラフのすべての可能な合計が含まれている必要があります。

各和の色は、例えば、色のグラフ、含まれるグラフの色の平均値によって決定されるrgb(255, 0, 255)rgb(0, 255, 255)のグラフを生成するrgb(128, 128, 255)(また、丸みを帯びた下であってもよいです)。

結果の画像は、すべてのグラフにフィットするために必要な高さにする必要があります。つまり、どの入力よりも大きい画像を出力する必要がある場合があります。

結果のグラフが結果の画像に描画される順序は重要ではありません。つまり、結果のグラフが重なっている場合、どちらを上にするかを選択できますが、色の組み合わせではなく、グラフの1つでなければなりません。

入力画像の幅が等しい、画像のすべての列に少なくとも1つの非白のピクセルがある、画像の高さ(出力を含む)が4096ピクセル未満であると想定する場合があります。

入力A:

グラフの例

入力B:

グラフ例b

出力例:

グラフ合計の例

(誰かが興味を持っている場合は、ランダムな会社の株価チャートからこれらのデータをコピーして貼り付けました。これが、現実的なデータをCSVとして取得する最初の方法でした。)

ルール

  • 任意のビットマップ画像入力ファイル形式を選択できます。
  • 入力と一致する必要がないビットマップ画像出力ファイル形式を選択できます。
  • 画像処理ライブラリを使用することもできますが、このタスクを直接完了する関数は禁止されています。
  • 標準の抜け穴が適用されます。
  • これはなので、バイト単位の最短コードが優先されます。

グラフ生成スクリプト

以下は、グラフを生成するPython 2スクリプトです。入力は行で指定され、最初の3行はRGBカラーで、残りはデータとして、EOFで終了します。

import PIL.Image as image
import sys

if len(sys.argv) < 2:
    sys.stderr.write("Usage: graphgen.py <outfile> [infile]")
    exit(1)
outfile = sys.argv[1]
if len(sys.argv) > 2:
    try:
        stream = open(sys.argv[2], "r")
        data = stream.read()
        stream.close()
    except IOError as err:
        if err.errno == 2:
            sys.stderr.write("File \"{0}\" not found".format(sys.argv[2]))
        else:
            sys.stderr.write("IO error {0}: {1}".format(err.errno, err.strerror))
        exit(1)
else:
    data = sys.stdin.read()

try:
    items = map(int, data.strip().split("\n"))
    red, green, blue = items[:3]
    items = items[3:]
    highest = max(items)
except (ValueError, TypeError, IndexError):
    sys.stderr.write("Invalid value(s) in input")

img = image.new("RGB", (len(items), highest + 1), (255, 255, 255))

prev = items[0]
img.putpixel((0, highest - items[0]), (red, green, blue))
for x, item in enumerate(items[1:]):
    img.putpixel((x + 1, highest - item), (red, green, blue))
    if item < prev:
        for i in range(item + 1, prev):
            img.putpixel((x, highest - i), (red, green, blue))
    else:
        for i in range(prev + 1, item):
            img.putpixel((x + 1, highest - i), (red, green, blue))
    prev = item

img.save(outfile, "png")

@MartinBüttner現在、2つのグラフに1つ作成しています。私は手作業で行っているため(参照実装はまだありません)、3の忍耐力があるかどうかはわかりません。また、幅が異なるため、指定した3つを合計することはできません。
PurkkaKoodari 2015年

n入力グラフがある場合2^n - 1、出力画像に線が表示されますか?
Peter Taylor

@PeterTaylorはい。
PurkkaKoodari 2015年

出力に実際に縦線が含まれている必要がないと思いますか?各列の一番上のピクセルだけですか?
マーティンエンダー2015年

@MartinBüttnerそのデータは最初のセクションで定義されているようにグラフとして解析できるので、それは正しいです。
PurkkaKoodari 2015年

回答:


3

MATLAB、405

経由で呼び出す: f('http://i.stack.imgur.com/ffCzR.png','http://i.stack.imgur.com/zHldg.png')

function f(varargin)
for k=1:nargin
i=im2double(imread(varargin{k}))
V(k,:)=size(i,1)-cellfun(@(V)find(any(V~=1,3),1),num2cell(i,[1,3]))
C(k,:)=i(find(any(i(:,1,:)~=1,3),1),1,:)
end
s=2^nargin-1
G=dec2bin(1:s)-'0'
C=bsxfun(@rdivide,G*C,sum(G,2))
V=G*V
m=max(V(:))
r=ones(m+1,size(V,2))
g=r
b=r
for i=1:s
M=bsxfun(@eq,(m:-1:0).',V(i,:))
r(M)=C(i,1)
g(M)=C(i,2)
b(M)=C(i,3)
end
imwrite(cat(3,r,g,b),'S.png')

4

Python、422

コマンドラインから呼び出す python plotsum im1.png im2.png im3.png

import sys
from numpy import*
from scipy import misc as m
R=m.imread
r=range
a=array
N=sys.args[1:]
L=len(N)
P=[map(argmin,R(n,1).T)for n in N]               #converts image to list of heights, counting from the top
C=a([R(N[i])[P[i][0],0,:]for i in r(L)])         #finds and stores the colour
P=a([len(R(N[i]))-a(P[i])for i in r(L)])         #flips the numbers, measures actual heights from bottom
w=len(P[0])
h=max(sum(P,0))+1                                    #compute dimensions
G=ones((h,w,3))*255                                  #and make a white grid
for i in r(1,2**L):
 z=where(a(list(bin(i)[2:].zfill(L)))=='1');y=sum(P[z],0)    #sum the graphs
 for x in r(w):G[y[x],x,:]=average(C[z],0)                   #average the colours
m.imsave('S.png',G[::-1])                            #flip image vertically and save

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

これはトリッキーなもので、高レベルの配列演算であり、インデックスとして配列を使用することは、ここで非常に役立ちます。MathematicaとMatlabを除いて、1000バイト未満の解決策を期待していません

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