El problema : cuente el número de agujeros en un polígono conectado. La conectividad del polígono está garantizada por la condición de que cada triángulo en la triangulación de entrada comparte al menos 1 lado con otro triángulo y que solo hay uno de esos conjuntos de triángulos conectados.
La entrada es una lista L
de n
puntos en el plano y una lista T
de 3 tuplas con entradas de 0...n-1
. Para cada elemento en T
la tupla (t_1,t_2,t_3)
representa los tres vértices (de la lista L
) de un triángulo en la triangulación. Tenga en cuenta que esta es una triangulación en el sentido de 'triangulación de polígono' , debido a esto nunca habrá dos triángulos en T
esa superposición. Una estipulación adicional es que no tendrá que desinfectar la entrada L
y T
no contiene repeticiones.
Ejemplo 1 : si L = {{0,0},{1,0},{0,1},{1,2}}
y T = {{0,1,2},{1,2,3}}
luego el polígono especificado tiene un recuento de agujeros de 0.
Ejemplo 2 : si L = {{0,0},{1,0},{2,0},{2,1},{2,2},{1,2},{0,2},{0,1},{.5,.5},{1.5,.5},{1.5,1.5},{.5,1.5}}
y T = {{5,6,11},{5,10,11},{4,5,10},{3,8,10},{2,3,9},{2,8,9},{1,2,8},{0,1,8},{0,8,11},{0,7,11},{6,7,11},{3,4,10}}
luego la entrada del polígono debería dar como resultado una salida de 2.
La tarea es escribir el programa más corto (o función) que toma L
y T
como entrada y devuelve el número de agujeros. El 'ganador' será reconocido como la entrada con el menor recuento de caracteres (fecha de finalización tentativa 1 de junio).
Ejemplo de formato de entrada (tenga en cuenta la indexación 0):
0,0
1,0
0,1
1,2
0,1,2
1,2,3
T=1,2,3/1,2,4/5,6,7/5,6,8
,. Cada triángulo comparte una arista con otro triángulo, pero la triangulación está desconectadaT=1,2,3/1,4,5
está conectado pero no conectado al borde)Respuestas:
GolfScript (23 caracteres)
Asume el formato de entrada utilizando la notación de matriz GolfScript y las coordenadas entre comillas (o integrales). P.ej
( Equivalente en línea )
o
( Equivalente en línea )
fuente
Python, 71
Lo que sigue es un programa (no una función ) que calcula el número deseado.
Ejemplo de uso:
fuente
APL, 36
La función toma
L
como argumento izquierdo yT
como derecho.Por ejemplo:
Explicación, de derecha a izquierda:
⍴⍺,⍵
concatena los dos vectores de entrada y devuelve su longitud (V + F
)¨⍵
aplica la función de la izquierda a cada elemento del argumento derecho y devuelve el resultado⍵,⍵
devuelve el argumento correcto concatenado consigo mismo3 2⍴
da forma al argumento del vector en tres pares. En este caso, combina los elementos primero y segundo, tercero y primero, y segundo y tercero del vector.,/
une el argumento del vector⍵[⍋⍵]
ordena el argumento correcto∪/
filtra cualquier duplicado⍴⊃
convierte un escalar anidado en un vector y devuelve su longitud.E
)1
se explica por sí mismo (espero ...)Toda la función vuelve
1+E-(V+F)
, o1-(F+V-E)
.fuente
Mathematica, 93 (no mucho golf todavía)
(Espacios añadidos para mayor claridad)
Pruebas:
fuente
Erosion
)?Ruby, 239 caracteres (227 cuerpos)
Tenga en cuenta que solo estoy considerando la topología. No estoy usando las posiciones de vértice de ninguna manera.
llamador (espera T en formato Mathematica o JSON):
Prueba:
fuente
Mathematica
76 73 72 6762Después de mucha experimentación, me di cuenta de que la ubicación precisa de los vértices no era una preocupación, por lo que representé el problema con los gráficos. Los invariantes esenciales, el número de triángulos, bordes y vértices permanecieron invariables (siempre que se evitara el cruce de línea).
Había dos tipos de "triángulos" internos en el gráfico: aquellos en los que presumiblemente había una cara, es decir, un triángulo "lleno", y aquellos donde no los había. El número de caras internas no tenía ninguna relación con los bordes o vértices. Eso significaba que hacer agujeros en gráficos completamente "rellenos" solo reducía el número de caras. Jugué sistemáticamente con variaciones entre triángulos, haciendo un seguimiento de las caras, vértices y bordes. Finalmente, me di cuenta de que el número de agujeros siempre era igual a 1 - # caras - # vértices + # bordes. Esto resultó ser 1 menos la característica de Euler (que solo conocía en el contexto de los poliedros regulares (aunque la longitud de los bordes claramente no tenía importancia).
La siguiente función devuelve el número de agujeros cuando se introducen los vértices y triángulos. A diferencia de mi presentación anterior, no se basa en un escaneo de una imagen. Puede pensarlo como 1 - característica de Euler, es decir, 1 - (F + V -E) donde
F
= #caras,V
= # vértices,E
= # aristas. La función devuelve el número de agujeros,1 - (F + V -E)
dadas las caras reales (triángulos) y vértices.Se puede demostrar fácilmente que la eliminación de cualquier triángulo en el exterior del complejo no tiene ningún efecto en la característica de Euler, independientemente de si comparte uno o 2 lados con otros triángulos.
Nota: La minúscula
v
se utilizará en lugar de laL
de la formulación original; es decir, contiene los vértices mismos (no V, el número de vértices)f
se usa para laT
formulación original; es decir, contiene los triángulos, representados como el triple ordenado de los índices de vértice.Código
(Gracias a Mr. Wizard por eliminar 5 caracteres al eliminar la regla de reemplazo).
Ejemplo 1
v = {{0, 0}, {1, 0}, {0, 1}, {1, 2}}; f = {{0, 1, 2}, {1, 2, 3}};
Cero agujeros.
Ejemplo 2
v = {{0, 0}, {1, 0}, {2, 0}, {2, 1}, {2, 2}, {1, 2}, {0, 2}, {0, 1} , {.5, .5}, {1.5, .5}, {1.5, 1.5}, {.5, 1.5}}; f = {{5, 6, 11}, {5, 10, 11}, {4, 5, 10}, {3, 8, 10}, {2, 3, 9}, {2, 8, 9} , {1, 2, 8}, {0, 1, 8}, {0, 8, 11}, {0, 7, 11}, {6, 7, 11}, {3, 4, 10}};
Por lo tanto, 2 agujeros son en el ejemplo 2.
fuente
MorphologicalEulerNumber[]
). Mma 9.01, Win XP.MorphologicalEulerNumber
a veces requiere una imagen; se niega a aceptar un objeto gráfico. En estos casos, el tamaño del agujero y la resolución son críticos (ver codegolf.stackexchange.com/questions/8706/… ). Pero aquí funciona directamente con el objeto Graphics, que contiene explícitamente todos los vértices. Imaginé (o esperaba) que usaría un enfoque que no dependiera de la imagen. Ojalá supiera cómo intentó resolver el problema. Tal vez algunos detalles en el código fuente de la función aclaren las cosas.Python, 107
Me di cuenta de que tomar las parejas directamente era más corto
from itertools import*
y escribircombinations()
. Sin embargo, también noté que mi solución se basaba en las caras triangulares de entrada que tenían sus vértices listados en orden consistente. Por lo tanto, las ganancias en el recuento de personajes no son tan grandes.Python, 115
Enfoque característico de Euler, la verbosidad de itertools parece imposible de evitar. Me pregunto si sería más barato usar una técnica más directa para hacer pares de vértices.
Ejemplo de uso:fuente