Escreva uma função que use 4 pontos no plano como entrada e retorne verdadeiro se os 4 pontos formarem um quadrado. Os pontos terão coordenadas integrais com valores absolutos <1000.
Você pode usar qualquer representação razoável dos 4 pontos como entrada. Os pontos não são fornecidos em nenhuma ordem específica.
O menor código vence.
Quadrados de exemplo:
(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
Exemplos não quadrados:
(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
Você pode retornar verdadeiro ou falso para o quadrado degenerado (0,0),(0,0),(0,0),(0,0)
Respostas:
Python
1769079 bytesA função S recebe uma lista de números complexos como entrada (A). Se conhecermos o centro e o canto de um quadrado, podemos reconstruí-lo girando o canto 90.180 e 270 graus em torno do ponto central (c). No plano complexo, a rotação de 90 graus sobre a origem é feita multiplicando o ponto por i . Se a nossa forma original e o quadrado reconstruído tiverem os mesmos pontos, deve ter sido um quadrado.
fonte
J, 28
172527J realmente não tem funções, mas aqui está um verbo monádico que pega um vetor de pontos do plano complexo:
O método é uma mistura de Michael Spencer (trabalho exclusivamente em comprimentos entre vértices; mas ele está atualmente falhando no meu losango2) e do Eelvex (verifique o tamanho dos conjuntos) funciona. Leitura da direita para a esquerda:
-/~
calcular todas as diferenças de pontos,
aplainar|
extrair magnitude/:~
arrumar#/.~
nub e count4 8 4 -:
deve ter exatamente 4 equidistantes (em 0), 8 um pouco maiores (comprimento 1, lados), 4 maiores ainda (comprimentosqrt 2
, diagonais)Demonstração:
Por uma questão de memória, meu método anterior (exigia vértices ordenados, mas podia detectar polígonos regulares de qualquer ordem):
Veja o histórico para obter explicações e demonstrações. O método atual provavelmente poderia ser expandido para outros polígonos, que
4 8 4
se parece muito com uma distribuição binomial.fonte
3 :'4 8 4-:#/.~/:~|,-/~y'
Python, 71
42Atualização 1) para exigir 4 pontos diferentes (anteriormente daria falsos positivos para pontos repetidos - existem outros?) 2) para definir uma função por especificação
Para um quadrado, o vetor entre dois pontos deve ser 0 (o mesmo ponto), um lado ou uma diagonal. Portanto, o conjunto da magnitude desses vetores deve ter comprimento 3.
fonte
Haskell, 100 caracteres
Aqui está como eu escreveria a solução J do JB em Haskell. Sem nenhuma tentativa de prejudicar a legibilidade removendo caracteres não essenciais, são cerca de 132 caracteres:
Você pode reduzi-lo um pouco para 100 removendo espaços em excesso e renomeando algumas coisas
Vamos usar o QuickCheck para garantir que ele aceite quadrados arbitrários, com um vértice em (x, y) e o vetor de aresta (a, b):
Tentando em ghci:
Ah, certo, o quadrado vazio não é considerado quadrado aqui, então revisaremos nosso teste:
E tentando novamente:
fonte
d
.s l=[4,8,4]==(map length.group.sort)[(x-a)^2+(y-b)^2|(x,y)<-l,(a,b)<-l]
Fator
Uma implementação na linguagem de programação do Fator :
E alguns testes de unidade:
fonte
OCaml, 145
164Execute assim:
Vamos desobstruir e explicar um pouco.
Primeiro, definimos uma norma:
Você notará que não há chamada para o sqrt, não é necessário aqui.
Aqui a, b, c e d são pontos. Assumimos que esses pontos são dispostos da seguinte maneira:
Se temos um quadrado, todas essas condições devem ser válidas:
Observe que o seguinte sempre se aplica:
Usaremos isso para simplificar nossa função de teste abaixo.
Como nossa entrada não é ordenada, também precisamos verificar todas as permutações. Sem perda de generalidade, podemos evitar permutar o primeiro ponto:
Após a simplificação:
Edit: seguiu o conselho de M.Giovannini.
fonte
n
uma redução em 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
.Python (105)
Os pontos são representados por
(x,y)
tuplas. Os pontos podem estar em qualquer ordem e só aceitam quadrados. Cria uma listas
de distâncias em pares (diferentes de zero) entre os pontos. Deve haver 12 distâncias no total, em dois grupos únicos.fonte
f([(0,0),(0,4),(2,2),(-2,2)])
é um quadradoPython - 42 caracteres
Parece que é uma melhoria usar números complexos para os pontos
onde A = [(11 + 13j), (14 + 12j), (13 + 9j), (10 + 10j)]
resposta antiga:
Os pontos são especificados em qualquer ordem como uma lista, por exemplo
fonte
>>> 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 # - não exatamente curto. Abusando do LINQ. Seleciona duas combinações distintas de pontos na entrada, calcula suas distâncias e verifica se exatamente quatro são iguais e se existe apenas um outro valor de distância distinto. Point é uma classe com dois membros duplos, X e Y. Poderia facilmente ser uma tupla, mas meh.
fonte
PHP, 82 caracteres
fonte
K - 33
Tradução da solução J por JB :
K sofre aqui de suas palavras reservadas (
_sqr
e_sqrt
).Teste:
fonte
OCaml + baterias, 132 caracteres
(veja, Ma, sem espaços!) A compreensão
q
da lista forma a lista de normas ao quadrado para cada par de pontos não ordenados distintos. Um quadrado tem quatro lados iguais e duas diagonais iguais, os comprimentos ao quadrado do último sendo duas vezes os comprimentos ao quadrado do anterior. Como não existem triângulos equiláteros na rede inteira, o teste não é realmente necessário, mas eu o incluo para completar.Testes:
fonte
Mathematica
65 80 6966Verifica se o número de distâncias entre pontos distintos (sem incluir a distância de um ponto a si mesmo) é 2 e o menor dos dois não é 0.
Uso
NB:
\[And]
é um caractere único no Mathematica.fonte
Gelatina , 8 bytes
Experimente online!
Leva uma lista de números complexos como um argumento de linha de comando. Imprime
1
ou0
.Parece um desafio agradável para reviver!
fonte
Haskell (211)
Primeira tentativa ingênua. Verifica as duas condições a seguir para todas as permutações da lista de pontos de entrada (onde uma determinada permutação representa, por exemplo, uma ordem dos pontos no sentido horário):
Código e testes desofuscados
fonte
Scala (146 caracteres)
fonte
JavaScript 144 caracteres
Matematicamente igual à resposta J Bs. Ele gera os 6 comprimentos e afirma que os 2 maiores são iguais e que os 4 menores são iguais. A entrada deve ser uma matriz de matrizes.
fonte
PHP,
161158 caracteresProva (1x1): http://codepad.viper-7.com/ZlBpOB
Isso é baseado na resposta JavaScript do eBuisness .
fonte
JavaScript 1,8, 112 caracteres
Atualização: salvou 2 caracteres dobrando as compreensões da matriz.
Outra reimplementação da resposta de JB. Explora os recursos do JavaScript 1.7 / 1.8 (fechamento de expressões, compreensão de array, atribuição de desestruturação). Também abusa
~~
(operador não bit a bit duplo) para coagirundefined
para numérico, com coerção de matriz para string e um regexp para verificar se a contagem de comprimento é[4, 8, 4]
(pressupõe que exatamente 4 pontos foram passados). O abuso do operador de vírgula é um velho truque C ofuscado.Testes:
fonte
GoRuby - 66 caracteres
expandido:
Mesmo algoritmo que a resposta de JB .
Teste como:
Saídas
true
para verdadeiro e em branco para falsofonte
ruby -r ./golf-prelude.rb FILE_TO_RUN.rb
e ele funcionará exatamente da mesma maneira.sort
antesgroup_by
..sort.group_by {...}
deve ser escrito como.group_by {...}
Python 97 (sem pontos complexos)
Isso pega listas de tuplas de pontos em [(x, y), (x, y), (x, y), (x, y)] em qualquer ordem e pode lidar com duplicatas ou com o número errado de pontos. NÃO requer pontos complexos, como as outras respostas em python.
Você pode testá-lo assim:
Isso vai exigir um pouco de explicação, mas a ideia geral é que existem apenas três distâncias entre os pontos em um quadrado (Lateral, Diagonal, Zero (ponto comparado a ele mesmo)):
Para salvar os caracteres de código, eu sou:
Receio que alguém possa encontrar um caso de teste que quebre isso. Então, por favor, faça e eu corrijo. Por exemplo, o fato de verificar apenas três distâncias, em vez de fazer um abs () e verificar o comprimento do lado e a hipotenusa, parece um erro.
Primeira vez que experimentei código de golfe. Seja gentil se eu violar alguma regra da casa.
fonte
Clojure, 159 caracteres.
Edit: Para também explicar um pouco.
(Nota: o enraizamento quadrado não é necessário e, portanto, no código salvo acima.)
fonte
C #, 107 caracteres
Onde points é Lista do Vector3D contendo os pontos.
Calcula todas as distâncias ao quadrado entre todos os pontos e, se houver exatamente três tipos distintos (deve ser 0, algum valor ae 2 * a) e 4 pontos distintos, os pontos formam um quadrado.
fonte
Python, 66
Melhorando a resposta do cavalo de papel de 76 para 66:
fonte
Python 2 , 49 bytes
Experimente online!
Leva uma lista de quatro números complexos como entrada. Gira cada ponto 90 graus em torno da média e verifica se cada ponto resultante está na lista original.
Mesmo comprimento (embora menor no Python 3 usando
{*l}
).Experimente online!
fonte
^
poderá ser usado em vez de==
.Wolfram Language (Mathematica) ,
3231 bytesExperimente online!
Toma uma lista de pontos representados por números complexos, calcula o segundo e o terceiro momento central e verifica se ambos são zero.
Sem golfe:
ou
prova
Este critério funciona em todo o plano complexo, não apenas nos números inteiros gaussianos .
Primeiro, notamos que os momentos centrais não mudam quando os pontos são traduzidos juntos. Para um conjunto de pontos
os momentos centrais são todos independentes
c
(é por isso que são chamados central ):Segundo, os momentos centrais dependem simples da escala complexa geral (escala e rotação) do conjunto de pontos:
Isso significa que, se um momento central for zero, a escala e / ou a rotação do conjunto de pontos manterão o momento central igual a zero.
Terceiro, vamos provar o critério para uma lista de pontos em que os dois primeiros pontos são fixos:
Sob quais condições as partes reais e imaginárias do segundo e terceiro momentos centrais são zero?
Todas essas seis soluções representam quadrados: Portanto, a única maneira de uma lista de pontos do formulário
{0, 1, x[3] + I*y[3], x[4] + I*y[4]}
ter zero segundo e terceiro momentos centrais é quando os quatro pontos formam um quadrado.Devido às propriedades de translação, rotação e escala demonstradas nos pontos 1 e 2, isso significa que sempre que o segundo e o terceiro momentos centrais são zero, temos um quadrado em algum estado de translação / rotação / escala. ∎
generalização
O k-ésimo momento central de um n-gon regular é zero se k não é divisível por n. Muitas dessas condições devem ser combinadas para formar um critério suficiente para a detecção de n-gons. Para o caso n = 4, foi suficiente detectar zeros em k = 2 e k = 3; para detectar, por exemplo, hexágonos (n = 6), pode ser necessário verificar k = 2,3,4,5 quanto a zeros. Não provei o seguinte, mas suspeito que ele detectará qualquer n-gon regular:
O desafio do código é essencialmente esse código especializado para listas de tamanho 4.
fonte
J,
31 29 2726verifica se as 8 menores distâncias entre os pontos são iguais.verifica se existem exatamente três tipos de distâncias entre os pontos (zero, comprimento lateral e comprimento diagonal).4 2 $
é uma maneira de escrever uma matriz em J.fonte
Smalltalk para 106 caracteres
onde p é uma coleção de pontos, por exemplo
Eu acho que a matemática é boa ...
fonte
Mathematica, 123 caracteres (mas você pode fazer melhor):
Onde 'a' é a entrada no formulário de lista do Mathematica, por exemplo:
a={{0,0},{3,4},{8,4},{5,0}}
A chave é examinar os produtos de ponto entre todos os vetores e observe que eles devem ter exatamente três valores: 0, x e 2 * x para algum valor de x. O produto pontilha verifica a perpendicularidade E o comprimento em um só swell.
Eu sei que existem atalhos do Mathematica que podem tornar isso mais curto, mas não sei o que são.
fonte
Union
vez deSort@DeleteDuplicates
. Coloquei suas 3 linhas juntas também:#[[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" relata 110 caracteres. Não verifica se a entrada possui 4 elementos.
Eu testei em
fonte