Joe, a cobra, está com fome.
Ele come fotos, um pixel de cada vez.
Ele realmente gosta de pixels brilhantes.
O desafio
Programe Joe para comer os pixels mais brilhantes que conseguir encontrar, pois ele só pode se mover para cima, baixo, esquerda ou direita.
Especificações
- Joe deve começar no pixel superior esquerdo da imagem.
- Joe só pode se mover horizontalmente ou verticalmente por 1 cada movimento
- Joe tem apenas tempo suficiente para mover 1/3 da quantidade de pixels na imagem (1/3 do número de movimentos que pixels). Se o número de pixels não for múltiplo de 3, arredonde para o número inteiro mais próximo.
- Joe pode cruzar seu caminho, embora isso conte como 0 brilho
- O brilho é baseado na soma de r, g e b, de modo que rgb (0,0,0) possui um brilho de 0 enquanto rgb (255,255,255) possui brilho máximo.
Entrada
Você pode inserir a imagem como quiser.
Saída
- uma imagem mostrando o resultado final da sua foto (com pixels sendo comidos em preto).
- A quantidade de brilho consumida (especifique qual intervalo em sua resposta)
Pontuação
Seu programa será classificado em:
- O brilho médio dos pixels que Joe come / O brilho médio dos pixels na imagem *
* você pode codificar isso no seu programa
Sua pontuação total será a média das pontuações das seguintes imagens:
Imagens de teste:
http://upload.wikimedia.org/wikipedia/en/thumb/f/f4/The_Scream.jpg/800px-The_Scream.jpg
code-challenge
image-processing
Stretch Maniac
fonte
fonte
[![image description](SE URL for downsized image)](URL for original image)
.Respostas:
C ++, Pontuação:
1.420421.46766Esta é essencialmente uma versão um pouco mais sofisticada das duas soluções existentes: Dos quatro movimentos possíveis, ele seleciona aquele que maximiza o brilho. No entanto, em vez de apenas observar o brilho do pixel de destino, ele analisa a soma ponderada de brilho de pixel na vizinhança do pixel de destino, onde os pixels mais próximos do alvo têm um peso maior.
EDIT: O uso do brilho não linear no cálculo da vizinhança melhora um pouco a pontuação.
Compile com
g++ joe.cpp -ojoe -std=c++11 -O3 -lcairo
. Requer cairo.Corra com
joe <image-file> [<radius>]
.<image-file>
é a imagem PNG de entrada.<radius>
(argumento opcional) é o raio da vizinhança resumida, em pixels (menor é mais rápido, maior é (aproximadamente) melhor).) Emite a pontuação e uma imagem chamadaout.<image-file>
.Resultados
Mais colírio para os olhos
fonte
if (o_neighborhood > o_max_neighborhood) o_max = *o, o_max_neighborhood = o_neighborhood;
apenas este código o define. no entanto, devido ao nan envolvido, a comparação é sempre falsa, portanto o_max nunca é definido e usado não inicializado.Python 3, pontuação = 1,57
Primeiro, nossa cobra viaja pela imagem, criando linhas verticais com a mesma distância uma da outra.
Podemos estender essa cobra colocando dois pontos próximos um do outro em uma linha vertical e criando um loop cujos pontos finais são eles.
Organizamos os pontos em pares e, para cada par, armazenamos o tamanho e o valor médio de brilho do loop, que fornece o maior brilho médio.
A cada passo, escolhemos o par com o valor mais alto, estendendo seu loop para obter o brilho médio máximo na extensão e calculando o novo tamanho de loop e valor de brilho ideais para o par.
Armazenamos os trigêmeos (value, size, point_pair) em uma estrutura de heap classificada por valor, para que possamos remover o elemento maior (em O (1)) e adicionar o novo elemento modificado (em O (log n)) com eficiência.
Paramos quando atingimos o limite de contagem de pixels e essa cobra será a cobra final.
A distância entre as linhas verticais tem muito pouco efeito nos resultados, portanto, uma constante de 40 pixels foi escolhida.
Resultados
Nota: a imagem original "The Scream" não estava disponível, então usei outra imagem "The Scream" com resolução semelhante.
Gif mostrando o processo de extensão da cobra na imagem "redemoinho":
O código pega um (ou mais espaços) nome do arquivo stdin e grava as imagens de cobra resultantes em arquivos png e imprime as pontuações no stdout.
fonte
Python 2 (pontuação: 0.0797116)
Apenas um algoritmo ganancioso muito simples e ingênuo para fazer a bola rolar.
Saída:
fonte
sum of brightnesses of eaten pixels / amount of eaten pixels
é a fórmula certa, correto? Talvez seja apenas um algoritmo realmente terrível;)The average brightness of pixels Joe eats / The average brightness of the pixels in the picture*
Java (pontuação: 0.6949)
Um algoritmo simples que obtém o pixel mais brilhante dos quatro pixels ao redor do pixel atual. No caso de empate, o pixel comido é aleatório, levando a pontuações diferentes e imagens resultantes a cada execução. Assim, as pontuações abaixo são as médias de mais de 50 execuções em cada imagem.
Para executá-lo, edite os três argumentos (existentes como constantes de classe) na fonte ou passe-os por linha de comando no formulário
java HungryImageSnake <source> <iterations> <printScores>
onde<source>
está o arquivo de origem da imagem a ser consumida,<iterations>
é o número de vezes em que a imagem é consumida (usando a pontuação média e salvando a melhor pontuação em todas as iterações) e<printScores>
é verdadeiro imprimir a pontuação de cada iteração ou falso em não.Pontuações médias, por imagem, em mais de cinquenta iterações:
Melhores pontuações, por imagem, nas mesmas cinquenta iterações:
As imagens das execuções com maior pontuação:
Como é evidente nas imagens, muito menos de um terço dos pixels são realmente consumidos, pois a cobra ocasionalmente fica presa entre os pixels que já ingeriu, nos quais permanece presa na área morta até que a aleatoriedade de seus movimentos a faça cair. uma parte comestível da imagem.
Também como resultado dos pixels que a cobra comeu novamente, as pontuações são enviesadas para baixo, pois o brilho zero dos pixels mortos é novamente considerado na média. Eu esperaria ver pontuações muito mais altas se o algoritmo de pontuação fosse modificado para dividir apenas pelo número de movimentos que levaram a comer novos pixels, em vez de todos os movimentos (incluindo aqueles em que a cobra come um pixel agora morto que ele havia comido antes )
Obviamente, uma abordagem melhor seria criar algum tipo de heurística de brilho para cada pixel e encontrar o caminho dos
width * height / 3
pixels com o brilho médio mais alto, mas duvido que essa abordagem seja ideal em tempo de execução, especialmente em imagens maiores, como o número possíveis permutações seria muito grande. Posso tentar alguma forma dessa abordagem posteriormente e publicá-la em uma resposta separada, se for o caso.fonte
Python 2, Pontuação: 1.205
Eu montei uma solução rápida em Python há algum tempo, mas esqueci de publicá-la. Aqui está. Ele encontra os blocos mais ricos da imagem e viaja para cada bloco, comendo todos os melhores blocos.
Resultados
Exemplo de imagem
Código Python 2.7
fonte