Dada uma imagem que possui apenas pixels preto e branco e um local (x, y) que é um pixel branco, pinte os pixels brancos com base na distância mínima de Manhattan de (x, y) em um caminho que envolva apenas o deslocamento de outros pixels brancos.
A tonalidade dos pixels coloridos deve ser proporcional à sua distância de (x, y), para que o pixel em (x, y) tenha uma tonalidade de 0 ° (vermelho puro) e os pixels mais distantes de (x, y) terá um matiz de 360 ° (também vermelho), com os outros matizes se mesclando de maneira uniforme e linear no meio. A saturação e o valor devem ser 100%.
Se um pixel branco não estiver conectado a (x, y) por outros pixels brancos, ele deverá permanecer em branco.
Detalhes
- A entrada consistirá no nome do arquivo da imagem ou nos dados brutos da imagem, além dos números xey.
- A imagem de saída pode ser salva em um arquivo ou em bruto para stdout em qualquer formato de arquivo de imagem comum ou simplesmente exibida.
- O valor x é 0 nos pixels mais à esquerda e aumenta para a direita. O valor y é 0 nos pixels mais altos e aumenta a diminuir. (x, y) estará sempre nos limites da imagem.
- Programas e funções completos são permitidos.
O código mais curto em bytes vence.
Exemplos
Todas essas imagens foram reduzidas para economizar espaço. Clique neles para ver em tamanho real.
Imagem de entrada:
(x,y) = (165,155)
e (x,y) = (0,0)
Entrada de imagem e saída com (x,y) = (0,0)
:
Entrada de imagem e saída com (x,y) = (600,350)
:
Entrada de imagem e saída com (x,y) = (0,0)
:
Entrada de imagem e saída com (x,y) = (0,0)
:
Bônus opcional de -30%: use a distância euclidiana. Uma sugestão para o seu algoritmo é a seguinte (descrição geral):
- Tenha um pixel inicial.
- Preenchimento a partir desse pixel.
- Para cada pixel atingido no preenchimento de inundação,
- Mova do pixel inicial para o pixel em etapas de meia unidade, em uma linha reta.
- Em cada etapa, aplique
int()
às coordenadas x e y. Se o pixel nessas coordenadas for preto, pare. Caso contrário, continue. (Este é um método de linha de visão.) - Qualquer pixel atingido que contorne um pixel branco e / ou um pixel que foi rotulado anteriormente com uma distância significativamente maior (ou seja, +10) se torna um pixel inicial.
Em um sentido mais meta, esse algoritmo se espalha para todos os pixels acessíveis em uma linha reta a partir de pixels iniciais / já coloridos, e então "polegadas" em torno das bordas. O bit "distância significativamente maior" destina-se a acelerar o algoritmo. Honestamente, realmente não importa como você implementa a distância euclidiana, apenas tem que se parecer com isso.
É assim que o primeiro exemplo se parece com a distância euclidiana, usando o algoritmo acima:
Insira a imagem e (x,y) = (165,155)
Muito obrigado ao Calvin'sHobbies e ao trichoplax por ajudar a escrever esse desafio! Diverta-se!
fonte
Respostas:
Matlab,
255 245231 bytesIsso espera o nome da imagem primeiro, depois
y
e depoisx
.Eu implementei o preenchimento de inundação (ou 'dijkstra para 4 vizinhanças', se você quiser), primeiro criando uma máscara em que o pixel inicial é definido como 1 e com um acumulador de distância (ambos do tamanho da imagem) e depois repetindo o seguinte passos:
k
k
Isso nos deixa com as distâncias de manhattan de cada pixel até o pixel inicial no acumulador de distância. Em seguida, criamos uma nova imagem percorrendo o intervalo de cores especificado e mapeamos a "primeira" tonalidade para o valor zero e a "última" tonalidade para a distância máxima.
Exemplos
Como um bônus, aqui está uma bela imagem de como a distância é calculada. mais brilhante = mais longe.
fonte
Blitz 2D / 3D , 3068 * 0,7 = 2147,6
Esta é a implementação de referência para o algoritmo euclidiano, golfed.
Na verdade, eu odeio o quão ilegível isso é comparado ao original. (Que são, aliás, 5305 bytes.) Na verdade, eu poderia cortar mais alguns bytes usando nomes de variáveis de um caractere para tudo, mas isso já é bastante ridículo. E não está ganhando tão cedo. : P
fonte
C ++ / SFML:
127112351226 bytes-36 bytes graças a user202729 -9 bytes graças a Zacharý
O
sf::Image
parâmetro também é a saída (será modificado). Você pode usá-lo assim:O primeiro parâmetro é a entrada (e a saída) da imagem, o segundo e o terceiro parâmetros são o parâmetro
x
ey
onde ele precisa iniciarfonte
setPixel(j, i,hsv2
eFI(xm,ym) (std::find_if
realmente necessário?G(d,a,b,c)
ecase d:
. Além disso, o espaço entrecase d:
e também nãoreturn C(a,b,c)
é necessário.(b>m?b:m)
não requer parênteses e(t/60)%6
=>t/60%6
por ordem das operações.xm
eym
a nomes de variáveis mais curtosG(d,a,b,c)
ecase
,FI
,ti
, ehsv2rgb
cada um pode ser substituído por um nome mais curto.C ++,
97996989885298bytesRGBARGB (produzido no arquivo: d)Não é exatamente um "ungolf" direto, mas esse foi um protótipo C que eu zombei primeiro:
Muitos conceitos permanecem semelhantes, mas há certamente uma miríade de pequenas mudanças. Para compilar que, como C, você precisa usar o C11 (o C99 provavelmente funcionará, mas eu apenas testei estritamente no C11).
Gostei muito desse desafio, obrigado por me dar a ideia de experimentar algo novo :).
Edit: Golf'd um pouco melhor.
Edit2: Mesclou duas estruturas para que minha estrutura e fila de pixels sejam as mesmas, pouco mais abuso de macro e refluxou os usos de 255, de modo que pode ser definido como -1 ao definir uma série de caracteres não assinados e, por fim, removi uma chamada de função.
Edit3: Reutilizou mais algumas variáveis, ajustes de precedência do operador e saída convertida em RGB, salvando o canal alfa
Edit4: Acho que já acabei com isso agora, algumas alterações aritméticas dos ponteiros e pequenos ajustes no fluxo de controle.
fonte
Python 3 e matplotlib, 251 bytes
A entrada é uma matriz numpy MxNx3, conforme retornada pela
imshow()
função matplotlib . A entrada é modificada pela função e, portanto, deve ser copiada previamente. Ele exibe a imagem automaticamente se o matplotlib estiver no modo "interativo"; caso contrário, uma chamada parashow()
deve ser adicionada por mais 7 bytes.A saída é criada exibindo primeiro a imagem original e depois a imagem do arco-íris sobre ela. O Matplotlib trata convenientemente inf e nan como transparentes, para que a imagem em preto e branco seja exibida.
fonte