Menjumlahkan grafik berwarna

9

Dalam beberapa kasus, seringkali dalam fisika, Anda harus menjumlahkan grafik. Tantangan Anda adalah menulis, dalam bahasa pilihan Anda, program atau fungsi yang menggunakan banyak grafik sebagai gambar, menghitung semua jumlah yang mungkin, dan mengeluarkan hasilnya.

Grafik

Grafik adalah gambar yang berisi rgb(255, 255, 255)latar belakang putih ( ) dengan piksel non-putih di setiap kolom. Contoh:

contoh grafik contoh grafik contoh grafik

Nilai skrip direpresentasikan sebagai posisi Y dari piksel berwarna. Nilai pada koordinat X tertentu sama dengan posisi Y dari piksel berwarna paling atas di kolom itu, dengan koordinat mulai dari 0 di kiri bawah. Mungkin ada atau tidak ada piksel berwarna tambahan di bawah piksel itu untuk alasan estetika.

Tugas

Tugas Anda adalah menulis, dalam bahasa pilihan Anda, program atau fungsi yang menggunakan banyak grafik sebagai gambar, menghitung semua 2^n - 1jumlah yang mungkin , dan menampilkan hasilnya.

Jumlah grafik adalah grafik di mana setiap nilai kolom sama dengan jumlah nilai kolom yang sesuai di setiap grafik input.

Grafik akan datang dalam berbagai warna. Gambar hasil harus mengandung semua jumlah yang mungkin dari grafik seperti grafik lainnya, termasuk grafik asli tetapi tidak termasuk jumlah nol.

Warna setiap penjumlahan ditentukan oleh rata-rata warna dari grafik termasuk, misalnya, grafik warna rgb(255, 0, 255)dan rgb(0, 255, 255)akan menghasilkan grafik rgb(128, 128, 255)(dapat juga dibulatkan ke bawah).

Gambar yang dihasilkan harus setinggi yang diperlukan agar sesuai dengan semua grafik. Ini berarti Anda mungkin harus menampilkan gambar yang lebih besar dari input mana pun.

Urutan di mana grafik yang dihasilkan digambar ke gambar yang dihasilkan tidak masalah, yaitu jika grafik hasil tumpang tindih, Anda dapat memilih yang mana di atas, tetapi harus salah satu grafik, bukan kombinasi warna mereka.

Anda dapat mengasumsikan bahwa gambar input memiliki lebar yang sama, bahwa semua kolom gambar memiliki setidaknya satu piksel non-putih, dan bahwa ketinggian gambar (termasuk output) di bawah 4096 piksel.

Contoh

Input A:

contoh grafik a

Input B:

contoh grafik b

Contoh output:

contoh jumlah grafik

(Jika seseorang tertarik, saya menyalin-menempelkan data ini dari grafik saham perusahaan acak. Itu adalah cara pertama yang saya temukan untuk mendapatkan data realistis sebagai CSV.)

Aturan

  • Anda dapat memilih format file input gambar bitmap apa pun.
  • Anda dapat memilih format file output gambar bitmap apa pun, yang tidak harus cocok dengan input.
  • Anda dapat menggunakan pustaka pemrosesan gambar, namun fungsi apa pun untuk menyelesaikan tugas ini secara langsung dilarang.
  • Celah standar berlaku.
  • Ini adalah , jadi kode terpendek dalam byte menang.

Script pembuat grafik

Berikut ini adalah skrip Python 2 yang menghasilkan grafik. Input diberikan dalam garis, dengan tiga baris pertama sebagai warna RGB dan sisanya sebagai data, diakhiri oleh 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")
PurkkaKoodari
sumber
@ MartinBüttner Saat ini saya membuat satu untuk dua grafik. Saya melakukannya dengan tangan (belum ada rujukan referensi), jadi saya tidak tahu apakah saya memiliki kesabaran untuk 3. Juga, tiga yang saya berikan tidak dapat dijumlahkan karena mereka memiliki lebar yang berbeda.
PurkkaKoodari
Jadi jika ada ngrafik input, akan ada 2^n - 1garis di gambar output?
Peter Taylor
@PeterTaylor Ya.
PurkkaKoodari
Saya mengambil output tidak benar-benar perlu mengandung garis vertikal? Hanya piksel paling atas di setiap kolom?
Martin Ender
@ MartinBüttner Itu benar, karena data itu masih dapat diuraikan sebagai grafik seperti yang didefinisikan pada bagian pertama.
PurkkaKoodari

Jawaban:

3

MATLAB, 405

Hubungi via: 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')
knedlsepp
sumber
4

Python, 422

Panggilan dari commandline 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

Contoh output Contoh
masukkan deskripsi gambar di sini
lain
masukkan deskripsi gambar di sini

Itu yang rumit, operasi array tingkat tinggi dan menggunakan array karena indeks sangat membantu di sini. Saya tidak berharap untuk melihat solusi di bawah 1000 byte kecuali di Mathematica dan Matlab

DenDenDo
sumber