Sumar gráficos coloreados

9

En algunos casos, a menudo en física, tienes que sumar gráficos. Su desafío es escribir, en el idioma que elija, un programa o función que tome múltiples gráficos como imágenes, calcule todas las sumas posibles y genere el resultado.

Gráficos

Los gráficos son imágenes que contienen un rgb(255, 255, 255)fondo blanco ( ) con un píxel no blanco en cada columna. Ejemplos:

gráfico de ejemplo gráfico de ejemplo gráfico de ejemplo

Los valores de la secuencia de comandos se representan como las posiciones Y de los píxeles coloreados. El valor en una determinada coordenada X es igual a la posición Y del píxel de color superior en esa columna, con coordenadas que comienzan desde 0 en la parte inferior izquierda. Puede haber o no píxeles de color adicionales debajo de esos píxeles por razones estéticas.

Tarea

Su tarea es escribir, en el idioma que elija, un programa o función que tome múltiples gráficos como imágenes, calcule todas las 2^n - 1sumas posibles y genere el resultado.

Una suma de gráficos es un gráfico donde el valor de cada columna es igual a la suma de los valores de la columna correspondiente en cada uno de los gráficos de entrada.

Los gráficos vendrán en múltiples colores. La imagen resultante debe contener todas las sumas posibles de los gráficos como otros gráficos, incluidos los gráficos originales pero excluyendo la suma cero.

El color de cada suma está determinado por el promedio de los colores de los gráficos incluidos, por ejemplo, gráficos de colores rgb(255, 0, 255)y rgb(0, 255, 255)produciría un gráfico de rgb(128, 128, 255)(también puede redondearse hacia abajo).

La imagen resultante debe ser tan alta como sea necesaria para adaptarse a todos los gráficos. Esto significa que es posible que deba generar una imagen más grande que cualquiera de las entradas.

El orden en que se dibujan los gráficos resultantes a la imagen resultante no importa, es decir, si los gráficos resultantes se superponen, puede elegir cuál está en la parte superior, pero debe ser uno de los gráficos, no una combinación de sus colores.

Puede suponer que las imágenes de entrada tienen el mismo ancho, que todas las columnas de las imágenes tienen al menos un píxel no blanco y que las alturas de las imágenes (incluida la salida) están por debajo de 4096 píxeles.

Ejemplo

Entrada A:

ejemplo gráfico a

Entrada B:

ejemplo gráfico b

Salida de ejemplo:

ejemplo de suma de gráficos

(En caso de que alguien esté interesado, copié y pegué los datos de estos a partir de gráficos de acciones de compañías aleatorias. Esa fue la primera forma en que encontré para obtener datos realistas como CSV).

Reglas

  • Puede elegir cualquier formato de archivo de entrada de imagen de mapa de bits.
  • Puede elegir cualquier formato de archivo de salida de imagen de mapa de bits, que no tenga que coincidir con la entrada.
  • Puede usar bibliotecas de procesamiento de imágenes, sin embargo, cualquier función para completar esta tarea directamente está prohibida.
  • Se aplican lagunas estándar .
  • Este es el , por lo que gana el código más corto en bytes.

Script generador de gráficos

Aquí hay un script de Python 2 que genera gráficos. La entrada se da en líneas, con las tres primeras líneas como color RGB y el resto como datos, terminados por 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
fuente
@ MartinBüttner Actualmente estoy haciendo uno para dos gráficos. Lo hago a mano (todavía no hay referencia implícita), así que no sé si tengo paciencia para 3. Además, los tres que di no se pueden sumar ya que son de diferentes anchos.
PurkkaKoodari
Entonces, si hay ngráficos de entrada, ¿habrá 2^n - 1líneas en la imagen de salida?
Peter Taylor
@PeterTaylor Sí.
PurkkaKoodari
¿Supongo que la salida no necesita contener líneas verticales? ¿Solo el píxel superior en cada columna?
Martin Ender
@ MartinBüttner Eso es correcto, ya que esos datos aún se pueden analizar como un gráfico como se define en la primera sección.
PurkkaKoodari

Respuestas:

3

MATLAB, 405

Llamar a través de: 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
fuente
4

Python, 422

Llamar desde la línea de 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

Ejemplo de salida
ingrese la descripción de la imagen aquí
Otro ejemplo
ingrese la descripción de la imagen aquí

Esa fue una operación complicada, las operaciones de matriz de alto nivel y el uso de matrices como índices ayudan mucho aquí. No espero ver soluciones de menos de 1000 bytes, excepto en Mathematica y Matlab

DenDenDo
fuente