Farbige Graphen summieren

9

In einigen Fällen, oft in der Physik, müssen Sie Graphen summieren. Ihre Herausforderung besteht darin, in einer Sprache Ihrer Wahl ein Programm oder eine Funktion zu schreiben, die mehrere Grafiken als Bilder verwendet, alle möglichen Summen berechnet und das Ergebnis ausgibt.

Grafiken

Die Grafiken sind Bilder, die einen weißen ( rgb(255, 255, 255)) Hintergrund mit einem nicht weißen Pixel in jeder Spalte enthalten. Beispiele:

Beispielgraph Beispielgraph Beispielgraph

Die Werte des Skripts werden als Y-Positionen der farbigen Pixel dargestellt. Der Wert an einer bestimmten X-Koordinate entspricht der Y-Position des obersten farbigen Pixels in dieser Spalte, wobei die Koordinaten unten links bei 0 beginnen. Aus ästhetischen Gründen können unter diesen Pixeln zusätzliche farbige Pixel vorhanden sein oder nicht.

Aufgabe

Ihre Aufgabe ist es, in einer Sprache Ihrer Wahl ein Programm oder eine Funktion zu schreiben, die mehrere Grafiken als Bilder verwendet, alle möglichen 2^n - 1Summen berechnet und das Ergebnis ausgibt.

Eine Summe von Diagrammen ist ein Diagramm, bei dem der Wert jeder Spalte gleich der Summe der Werte der entsprechenden Spalte in jedem der Eingabediagramme ist.

Die Grafiken werden in mehreren Farben geliefert. Das Ergebnisbild muss alle möglichen Summen der Diagramme wie andere Diagramme enthalten, einschließlich der Originaldiagramme, jedoch ohne die Nullsumme.

Die Farbe jeder Summe wird durch den Durchschnitt der Farben der enthaltenen Diagramme bestimmt, beispielsweise Farbdiagramme, rgb(255, 0, 255)und rgb(0, 255, 255)würde ein Diagramm von erzeugen rgb(128, 128, 255)(kann auch abgerundet werden).

Das resultierende Bild sollte so hoch sein, wie es für alle Diagramme erforderlich ist. Dies bedeutet, dass Sie möglicherweise ein Bild ausgeben müssen, das größer als eine der Eingaben ist.

Die Reihenfolge, in der die resultierenden Diagramme in das resultierende Bild gezeichnet werden, spielt keine Rolle. Wenn sich die Ergebnisdiagramme überlappen, können Sie auswählen, welches oben liegt. Es muss sich jedoch um eines der Diagramme handeln, nicht um eine Kombination ihrer Farben.

Sie können davon ausgehen, dass die Eingabebilder gleich breit sind, dass alle Spalten der Bilder mindestens ein nicht weißes Pixel haben und dass die Höhe der Bilder (einschließlich der Ausgabe) unter 4096 Pixel liegt.

Beispiel

Eingabe A:

Beispielgraph a

Eingang B:

Beispielgraph b

Beispielausgabe:

Beispiel Graph Summe

(Falls jemand interessiert ist, habe ich die Daten für diese aus den Aktiencharts zufälliger Unternehmen kopiert. Dies war der erste Weg, um realistische Daten als CSV zu erhalten.)

Regeln

  • Sie können ein beliebiges Bitmap-Bildeingabedateiformat auswählen.
  • Sie können ein beliebiges Bitmap-Bildausgabedateiformat auswählen, das nicht mit der Eingabe übereinstimmen muss.
  • Sie können Bildverarbeitungsbibliotheken verwenden, jedoch sind alle Funktionen zum direkten Ausführen dieser Aufgabe gesperrt.
  • Es gelten Standardlücken .
  • Dies ist , also gewinnt der kürzeste Code in Bytes.

Graphgeneratorskript

Hier ist ein Python 2-Skript, das Diagramme generiert. Die Eingabe erfolgt in Zeilen, wobei die drei ersten Zeilen als RGB-Farbe und der Rest als Daten als EOF abgeschlossen werden.

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
quelle
@ MartinBüttner Ich mache gerade eins für zwei Graphen. Ich mache es von Hand (noch kein Referenz-Impl), daher weiß ich nicht, ob ich die Geduld für 3 habe. Außerdem können die drei, die ich gegeben habe, nicht summiert werden, da sie unterschiedliche Breiten haben.
PurkkaKoodari
Wenn also nEingabegraphen vorhanden sind , enthält 2^n - 1das Ausgabebild Linien?
Peter Taylor
@ PeterTaylor Ja.
PurkkaKoodari
Ich nehme an, die Ausgabe muss eigentlich keine vertikalen Linien enthalten? Nur das oberste Pixel in jeder Spalte?
Martin Ender
@ MartinBüttner Das ist richtig, da diese Daten weiterhin als Grafik analysiert werden können, wie im ersten Abschnitt definiert.
PurkkaKoodari

Antworten:

3

MATLAB, 405

Anruf über: 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
quelle
4

Python, 422

Anruf von der Kommandozeile 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

Beispielausgabe
Geben Sie hier die Bildbeschreibung ein
Ein weiteres Beispiel
Geben Sie hier die Bildbeschreibung ein

Das war eine knifflige Array-Operation auf hoher Ebene, und die Verwendung von Arrays als Indizes hilft hier sehr. Ich erwarte keine Lösungen unter 1000 Bytes außer in Mathematica und Matlab

DenDenDo
quelle