최대 울타리 배열 수


9

배경

울타리를 만들고 싶습니다. 이를 위해 많은 기둥을 모아서 땅에 붙였습니다. 나는 또한 실제 울타리를 만들기 위해 기둥에 못을 박을 보드를 많이 모았습니다. 나는 물건을 만들 때 쫓겨 버리는 경향이 있으며, 더 이상 보드를 놓을 곳이 없을 때까지 보드를 기둥에 고정시킬 것입니다. 내가 끝낼 수있는 울타리를 열거하기를 바랍니다.

입력

입력은 편리한 형식으로 극의 위치를 ​​나타내는 2 차원 정수 좌표 목록입니다. 중복이 포함되어 있지 않다고 가정 할 수 있지만 순서에 대해서는 아무 것도 가정 할 수 없습니다.

보드는 극 사이의 직선으로 표시되며 단순성을 위해 수평 및 수직 보드 만 고려합니다. 보드 사이에 다른 극이나 보드가없는 경우 두 개의 극을 보드로 연결할 수 있습니다. 즉, 보드가 서로 교차 할 수 없습니다. 새 보드를 추가 할 수없는 경우 기둥과 보드의 배열은 최대입니다 (동일하게 수평 또는 수직으로 정렬 된 두 기둥 사이에 기둥 또는 보드가 있음).

산출

출력은 극점을 사용하여 구성 할 수있는 최대 배열 수입니다.

입력 목록을 고려하십시오

[(3,0),(1,1),(0,2),(-1,1),(-2,0),(-1,-1),(0,-2),(1,-1)]

위에서 본 기둥의 해당 배열은 다음과 같습니다.

  o
 o o
o    o
 o o
  o

이 극을 사용하여 구성 할 수있는 최대 3 개의 최대 배열이 있습니다.

  o        o        o
 o-o      o|o      o-o
o----o   o||| o   o| | o
 o-o      o|o      o-o
  o        o        o

따라서 올바른 출력은 3입니다.

규칙

함수 또는 전체 프로그램을 작성할 수 있습니다. 가장 낮은 바이트 수가 이기고 표준 허점은 허용되지 않습니다.

테스트 사례

[] -> 1
[(0,0),(1,1),(2,2)] -> 1
[(0,0),(1,0),(2,0)] -> 1
[(0,0),(0,1),(1,0),(1,1)] -> 1
[(1,0),(0,1),(-1,0),(0,-1)] -> 2
[(3,0),(1,1),(0,2),(-1,1),(-2,0),(-1,-1),(0,-2),(1,-1)] -> 3
[(0,0),(4,0),(1,1),(1,-2),(3,1),(3,-2),(2,-1),(4,-1)] -> 3
[(0,0),(4,0),(1,1),(1,-2),(3,1),(3,-2),(2,-1),(4,-1),(0,-1)] -> 4
[(0,0),(4,0),(1,1),(1,-2),(3,1),(3,-2),(2,-1),(0,-1),(2,2)] -> 5
[(0,0),(4,0),(1,1),(1,-2),(3,1),(3,-2),(2,-1),(4,-1),(0,-1),(2,2)] -> 8

1
이 예에는 (-2,0)이 두 번있는 것 같습니다. 그 중 하나가 (2,0)이어야합니까?
isaacg

@isaacg 사실, 그것은 (0,-2)잘 잡아야합니다. 지금 변경 중입니다.
Zgarb

답변:


5

Mathematica, 301 바이트

(t~SetAttributes~Orderless;u=Subsets;c=Complement;l=Select;f=FreeQ;Count[s=List@@@l[t@@@u[Sort@l[Sort/@#~u~{2},!f[#-#2&@@#,0]&]//.{a___,{x_,y_},{x_,z_},b___,{y_,z_},c___}:>{a,{x,y},b,{y,z},c}],f[#,t[{{a_,b_},{a_,c_}},{{d_,e_},{f_,e_}},___]/;d<a<f&&b<e<c]&],l_/;f[s,k_List/;k~c~l!={}&&l~c~k=={},{1}]])&

이것은 좌표를 중첩으로 취하고 List정수를 반환하는 명명되지 않은 함수입니다 . 즉, 이름을 지정하고 전화하거나 추가 할 수 있습니다

@ {{3, 0}, {1, 1}, {0, 2}, {-1, 1}, {-2, 0}, {-1, -1}, {0, -2}, {1, -1}}

들여 쓰기

(
  t~SetAttributes~Orderless;
  u = Subsets;
  c = Complement;
  l = Select;
  f = FreeQ;
  Count[
    s = List @@@ l[
      t @@@ u[
        Sort @ l[
          Sort /@ #~u~{2}, 
          !f[# - #2 & @@ #, 0] &
        ] //. {a___, {x_, y_}, {x_, z_}, b___, {y_, z_}, c___} :> 
              {a, {x, y}, b, {y, z}, c}
      ],
      f[
        #,
        t[{{a_, b_}, {a_, c_}}, {{d_, e_}, {f_, e_}}, ___] 
          /; d < a < f && b < e < c
      ] &
    ], 
    l_ /; f[
      s, 
      k_List /; k~c~l != {} && l~c~k == {}, 
      {1}
    ]
  ]
) &

나는이 구현이 얼마나 순진한지를 표현조차 시작할 수조차 없습니다 ... 확실히 더 무력한 힘이 될 수 없었습니다 ...

  • 모든 (정렬되지 않은) 극 쌍을 가져옵니다.
  • 각 쌍과 모든 쌍을 정식 순서로 정렬하십시오.
  • 한 좌표를 공유하지 않는 (즉, 직교 선으로 연결할 수없는) 쌍을 버리십시오.
  • 버리기 쌍은 두 개의 더 짧은 쌍으로 구성 될 수 있습니다 (따라서 o--o--o3 개 대신 2 개의 펜스 만 생성됨).
  • 해당 쌍의 모든 하위 집합 (즉, 가능한 모든 펜스 조합)을 가져옵니다.
  • 펜스가 서로 교차하는 조합을 필터링하십시오.
  • 목록에서 엄격한 수퍼 세트를 찾을 수없는 결과 펜스 세트 수를 계산하십시오.

놀랍게도 모든 테스트 사례를 거의 즉시 해결합니다.

내가 찾은 정말 깔끔한 트릭은 내가 Orderless일치 해야하는 패턴의 수를 줄이는 것입니다. 기본적으로 교차 울타리가있는 울타리 세트를 버리고 싶을 때 세로 및 가로 울타리 쌍을 찾아서 상태를 확인해야합니다. 그러나 어떤 순서로 표시 될지 모르겠습니다. 목록 패턴은 일반적으로 순서에 따라 달라 지므로 두 가지 패턴이 실제로 길어집니다. 대신에 나는 주위 목록으로 -로 정의되지 않은 함수 t로 대체 t @@@합니다. 하지만 그 기능은 Orderless내가, 그래서 수 있습니다 단지 패턴에서 하나의 순서를 확인하고 티카 모든 순열에 대해 그것을 확인합니다. 그런 다음 목록을로 다시 배치했습니다 List @@@.

a) Orderless, b) not Listable 및 c) 0 인수 또는 목록 인수에 대해 정의 되지 않은 내장 기능이 있기를 바랍니다 . 그런 다음 교체 할 수 t있습니다. 그러나 그런 연산자는없는 것 같습니다.


Mathematica가 옳고 빠른 방법으로 생각할 때 대답은 "예"입니다.
seequ

글쎄, 그건 내 참조 구현만큼 순진합니다. : P
Zgarb

1

하스켈, 318 바이트

import Data.List
s=subsequences
k[(_,a,b),(_,c,d)]|a==c=f(\w->(1,a,w))b d|1<2=f(\w->(2,w,b))a c
f t u v=[t x|x<-[min u v+1..max u v-1]]
q l=nub[x|x<-map(k=<<)$s[a|a@[(_,n,m),(_,o,p)]<-s l,n==o||m==p],x++l==nubBy(\(_,a,b)(_,c,d)->a==c&&b==d)(x++l)]
m=q.map(\(a,b)->(0,a,b))
p l=sum[1|x<-m l,all(\y->y==x||x\\y/=[])$m l]

사용법 : p [(1,0),(0,1),(-1,0),(0,-1)]. 산출:2

작동 방식 :

  • 입력 목록의 모든 하위 목록을 작성하고 두 개의 요소와 동일한 x 또는 동일한 y 좌표로 유지하십시오. 이것은 울타리를 사이에 둘 수있는 모든 극 쌍의 목록입니다.
  • 그것의 모든 하위 목록을 만들
  • 모든 목록에 보드 추가
  • xy 좌표가 두 번 나타나는 목록 제거 (보드 및 극)
  • 직접 인접한 극 (예 : (1,0) 및 (1,1))으로 인해 여러 개의 빈 목록을 처리하기 위해 중복 목록 (보드 만)을 제거합니다.
  • 다른 목록의 엄격한 하위 목록이 아닌 것을 유지하십시오
  • 남은 목록을 세다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.