Verifique se os retângulos preenchem um espaço retangular sem espaços ou sobreposições

8

Esse desafio é baseado em outro desafio semelhante. Como encontrar o empacotamento de retângulos mais eficiente é NP-difícil (ou seja, sua solução é fácil de verificar, mas difícil de encontrar), esse desafio é muito mais fácil do que este aqui

Este desafio

Dado um monte de retângulos, descubra se eles preenchem ou não um espaço retangular sem lacunas ou sobreposições.

Entrada

A entrada pode ser de duas formas, uma das quais tem uma penalidade de pontuação.

O primeiro: contém uma lista de sublistas, cada uma com comprimento 4. Esta lista contém 4 números inteiros, que são as coordenadas dos vértices opostos. Como todos os retângulos serão horizontais / verticais, não há ambiguidade quanto ao local onde o retângulo está. Cada sub-lista conterá quatro números inteiros, que, em ordem, são a coordenada x do primeiro vértice, a coordenada y do primeiro vértice, a coordenada x do segundo vértice e a coordenada y do segundo vértice.

O segundo: contém quatro listas de números inteiros com o mesmo comprimento. As quatro listas representam as diferentes coordenadas. Se você imaginar a opção de entrada 1 como uma matriz, a entrada aqui é apenas a transposição da matriz. Esta entrada possui uma +20%penalidade de bytes.

Resultado

Saída simples de verdade / falsidade.

Especificações

Se houver um retângulo com a área 0 (ou seja, x1 == x2 || y1 == y2), desconsidere esse retângulo (isso [0 0 1 1], [2 2 3 2]é válido). Essa especificação existe para tornar mais difícil para as pessoas simplesmente obterem os valores mínimo / máximo x / y.

x1 <= x2e y1 <= y2nem sempre são verdadeiras. Se x1 > x2 || y1 > y2, o retângulo não é um retângulo de área zero; em vez disso, ocupa o espaço retangular entre (x1, y1)e (x2, y2).
As coordenadas podem ser negativas, caso em que ainda ocupam o espaço entre as coordenadas.
O retângulo superior esquerdo mais nem sempre está em (0, 0); portanto, o espaço retangular que é preenchido não necessariamente tem seu canto superior esquerdo em (0, 0).
(Agradecemos a @xnor por apontar essas ambiguidades)

Especifique como deseja sua entrada e como sua saída será representada.

Pontuação

Pontuação é o tamanho do código em bytes, mais uma penalidade de bytes, se aplicável. A pontuação mais baixa a partir de 15 de dezembro vence.

Casos de teste

0 0 1 2
1 0 3 1 ==> true
1 1 3 2

0 0 2 2
0 0 1 1 ==> false
0 0 0 0

0 0 1 1
2 2 2 2 ==> true
0 1 2 1

Boa sorte, feliz golfe!

HyperNeutrino
fonte
O retângulo deve ter um canto em (0,0)? As coordenadas podem ser negativas?
Xnor
Temos a garantia de que cada retângulo possui x1 <= x2e y1 <= y2? É um retângulo da área 0 com x1 == x2e é y1 <= y2possível?
Xnor
@xnor Estas são todas as pequenas coisas que não considerei. Obrigado por apontá-los, vou esclarecer em uma edição. Minhas respostas a essas perguntas são não, sim, não, sim.
HyperNeutrino
Eu recomendaria o Sandbox para detalhar detalhes como esse com antecedência. Seus casos de teste devem abranger o maior número possível de casos de canto. Ainda não estou claro em "Assim, a lista será semelhante a [x1, y1, x2, y2], onde (x1, y1) e (x2, y2) representam os vértices superior esquerdo e inferior direito". Se x1 > x2e y1 > y2, é um retângulo de área zero porque as coordenadas são trocadas?
Xnor
2
Alguém assistiu numberphile?
Ou orp

Respostas:

0

JavaScript (ES6), 249 bytes

with(Math)a=>!(a=a.map(([l,t,r,b])=>[l<r?l:r,t<b?t:b,l>r?l:r,t>b?t:b]).filter(g=([l,t,r,b])=>(r-l)*(b-t))).reduce((s,b)=>s-g(b),g([min,min,max,max].map((f,i)=>f(...a.map(a=>a[i])))))>a.some(([l,t,r,b],i)=>a.some(([m,u,s,c],j)=>i!=j&l<s&m<r&t<c&u<b))

Nota: Para usar isso, avalie-o como uma sequência e atribua o resultado a uma variável ou insira a atribuição após o with(Math). Explicação:

with(Math)a=>!(Trazer mine maxdentro do escopo.
a=a.map(([l,t,r,b])=>[l<r?l:r,t<b?t:b,l>r?l:r,t>b?t:b])Normalizar as coordenadas
.filter(g=([l,t,r,b])=>(r-l)*(b-t)))Remova os retângulos vazios, definindo também uma função para calcular a área
.reduce((s,b)=>s-g(b),Subtraia as áreas de todos os retângulos
g([min,min,max,max].map((f,i)=>f(...a.map(a=>a[i])))))da área da caixa delimitadora
>a.some(([l,t,r,b],i)=>a.some(([m,u,s,c],j)=>i!=j&l<s&m<r&t<c&u<b))e verifique se nenhum retângulo se sobrepõe.

Neil
fonte
Estou tendo problemas para testar isso. Você poderia esclarecer o que quer dizer com "inserir a tarefa"? (Não tenho nenhuma experiência em ES6). Ou, se possível, você poderia fornecer um link para alguns casos de teste? Obrigado.
HyperNeutrino
@AlexL. Quero dizer que você precisa escrever, por exemplo, with(Math)f=a=>etc. - colocar f=o início não funcionará.
Neil
OK. Entendo o que você quer dizer, mas os compiladores online que tentei me deram vários erros. Você poderia fornecer um compilador que realmente funcione (os outros compiladores estão sendo estranhos)?
HyperNeutrino
@AlexL. Ah, acho que digitei uma de minhas edições; Verifiquei duas vezes e você deve estar bem agora.
Neil
Estou marcando isso como aceito agora. Confiarei em você com os resultados do teste e continuarei tentando verificar isso.
HyperNeutrino
0

Mathematica, 194 bytes

(r=Select[#,(#-#3)(#2-#4)&@@#>0&];m={#~Min~#3,#2~Min~#4,#~Max~#3,#2~Max~#4}&@@Transpose@r;b=Boole[(x-#)(x-#3)<0&&(y-#2)(y-#4)<0]&;Integrate[(Plus@@(b@@@r)-b@@m)^2,{x,#,#3}&@@m,{y,#2,#4}&@@m]<1)&

Uma versão não destruída:

1  (r = Select[#1, (#1 - #3) (#2 - #4) & @@ #1 > 0 &]; 
2   m = {Min[#1, #3], Min[#2, #4], Max[#1, #3], Max[#2, #4]} & @@ Transpose[r]; 
3   b = Boole[(x - #1) (x - #3) < 0 && (y - #2) (y - #4) < 0] &;
4   Integrate[
5     (Plus @@ (b @@@ r) - b @@ m)^2 ,
6     {x, #1, #3} & @@ m ,
7     {y, #2, #4} & @@ m
8   ] < 1
9  ) &

A linha 1 define rcomo o conjunto de retângulos não triviais da entrada fornecida. (Há muita coisa & @@acontecendo nesse código; isso é apenas para que possamos usar #1,#2,#3,#4os quatro elementos de uma lista em vez de #[[1]],#[[2]],#[[3]],#[[4]].) Então a linha 2 define mas coordenadas do menor retângulo que limita todos os listados r; portanto, se os retângulos de entrada colocarem um retângulo grande em mosaico, esse retângulo grande deverá ser m.

A linha 3 define a função bque, quando aplicada a um quádruplo representando um retângulo, produz uma função de duas variáveis xe yque é igual a 1 se o ponto (x,y)estiver dentro do retângulo e 0 se não estiver. A linha 5 produz muitas dessas funções, uma para cada retângulo em r(todas adicionadas juntas) e uma última para o retângulo grande m(subtraído); essa complicada função de duas variáveis ​​é então ao quadrado.

A chave, neste ponto, é que essa função de duas variáveis ​​seja identicamente 0 se os retângulos pequenos estiverem lado a lado com o retângulo grande, mas terá alguns valores positivos se dois retângulos pequenos se sobreporem, ou alguns valores negativos (antes do quadrado) se alguma parte do retângulo grande não está coberto. Detectamos isso integrando literalmente (!) A função de duas variáveis ​​sobre o retângulo grande (os limites de integração são apresentados nas linhas 6-7): se obtivermos 0, o lado a lado foi perfeito e se obtivermos um valor positivo , houve um problema em algum lugar. Como tudo à vista é um número inteiro, salvamos um byte final usando em < 1vez da == 0linha 8.

(Eu acho bastante divertido podermos explorar a capacidade do Mathematica de fazer cálculos para resolver esse problema combinatório.)

Greg Martin
fonte