Підведення підсумків кольорових графіків


9

У деяких випадках, часто з фізики, доводиться підсумовувати графіки. Ваше завдання полягає в тому, щоб написати мовою на вашу вибір програму або функцію, яка сприймає кілька графіків як зображення, обчислює всі можливі суми та видає результат.

Графіки

Графіки - зображення, які містять білий ( rgb(255, 255, 255)) фон із небілим пікселем у кожному стовпчику. Приклади:

приклад графіка приклад графіка приклад графіка

Значення сценарію представлені у вигляді Y-позицій кольорових пікселів. Значення на певній координаті X дорівнює положенню Y самого верхнього кольорового пікселя в цьому стовпчику, координати починаються від 0 внизу зліва. Можливо, з естетичних причин можуть бути додаткові кольорові пікселі нижче цих пікселів.

Завдання

Ваше завдання полягає в тому, щоб написати мовою, яку ви обрали, програму чи функцію, яка сприймає кілька графіків як зображення, обчислює всі можливі 2^n - 1суми та видає результат.

Сума графіків - це графік, де значення кожного стовпця дорівнює сумі значень відповідного стовпця у кожному з вхідних графіків.

Графіки вийдуть у декількох кольорах. Результатне зображення повинно містити всі можливі суми графіків у вигляді інших графіків, включаючи оригінальні графіки, але виключаючи нульову суму.

Колір кожної суми визначається середнім значенням кольорів графіків, що включаються, наприклад, графіки кольорів rgb(255, 0, 255)і rgb(0, 255, 255)дають графік rgb(128, 128, 255)(може також округлятися вниз).

Отримане зображення має бути настільки високим, скільки потрібно для розміщення всіх графіків. Це означає, що вам, можливо, доведеться вивести зображення, яке перевищує будь-який з входів.

Порядок, в якому малюються отримані графіки до отриманого зображення, не має значення, тобто якщо графіки результатів перекриваються, ви можете вибрати, який з них знаходиться вгорі, але він повинен бути одним із графіків, а не комбінацією їх кольорів.

Ви можете припустити, що вхідні зображення мають однакову ширину, що всі стовпці зображень мають принаймні один небілий піксель, а висота зображень (включаючи вихідні) нижче 4096 пікселів.

Приклад

Введення A:

приклад графіку a

Введення B:

приклад графіку b

Приклад виводу:

Приклад графної суми

(Якщо хтось зацікавився, я скопіював ці дані для них з фондових діаграм випадкових компаній. Це був перший спосіб, коли я знайшов реалістичні дані як CSV.)

Правила

  • Ви можете обрати будь-який формат вхідного зображення зображення.
  • Ви можете вибрати будь-який формат вихідного файлу растрового зображення, який не повинен відповідати вхідному.
  • Ви можете використовувати бібліотеки обробки зображень, однак будь-які функції безпосередньо для виконання цього завдання заборонені.
  • Застосовуються стандартні лазівки .
  • Це є , тому виграє найкоротший код у байтах.

Сценарій генератора графіків

Ось сценарій Python 2, який генерує графіки. Введення подається у рядках, три перші рядки як колір RGB, а решта як дані, що закінчуються 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 Я зараз роблю один на два графіки. Я роблю це вручну (ще немає посилання на імпл), тому я не знаю, чи маю терпіння для 3. Також три, які я дав, не можна підсумовувати, оскільки вони різної ширини.
PurkkaKoodari

Отже, якщо є nвхідні графіки, 2^n - 1у вихідному зображенні будуть рядки?
Пітер Тейлор

@PeterTaylor Так.
PurkkaKoodari

Я вважаю, що висновок насправді не повинен містити вертикальних ліній? Лише самий верхній піксель у кожному стовпчику?
Мартін Ендер

@ MartinBüttner Це правильно, оскільки ці дані все ще можна проаналізувати як графік, як визначено в першому розділі.
PurkkaKoodari

Відповіді:


3

МАТЛАБ, 405

Телефонуйте через: 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

Пітона, 422

Виклик з командної лінії 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

Приклад виведення
введіть тут опис зображення
Інший приклад
введіть тут опис зображення

Це було складним, операції з масивом на високому рівні та використання масивів як індексів тут дуже допомагає. Я не сподіваюся побачити рішення під 1000 байтів, за винятком Mathematica та Matlab

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.