Prefacio
Como estaba disparando un tiro de arco 900 hoy más temprano (10 termina con 6 flechas por final, y 10 termina con 3 flechas por final, para un total de 90 flechas y un puntaje máximo de 900), pensé en este desafío.
En tiro con arco (suponiendo que está disparando en una cara objetivo suministrada por FITA [la hoja de papel a la que dispara]), por cada flecha puede reclamar una puntuación máxima de 10. La cara objetivo contiene 10 u 11 anillos de diámetro decreciente, anidados uno dentro del otro. Desde el anillo interno hacia afuera, estos se cuentan de 10 puntos a un punto (y en el caso de 11 anillos, hay un anillo interno más secundario que cuenta como 'X', que puntúa como 10 pero se usa en casos de desempate como El valor más alto). Observar:
Por supuesto, me refiero a la puntuación métrica FITA, como se ve en la ilustración anterior. Si observa de cerca, puede observar el anillo más interno, que es una línea de puntos desvanecida, cuyo puntaje no está marcado. Esa es la 'X' a la que me refería, pero no tendrá que prestar atención a eso a menos que compita por el bono.
Desafío
Cree una función (o programa completo, si el idioma no admite funciones), que reciba una imagen perfectamente cuadrada como entrada (o nombre de archivo de imagen, si es necesario), que contenga algún número de verde (HEX # 00FF00, RGB (0, 255, 0)) puntos de algún tamaño, y devuelve la puntuación. La imagen puede contener datos distintos de los puntos verdes , pero el verde siempre será exactamente el mismo tono.
Puede imaginar que la imagen cuadrada representa la cara del objetivo, con el anillo más externo tocando en 4 puntos (centro superior, centro inferior, centro derecho, centro izquierdo). La cara objetivo representada siempre será de la misma proporción, con todos los anillos con un ancho de exactamente 1/20 del ancho de la imagen objetivo de entrada. Como ejemplo, dada una imagen de entrada de dimensiones de entrada de 400 px por 400 px, puede suponer que cada anillo tiene un ancho interno de 20 px, como se ilustra a continuación:
Aclaraciones
- Si toca dos anillos separados, se cuenta el mayor de los dos anillos
- No tiene que contabilizar automáticamente las fallas o el caso 'x', a menos que intente el bono
- Puede suponer que no se superponen círculos verdes
- También puede suponer que no hay otros píxeles de ese tono de verde en la imagen
- La imagen estará en formato PNG, JPEG o PPM (a elección)
- Se permiten bibliotecas de procesamiento de imágenes externas, si se crearon antes de publicar esta pregunta
- Puede suponer que todos los círculos verdes en un objetivo tendrán el mismo diámetro
- Si disparas (hah) para la bonificación de círculos superpuestos, puedes suponer que al menos un círculo en la imagen no tiene otra superposición
- Las lagunas estándar no están permitidas
Casos de prueba
Los siguientes dos casos deberían tener un puntaje de 52 (o en el caso de bonos, 52 con 1 'x' y 1 falta):
Y este último caso de prueba debería obtener una puntuación de 25 :
Prima
- -25 bytes si también devuelve el número de errores (fuera de cualquiera de los anillos)
- -30 bytes si también devuelve la cantidad de X (suponga que la x más interna es 3/100 del ancho de la imagen, y 10 es entonces 2/100 del ancho de la imagen. Las proporciones 1-9 permanecen sin cambios)
- -35% de recuento de bytes si tiene en cuenta círculos superpuestos
Este es el código de golf, por lo que gana el menor número de bytes. ¡Que te diviertas!
fuente
Respuestas:
Procesamiento 2, 448-25 = 423 bytes
Lee en un archivo de imagen f recorre los píxeles hasta que encuentra verde y luego inunda el círculo determinando el punto más cercano al centro. Luego agrega esa puntuación a un total. Si el puntaje es negativo, se agrega a un contador de fallas.
El programa generará 2 números, el primero es el puntaje y el segundo es el número de fallas.
puedes procesar aquí
fuente
Perl 5 + GD: 225-25 = 200
Editar: Encontró el motivo de la lectura incorrecta de píxeles en PNG indexados y aplicó una solución alternativa.
Por alguna razón con la biblioteca GD, los valores de píxeles verdes se leen como (4,254,4). No estoy seguro de si esto es específico para los archivos PNG incluidos en la pregunta.Los saltos de línea se pueden eliminar en el siguiente código.Toma una imagen PNG en la entrada e imprime 2 valores: Número de puntos y errores. Por ejemplo:
Cambio de última hora:
En el modo de color verdadero que necesitaba de todos modos, los índices de color utilizados por
getPixel
yfill
son simplemente valores RGB codificados con enteros, por lo que no es necesario usarrgb
ycolorAllocate
convertir ay desde esos índices.Explicación:
sub v
cual toma el parámetro en$_
lugar de los parámetros estándar, ya que es más corto).fuente
Haskell -
579-25 =554603-25-30576-25-30 = 521 BytesEstrategia:
La salida es un triple (puntuación, errores, X), por ejemplo,
(52,1,1)
para la imagen de prueba.El programa puede fallar si el píxel de un círculo más cercano al centro está dentro de los 3 píxeles de otro círculo.
fuente
all id
es lo mismo queand
.También, puedes implementarloj
con guardias de patronesj n m|PixelRGBA8 0 255 0 _<-getColor n m v=0<1|0<1=0>1
Mathematica -
371386 - 25 = 361Una solución más óptima. Calcula la respuesta mucho más rápido que mi solución Python.
Python con PIL: una solución trivial y no óptima, 961 bytes
Esto es simplemente para tratar de demostrar un enfoque tonto para resolver el problema. Se necesitan ~ 2 minutos para ejecutar los primeros dos casos de prueba, y ~ 20 minutos para ejecutar el tercero en mi sistema debido al detector de círculo rápidamente inventado, terriblemente intensivo en recursos y repulsivamente algorítmicamente complejo. A pesar de esto, cumple con los requisitos, aunque ciertamente no es un campo de golf óptimo. Cuanto más verde hay en la imagen, más tiempo tarda en ejecutarse.
Toma un objeto de imagen PIL y devuelve la puntuación.
Pasos necesarios:
n
, si alguno es de color verde, agréguelos al círculo.fuente
a
se puede escribir 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]