Prefácio
Como eu estava disparando um tiro com arco 900 no início de hoje (10 termina em 6 flechas por fim e 10 termina em 3 flechas por fim, num total de 90 flechas e uma pontuação máxima de 900), pensei nesse desafio.
No arco e flecha (supondo que você esteja atirando em uma face-alvo fornecida pela FITA [o pedaço de papel em que você dispara]), para cada flecha você pode obter uma pontuação máxima de 10. A face-alvo contém 10 ou 11 anéis de diâmetro decrescente, aninhados um dentro do outro. Do anel interno para fora, eles são contados de 10 pontos a um ponto (e no caso de 11 anéis, existe um anel interno secundário que conta como 'X', que tem 10 pontos, mas é usado em casos de desempate como o valor mais alto). Observar:
Obviamente, estou me referindo à pontuação do FITA Metric, como visto na ilustração acima. Se você olhar atentamente, poderá observar o anel mais interno, que é uma linha pontilhada desbotada, cuja pontuação não está marcada. Esse é o 'X' ao qual eu estava me referindo, mas você não terá que prestar atenção a menos que esteja competindo pelo bônus.
Desafio
Crie uma função (ou programa completo, se o idioma não suportar funções), que receba uma imagem perfeitamente quadrada como entrada (ou nome do arquivo da imagem, se necessário), contendo algum número de verde (HEX # 00FF00, RGB (0, 255, 0)) pontos de algum tamanho e retorna a pontuação. A imagem pode conter dados que não sejam os pontos verdes , mas o verde sempre terá exatamente a mesma tonalidade.
Você pode imaginar que a imagem quadrada representa a face do alvo, com o anel mais externo tocando em 4 pontos (centro superior, centro inferior, centro direito, centro esquerdo). A face do destino representada sempre terá a mesma proporção, com todos os anéis com uma largura de exatamente 1/20 da largura da imagem de destino da entrada. Como exemplo, dada uma imagem de entrada com dimensões de 400px por 400px, você pode supor que cada anel tenha uma largura interna de 20px, conforme ilustrado abaixo:
Esclarecimentos
- Se tocar em dois anéis separados, o mais alto dos dois anéis será contado
- Você não precisa contabilizar automaticamente os erros ou o caso 'x', a menos que tente o bônus
- Você pode assumir que nenhum círculo verde se sobrepõe
- Você também pode assumir que nenhum outro pixel dessa tonalidade de verde está na imagem
- A imagem estará no formato PNG, JPEG ou PPM (sua escolha)
- Bibliotecas de processamento de imagem externas são permitidas, se criadas antes da publicação desta pergunta
- Você pode assumir que todos os círculos verdes em um alvo terão o mesmo diâmetro
- Se fotografar (hah) pelo bônus de círculos sobrepostos, você pode assumir que pelo menos um círculo na imagem não possui outro sobreposto
- As brechas padrão não são permitidas
Casos de teste
Os dois casos a seguir devem pontuar 52 (ou, no caso de bônus, 52 com 1 'x' e 1 falta):
E este último caso de teste deve marcar 25 :
Bônus
- -25 bytes se você também retornar o número de erros (fora de qualquer um dos toques) também
- -30 bytes se você também retornar a quantidade de Xs (suponha que o x mais interno seja 3 / 100º da largura da imagem e 10 seja 2 / 100º da largura da imagem. As proporções de 1 a 9 permanecem inalteradas)
- -35% de contagem de bytes, se você considerar círculos sobrepostos
Isso é código de golfe, então o mínimo de bytes vence. Diverta-se!
fonte
Respostas:
Processando 2, 448-25 = 423 bytes
Lê em um arquivo de imagem f percorre os pixels até que fique verde e depois a inundação preenche o círculo, determinando o ponto mais próximo do centro. Em seguida, adiciona essa pontuação a um total. se a pontuação for negativa, ela é adicionada a um contador de erros.
O programa produzirá 2 números, o primeiro é o placar e o segundo é o número de erros.
você pode obter o processamento aqui
fonte
Perl 5 + GD: 225-25 = 200
Editar: localizou o motivo da leitura incorreta de pixels em PNGs indexados e aplicou uma solução alternativa.
Por alguma razão, com a biblioteca GD, os valores de pixel verde são lidos como (4.254,4). Não tenho certeza se isso é específico para os arquivos PNG incluídos na pergunta.Quebras de linha podem ser removidas no código abaixo.Tira uma imagem PNG na entrada e imprime 2 valores: Número de pontos e erros. Por exemplo:
Alteração de última hora:
No modo de cores verdadeiras que eu precisava, os índices de cores usados
getPixel
efill
são simplesmente valores RGB codificados por números inteiros, portanto, não é necessáriorgb
ecolorAllocate
converter e converter para esses índices.Explicação:
sub v
que leva o parâmetro até$_
vez dos parâmetros padrão, pois é mais curto).fonte
Haskell -
579-25 = 554603-25-30576-25-30 = 521 bytesEstratégia:
O resultado é um triplo (pontuação, falha, Xs), por exemplo
(52,1,1)
para a imagem de teste.O programa poderá falhar se o pixel de um círculo mais próximo do centro estiver a 3 pixels de outro círculo.
fonte
all id
é o mesmo queand
.also, você pode implementarj
com guardas de padrãoj n m|PixelRGBA8 0 255 0 _<-getColor n m v=0<1|0<1=0>1
Mathematica -
371386 - 25 = 361Uma solução mais ideal. Calcula a resposta muito mais rapidamente que minha solução Python.
Python com PIL - Uma solução trivial e não ideal, 961 bytes
Isso é simplesmente para tentar demonstrar uma abordagem boba para resolver o problema. Demora ~ 2 minutos para executar os dois primeiros casos de teste e ~ 20 minutos para executar o terceiro no meu sistema por causa do detector de círculo rapidamente inventado, com grande demanda de recursos e complexo de algoritmos repulsivamente. Apesar disso, ele atende aos requisitos, embora certamente não seja um golfe ideal. Quanto mais verde houver na imagem, mais tempo levará para ser executado.
Pega um objeto de imagem PIL e retorna a pontuação.
Passos necessários:
n
, se houver pixels verdes, adicione-os ao círculofonte
a
pode ser escrita comoa=lambda x,y,w,h:[(X,Y)for X in(x-1,x,x+1)for Y in(y-1,y,y+1)if w>X>-1<Y<h]