Escriba una función que tome 4 puntos en el plano como entrada y devuelva verdadero si los 4 puntos forman un cuadrado. Los puntos tendrán coordenadas integrales con valores absolutos <1000.
Puede usar cualquier representación razonable de los 4 puntos como entrada. Los puntos no se proporcionan en ningún orden en particular.
El código más corto gana.
Cuadrados de ejemplo:
(0,0),(0,1),(1,1),(1,0) # standard square
(0,0),(2,1),(3,-1),(1,-2) # non-axis-aligned square
(0,0),(1,1),(0,1),(1,0) # different order
Ejemplos no cuadrados:
(0,0),(0,2),(3,2),(3,0) # rectangle
(0,0),(3,4),(8,4),(5,0) # rhombus
(0,0),(0,0),(1,1),(0,0) # only 2 distinct points
(0,0),(0,0),(1,0),(0,1) # only 3 distinct points
Puede devolver verdadero o falso para el cuadrado degenerado (0,0),(0,0),(0,0),(0,0)
Respuestas:
Python
1769079 bytesLa función S toma una lista de números complejos como su entrada (A). Si conocemos el centro y una esquina de un cuadrado, podemos reconstruir el cuadrado girando la esquina 90,180 y 270 grados alrededor del punto central (c). En el plano complejo, la rotación de 90 grados sobre el origen se realiza multiplicando el punto por i . Si nuestra forma original y el cuadrado reconstruido tienen los mismos puntos, entonces debe haber sido un cuadrado.
fuente
J, 28
172527J realmente no tiene funciones, pero aquí hay un verbo monádico que toma un vector de puntos del plano complejo:
El método es una mezcla de Michael Spencer (funciona únicamente en longitudes entre vértices; pero actualmente está fallando mi rombo2) y funciona Eelvex (verifique los tamaños de los conjuntos). Lectura de derecha a izquierda:
-/~
calcular todas las diferencias de puntos,
aplanar|
extraer magnitud/:~
ordenar#/.~
protuberancia y cuenta4 8 4 -:
debe tener exactamente 4 equidistantes (en 0), 8 un poco más grandes (longitud 1, lados), 4 más grandes (longitudsqrt 2
, diagonales)Demostración:
Por el bien de la memoria, mi método anterior (requería vértices ordenados, pero podía detectar polígonos regulares de cualquier orden):
Ver historia para explicación y demostración. El método actual probablemente podría expandirse a otros polígonos, que
4 8 4
se parece mucho a una distribución binomial.fuente
3 :'4 8 4-:#/.~/:~|,-/~y'
Pitón, 71
42Actualización 1) para requerir 4 puntos diferentes (anteriormente daría falsos positivos para puntos repetidos, ¿hay otros?) 2) para definir una función por especificación
Para un cuadrado, el vector entre dos puntos debe ser 0 (el mismo punto), un lado o una diagonal. Entonces, el conjunto de la magnitud de estos vectores debe tener una longitud 3.
fuente
Haskell, 100 personajes
Así es como escribiría la solución J de JB en Haskell. Sin ningún intento de dañar la legibilidad eliminando caracteres no esenciales, se trata de 132 caracteres:
Puede reducirlo un poco a 100 eliminando espacios en exceso y renombrando algunas cosas
Usemos QuickCheck para asegurarnos de que acepta cuadrados arbitrarios, con un vértice en (x, y) y un vector de borde (a, b):
Probándolo en ghci:
Ah, claro, el cuadrado vacío no se considera un cuadrado aquí, así que revisaremos nuestra prueba:
Y probándolo de nuevo:
fuente
d
.s l=[4,8,4]==(map length.group.sort)[(x-a)^2+(y-b)^2|(x,y)<-l,(a,b)<-l]
Factor
Una implementación en el lenguaje de programación Factor :
Y algunas pruebas unitarias:
fuente
OCAML,
145164Corre así:
Desobusquemos y expliquemos un poco.
Primero definimos una norma:
Notarás que no hay llamada a sqrt, no es necesario aquí.
Aquí a, b, cyd son puntos. Suponemos que estos puntos se presentan así:
Si tenemos un cuadrado, entonces todas estas condiciones deben cumplir:
Observe que siempre se cumple lo siguiente:
Usaremos eso para simplificar nuestra función de prueba a continuación.
Como nuestra entrada no está ordenada, también tenemos que verificar todas las permutaciones. Sin pérdida de generalidad podemos evitar permutar el primer punto:
Después de la simplificación:
Editar: siguió el consejo de M.Giovannini.
fuente
n
una reducción de 20 caracteres:let t a b c d=a%b+a%c=b%c&&d%c+d%b=b%c&&a%b=a%c&&d%c=d%b
.Pitón (105)
Los puntos están representados por
(x,y)
tuplas. Los puntos pueden estar en cualquier orden y solo acepta cuadrados. Crea una lista,s
de distancias por pares (no cero) entre los puntos. Debe haber 12 distancias en total, en dos grupos únicos.fuente
f([(0,0),(0,4),(2,2),(-2,2)])
es un cuadradoPython - 42 caracteres
Parece que es una mejora usar números complejos para los puntos
donde A = [(11 + 13j), (14 + 12j), (13 + 9j), (10 + 10j)]
vieja respuesta:
Los puntos se especifican en cualquier orden como una lista, por ej.
fuente
>>> A=[(0,0),(0,0),(1,1),(0,0)] >>> len(set((a-c)**2+(b-d)**2 for(a,b),(c,d)in combinations(A,2)))==2 True
A=[(0,0),(0,4),(2,2),(-2,2)]; len(set((a-c)**2+(b-d)**2 for(a,b),(c,d)in combinations(A,2)))==2
C # - no exactamente corto. Abusando de LINQ. Selecciona dos combinaciones distintas de puntos en la entrada, calcula sus distancias, luego verifica que exactamente cuatro de ellos sean iguales y que solo haya otro valor de distancia distinto. Point es una clase con dos miembros dobles, X e Y. Podría ser fácilmente una Tupla, pero meh.
fuente
PHP, 82 caracteres
fuente
K - 33
Traducción de la solución J por JB :
K sufre aquí de sus palabras reservadas (
_sqr
y_sqrt
).Pruebas:
fuente
OCaml + Batteries, 132 caracteres
(¡mira, Ma, sin espacios!) La comprensión de
q
la lista en forma la lista de normas al cuadrado para cada par de puntos desordenados distintos. Un cuadrado tiene cuatro lados iguales y dos diagonales iguales, siendo las longitudes al cuadrado de este último el doble de las longitudes al cuadrado del primero. Como no hay triángulos equiláteros en la red de enteros, la prueba no es realmente necesaria, pero la incluyo para completarla.Pruebas:
fuente
Mathematica
65 80 6966Comprueba que el número de distancias entre puntos distintas (sin incluir la distancia de un punto a sí mismo) es 2 y la más corta de las dos no es 0.
Uso
NB:
\[And]
es un solo personaje en Mathematica.fuente
Jalea , 8 bytes
Pruébalo en línea!
Toma una lista de números complejos como argumento de línea de comando. Impresiones
1
o0
.¡Esto parece un desafío agradable para revivir!
fuente
Haskell (212)
Ingenuo primer intento. Comprueba las siguientes dos condiciones para todas las permutaciones de la lista de puntos de entrada (donde una permutación dada representa, por ejemplo, un orden de los puntos en el sentido de las agujas del reloj):
Código desofuscado y pruebas
fuente
Scala (146 caracteres)
fuente
JavaScript 144 caracteres
Matemáticamente igual a la respuesta de J Bs. Genera las 6 longitudes y afirma que las 2 más grandes son iguales y que las 4 más pequeñas son iguales. La entrada debe ser una matriz de matrices.
fuente
PHP,
161158 caracteresPrueba (1x1): http://codepad.viper-7.com/ZlBpOB
Esto se basa en la respuesta JavaScript de eBuisness .
fuente
JavaScript 1.8, 112 caracteres
Actualización: salvó 2 caracteres al plegar las comprensiones de la matriz juntas.
Otra reimplementación de la respuesta de JB. Explota las características de JavaScript 1.7 / 1.8 (cierre de expresiones, comprensión de matrices, asignación de desestructuración). También abusa
~~
(doble bitbit no operador) para obligarundefined
a numérico, con coerción de matriz a cadena y una expresión regular para verificar que los recuentos de longitud son[4, 8, 4]
(se supone que se pasan exactamente 4 puntos). El abuso del operador de coma es un viejo truco C ofuscado.Pruebas:
fuente
GoRuby - 66 caracteres
expandido:
Mismo algoritmo que la respuesta de JB .
Prueba como:
Salidas
true
para verdadero y en blanco para falsofuente
ruby -r ./golf-prelude.rb FILE_TO_RUN.rb
y funcionará exactamente igual.sort
antesgroup_by
..sort.group_by {...}
debe escribirse como.group_by {...}
Python 97 (sin puntos complejos)
Esto tomará listas de tuplas de puntos en [(x, y), (x, y), (x, y), (x, y)] en cualquier orden, y puede manejar duplicados o el número incorrecto de puntos. NO requiere puntos complejos como las otras respuestas de Python.
Puedes probarlo así:
Esto requerirá una pequeña explicación, pero la idea general es que solo hay tres distancias entre los puntos en un cuadrado (lateral, diagonal, cero (punto en comparación con sí mismo)):
Para guardar caracteres de código soy:
Me temo que alguien puede encontrar un caso de prueba que rompa esto. Así que por favor hazlo y lo corregiré. Por ejemplo, el hecho de que solo verifique tres distancias, en lugar de hacer un abs () y verificar la longitud del lado y la hipotenusa, parece un error.
La primera vez que probé el código de golf. Sé amable si he roto las reglas de la casa.
fuente
Clojure, 159 caracteres.
Editar: Para explicar también un poco.
(Nota: el enrutamiento cuadrado no es necesario y, por lo tanto, en el código guardado anteriormente)
fuente
C #, 107 caracteres
Donde puntos es la Lista de Vector3D que contiene los puntos.
Calcula todas las distancias al cuadrado entre todos los puntos, y si hay exactamente tres tipos distintos (debe ser 0, algún valor a y 2 * a) y 4 puntos distintos, entonces los puntos forman un cuadrado.
fuente
Python, 66
Mejorando la respuesta de paperhorse de 76 a 66:
fuente
Python 2 , 49 bytes
Pruébalo en línea!
Toma una lista de cuatro números complejos como entrada. Rota cada punto 90 grados alrededor del promedio y verifica que cada punto resultante esté en la lista original.
Misma longitud (aunque más corta en Python 3 usando
{*l}
).Pruébalo en línea!
fuente
^
se puede usar en lugar de==
.Wolfram Language (Mathematica) ,
3231 bytesPruébalo en línea!
Toma una lista de puntos representados por números complejos, calcula el segundo y tercer momento central y comprueba que ambos son cero.
Sin golf:
o
prueba
Este criterio funciona en todo el plano complejo, no solo en el enteros gaussianos .
Primero, notamos que el momentos centrales no cambian cuando los puntos se traducen juntos. Por un conjunto de puntos
los momentos centrales son independientes de
c
(es por eso que se llaman centrales ):En segundo lugar, los momentos centrales tienen una dependencia simple del escalado complejo general (escalado y rotación) del conjunto de puntos:
Esto significa que si un momento central es cero, entonces escalar y / o rotar el conjunto de puntos mantendrá el momento central igual a cero.
Tercero, demostremos el criterio para una lista de puntos donde los dos primeros puntos son fijos:
¿En qué condiciones son cero las partes reales e imaginarias del segundo y tercer momento central?
Todas estas seis soluciones representan cuadrados: Por lo tanto, la única forma en que una lista de puntos de la forma
{0, 1, x[3] + I*y[3], x[4] + I*y[4]}
puede tener cero segundos y terceros momentos centrales es cuando los cuatro puntos forman un cuadrado.Debido a las propiedades de traslación, rotación y escala demostradas en los puntos 1 y 2, esto significa que cada vez que el segundo y tercer momento central son cero, tenemos un cuadrado en algún estado de traslación / rotación / escala. ∎
generalización
El k-ésimo momento central de un n-gon regular es cero si k no es divisible por n. Se deben combinar suficientes condiciones para formar un criterio suficiente para detectar n-gons. Para el caso n = 4 fue suficiente para detectar ceros en k = 2 yk = 3; para detectar, por ejemplo, hexágonos (n = 6) puede ser necesario verificar k = 2,3,4,5 para ceros. No he probado lo siguiente, pero sospecho que detectará cualquier n-gon regular:
El desafío del código es esencialmente este código especializado para listas de longitud 4.
fuente
J,
31 29 2726comprueba si las 8 distancias más pequeñas entre los puntos son las mismas.comprueba si hay exactamente tres tipos de distancias entre los puntos (cero, longitud lateral y longitud diagonal).4 2 $
es una forma de escribir una matriz en J.fuente
Smalltalk para 106 caracteres
donde p es una colección de puntos, p. ej.
Creo que las matemáticas son buenas ...
fuente
Mathematica, 123 caracteres (pero puedes hacerlo mejor):
Donde 'a' es la entrada en el formulario de lista de Mathematica, por ejemplo:
a={{0,0},{3,4},{8,4},{5,0}}
La clave es mirar el punto productos de entre todos los vectores y observar que deben tener exactamente tres valores: 0, x, y 2 * x para algún valor de x. El producto de punto verifica tanto la perpendicularidad como la longitud en una sola bola.
Sé que hay atajos de Mathematica que pueden acortar esto, pero no sé cuáles son.
fuente
Union
lugar deSort@DeleteDuplicates
. Puse tus 3 líneas juntas también:#[[1]] == 0 && #[[3]]/#[[2]] == 2 &[ Union@Abs@Flatten[Table[c.d, {c, #}, {d, #}]] &[ Flatten[Table[x - y, {x, a}, {y, a}], 1]]]
Haskell, "wc -c" informa 110 caracteres. No comprueba que la entrada tenga 4 elementos.
Probé en
fuente