Contar interseções de retângulos

8

O desafio

Dada uma quantidade arbitrária de retângulos, produza a contagem total de interseções daquelas quando desenhadas em um plano 2D.

Uma interseção aqui é definida como um ponto Pque é cruzado por duas linhas que são ortogonais entre si e que não terminam em P.

Exemplo

Cada retângulo aqui é indicado por uma tupla de 2 com as coordenadas do canto superior esquerdo primeiro e as coordenadas do canto inferior direito em segundo.

[(-8,6), (- 4, -2)]
[(-4,9), (4,3)]
[(2,10), (14,4)]
[(1,7), (10, -6)]
[(7,4), (10,2)]
[(5,2), (9, -4)]
[(-6, -4), (- 2, -6)]

insira a descrição da imagem aqui

Esses retângulos criam 6 interseções, que devem ser sua saída.

  • Como você pode ver na imagem acima, tocar em retângulos não criará interseções aqui e não será contado.
  • Você pode codificar os retângulos em qualquer formato que desejar. Deixe claro qual formato você usa.
  • Se vários retângulos se cruzam no mesmo ponto, isso conta apenas como uma interseção.
  • As coordenadas serão sempre números inteiros.
  • Não haverá retângulos duplicados na entrada.
  • Você sempre terá pelo menos um retângulo como entrada.
  • Você não pode usar nenhum componente interno que resolva esse problema diretamente. Além disso, você não pode usar os componentes internos que resolvem equações. Todos os outros builtins são permitidos.
  • A saída deve ser um único inteiro indicando a contagem de interseções.

Regras

Casos de teste

Mesmo formato que no exemplo acima. Os retângulos são agrupados em uma lista.

[[(-8,6), (- 4, -2)], [(- 4,9), (4,3)], [(2,10), (14,4)], [(1 , 7), (10, -6)], [(7,4), (10,2)], [(5,2), (9, -4)], [(- 6, -4), (-2, -6)]] -> 6
[[(-2,2), (6, -4)]] -> 0
[[(-12,10), (- 8,6)], [(- 14,6), (- 10,2)], [(- 10,6), (- 6,2)]] - > 0
[[(-4,10), (6,2)], [(- 2,8), (4,3)], [(1,6), (8,4)], [(2,11 ), (5,5)]] -> 10
[[(8,2), (12, -2)], [(10,0), (14, -4)]] -> 2
[[(0,2), (2,0)], [(0,1), (3,0)]] -> 1
[[(-10, -2), (- 6, -6)], [(- 6, -2), (- 2, -6)], [(- 8, -4), (- 4, -8)]] -> 3

Feliz codificação!

Denker
fonte
Você precisa definir o que deseja que as respostas sejam contadas, pois muitos pontos na interseção de dois ou mais retângulos são aparentemente ignorados, de acordo com o diagrama.
feersum
1
Então, [[(0,0),(1,2)],[(0,0),(2,1)]]teria 1 interseção?
314 Neil
@ Neil Exatamente. Vou adicionar este caso de teste, obrigado!
Denker
@feersum Acho que o diagrama deixa bem claro o que contar e o que não. Mas uma definição formal não faria mal, suponho, acrescentando uma.
Denker
1
Se houver N pares de retângulos que se cruzam em (x, y), o ponto (x, y) é contado uma vez ou N vezes?
feersum 27/03

Respostas:

2

JavaScript (ES6), 186 bytes

a=>a.map(([a,b,c,d])=>h.push([b,a,c],[d,a,c])&v.push([a,b,d],[c,b,d]),h=[],v=[])|h.map(([d,a,e])=>v.map(([c,f,b])=>a<c&c<e&b<d&d<f&t.every(([a,b])=>a-c|b-d)&&t.push([c,d])),t=[])|t.length

Divide cada retângulo em suas linhas de componentes e intercepta as linhas horizontais e verticais, criando uma lista de interseções para evitar duplicatas.

Neil
fonte
Qual formato de entrada você usa? Quando ligo para isso com as caixas, sempre recebo zero.
Denker
@ DenkerAffe Desculpe, eu deveria ter dito, espero uma matriz de matrizes de 4 elementos, por exemplo [[-4,10,6,2],[-2,8,4,3],[1,6,8,4],[2,11,5,5]]. Como o JavaScript não possui tuplas, se você tentasse usar seus exemplos literalmente, teria acionado o operador de vírgula, invalidando a entrada.
Neil
Tudo bem, obrigado. No entanto, isso fornece 4 em vez de 3 para a última caixa de teste, pois as interseções de vários retângulos contam apenas como uma interseção. Eu esclarei isso depois que você postou sua resposta, eu acho, então esta continua comigo. Espero que não seja muito difícil corrigir isso, desculpe pela inconveniência.
31416 Denker
@DenkerAffe Atualizei-o para trabalhar com suas novas especificações.
Neil
0

Mathematica 138 bytes

Não finalizado! Isso funciona para todos os casos, exceto[[(0,0),(1,2)],[(0,0),(2,1)]]


Length@Union[Join@@(Cases[RegionIntersection@@# &/@Subsets[Line[{{#,#2},{#3,#2},{#3,#4},{#,#4},{#,#2}}]&@@@Flatten/@#,{2}],Point@a__:> a])]

Exemplo

Length@Union[
Join @@ (Cases[RegionIntersection @@ # & /@ Subsets[
Line[{{#, #2}, {#3, #2}, {#3, #4}, {#, #4}, {#, #2}}] & @@@ Flatten /@ #, {2}], 
Point@a__ :> a])] &@{{{-8, 6}, {-4, -2}}, {{-4, 9}, {4, 3}}, {{2, 10}, {14, 4}}, 
{{1, 7}, {10, -6}}, {{7, 4}, {10, 2}}, {{5, 2}, {9, -4}}, {{-6, -4}, {-2, -6}}}

6

DavidC
fonte