Renkli grafikleri toplama


9

Bazı durumlarda, genellikle fizikte, grafikleri toplamalısınız. Zorluk, seçtiğiniz bir dilde, birden çok grafiği resim olarak alan, olası tüm toplamları hesaplayan ve sonucu çıktılayan bir program veya işlev yazmaktır.

Grafikler

Grafikler, rgb(255, 255, 255)her sütunda beyaz olmayan bir piksele sahip beyaz ( ) bir arka plan içeren görüntülerdir . Örnekler:

örnek grafik örnek grafik örnek grafik

Komut dosyasının değerleri, renkli piksellerin Y konumları olarak temsil edilir. Belirli bir X koordinatındaki değer, o sütundaki en üstteki renkli pikselin Y konumuna eşittir, koordinatlar sol altta 0'dan başlar. Estetik nedenlerle bu piksellerin altında ek renkli pikseller olabilir veya olmayabilir.

Görev

Göreviniz, seçtiğiniz bir dilde, birden çok grafiği resim olarak alan, olası tüm 2^n - 1toplamları hesaplayan ve sonucu çıktılayan bir program veya işlev yazmaktır .

Grafiklerin toplamı, her bir sütunun değerinin, girdi grafiklerinin her birinde karşılık gelen sütunun değerlerinin toplamına eşit olduğu bir grafiktir.

Grafikler birden fazla renkte gelecek. Sonuç resmi, orijinal grafikler de dahil olmak üzere, ancak sıfır toplamı hariç olmak üzere, grafiklerin olası tüm toplamlarını içermelidir.

Her bir toplamın rengi, dahil edilen grafiklerin renklerinin ortalaması ile belirlenir, örneğin renk grafikleri rgb(255, 0, 255)ve rgb(0, 255, 255)bir grafik oluşturur rgb(128, 128, 255)(ayrıca yuvarlanabilir).

Ortaya çıkan görüntü, tüm grafiklere sığacak kadar yüksek olmalıdır. Bu, herhangi bir girişten daha büyük bir görüntü vermeniz gerekebileceği anlamına gelir.

Elde edilen grafiklerin elde edilen görüntüye çekilme sırası önemli değildir, yani sonuç grafikleri çakışıyorsa hangisinin üstte olacağını seçebilirsiniz, ancak renklerin bir kombinasyonu değil, grafiklerden biri olması gerekir.

Giriş görüntülerinin eşit genişlikte olduğunu, görüntülerin tüm sütunlarının en az bir beyaz olmayan piksele sahip olduğunu ve görüntülerin yüksekliklerinin (çıktı dahil) 4096 pikselin altında olduğunu varsayabilirsiniz.

Misal

Giriş A:

örnek grafik a

Giriş B:

örnek grafik b

Örnek çıktı:

örnek grafik toplamı

(Birinin ilgilenmesi durumunda, bunların verilerini rasgele şirketlerin hisse senedi grafiklerinden kopyaladım. CSV olarak gerçekçi veri elde etmenin ilk yolu buydu.)

kurallar

  • Herhangi bir bitmap görüntü giriş dosyası formatı seçebilirsiniz.
  • Girişle eşleşmesi gerekmeyen herhangi bir bitmap görüntü çıktısı dosya biçimi seçebilirsiniz.
  • Görüntü işleme kütüphanelerini kullanabilirsiniz, ancak bu görevi doğrudan tamamlamak için herhangi bir işlev yasaklanmıştır.
  • Standart boşluklar geçerlidir.
  • Bu , bayttaki en kısa kod kazanır.

Grafik oluşturucu komut dosyası

İşte grafikler üreten bir Python 2 betiği. Girdi, EOF tarafından sonlandırılan ilk üç satır RGB rengi ve geri kalan veri olarak satırlar halinde verilir.

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 Şu anda iki grafik için bir tane yapıyorum. Elle yapıyorum (henüz referans impl yok), bu yüzden 3 için sabrım olup olmadığını bilmiyorum. Ayrıca, verdiğim üç farklı genişliklerde oldukları için toplanamıyor.
PurkkaKoodari

Vardır Yani eğer ngirdi grafikleri, orada olacağım 2^n - 1çıktı resimlerdeki çizgiler?
Peter Taylor

@PeterTaylor Evet.
PurkkaKoodari

Çıktının aslında dikey çizgiler içermesine gerek yok mu? Her sütunda yalnızca en üstteki piksel mi?
Martin Ender

@ MartinBüttner Bu doğrudur, çünkü bu veriler ilk bölümde tanımlandığı gibi bir grafik olarak ayrıştırılabilir.
PurkkaKoodari

Yanıtlar:


3

MATLAB, 405

Şununla ara: 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

Komut satırından arama 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

Örnek çıktı
resim açıklamasını buraya girin
Başka bir örnek
resim açıklamasını buraya girin

Zor bir işlemdi, üst düzey dizi işlemleri ve dizileri dizin olarak kullanmak burada çok yardımcı oluyor. Mathematica ve Matlab hariç 1000 baytın altındaki çözümleri görmeyi beklemiyorum

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.