Sommando grafici colorati


9

In alcuni casi, spesso in fisica, devi sommare i grafici. La tua sfida è scrivere, in una lingua a tua scelta, un programma o una funzione che prende più grafici come immagini, calcola tutte le possibili somme e genera il risultato.

grafici

I grafici sono immagini che contengono uno rgb(255, 255, 255)sfondo bianco ( ) con un pixel non bianco in ogni colonna. Esempi:

grafico di esempio grafico di esempio grafico di esempio

I valori dello script sono rappresentati come posizioni Y dei pixel colorati. Il valore in corrispondenza di una determinata coordinata X è uguale alla posizione Y del pixel colorato più in alto in quella colonna, con coordinate che iniziano da 0 in basso a sinistra. Potrebbero esserci o meno pixel colorati aggiuntivi al di sotto di tali pixel per motivi estetici.

Compito

Il tuo compito è scrivere, in una lingua a tua scelta, un programma o una funzione che prende più grafici come immagini, calcola tutte le possibili 2^n - 1somme e genera il risultato.

Una somma di grafici è un grafico in cui il valore di ogni colonna è uguale alla somma dei valori della colonna corrispondente in ciascuno dei grafici di input.

I grafici verranno in più colori. L'immagine del risultato deve contenere tutte le possibili somme dei grafici come altri grafici, inclusi i grafici originali ma esclusa la somma zero.

Il colore di ogni somma è determinato dalla media dei colori dei grafici inclusi, ad esempio i grafici dei colori rgb(255, 0, 255)e rgb(0, 255, 255)produrrebbe un grafico di rgb(128, 128, 255)(può anche essere arrotondato per difetto).

L'immagine risultante dovrebbe essere alta quanto basta per adattarsi a tutti i grafici. Ciò significa che potrebbe essere necessario produrre un'immagine più grande di qualsiasi input.

L'ordine in cui i grafici risultanti vengono disegnati sull'immagine risultante non ha importanza, vale a dire se i grafici dei risultati si sovrappongono, è possibile scegliere quale si trova in cima, ma deve essere uno dei grafici, non una combinazione dei loro colori.

Si può presumere che le immagini di input abbiano la stessa larghezza, che tutte le colonne delle immagini abbiano almeno un pixel non bianco e che le altezze delle immagini (incluso l'output) siano inferiori a 4096 pixel.

Esempio

Ingresso A:

grafico di esempio a

Ingresso B:

esempio grafico b

Esempio di output:

somma del grafico di esempio

(Nel caso qualcuno fosse interessato, ho copiato e incollato i dati per questi da grafici azionari di società casuali. Questo è stato il primo modo che ho trovato per ottenere dati realistici come CSV.)

Regole

  • È possibile scegliere qualsiasi formato di file di input dell'immagine bitmap.
  • È possibile scegliere qualsiasi formato di file di output dell'immagine bitmap, che non deve corrispondere all'input.
  • È possibile utilizzare le librerie di elaborazione delle immagini, tuttavia è vietata qualsiasi funzione per completare direttamente questa attività.
  • Si applicano scappatoie standard .
  • Questo è , quindi vince il codice più breve in byte.

Script del generatore di grafici

Ecco uno script di Python 2 che genera grafici. L'input viene dato in righe, con le prime tre righe come colore RGB e il resto come dati, terminato da 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 Attualmente ne sto realizzando uno per due grafici. Lo sto facendo a mano (ancora nessun impianto di riferimento), quindi non so se ho la pazienza di 3. Inoltre, i tre che ho dato non possono essere sommati poiché hanno larghezze diverse.
PurkkaKoodari,

Quindi se ci sono ngrafici di input, ci saranno 2^n - 1linee nell'immagine di output?
Peter Taylor,

@PeterTaylor Sì.
PurkkaKoodari,

Presumo che l'output non abbia effettivamente bisogno di contenere linee verticali? Solo il pixel più in alto in ogni colonna?
Martin Ender,

@ MartinBüttner È corretto, dato che i dati possono ancora essere analizzati come un grafico, come definito nella prima sezione.
PurkkaKoodari,

Risposte:


3

MATLAB, 405

Chiama 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')

4

Python, 422

Chiama dalla riga di comando 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

Esempio di output
inserisci qui la descrizione dell'immagine
Un altro esempio
inserisci qui la descrizione dell'immagine

Questa è stata un'operazione complessa, operazioni di array di alto livello e l'uso di array come indici aiuta molto qui. Non mi aspetto di vedere soluzioni con meno di 1000 byte tranne Mathematica e Matlab

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.