가장 긴 도미노 체인


31

도전 설명

도미노 는 왼쪽에 하나, 오른쪽에 하나 [2|4]또는 두 개의 값이있는 타일로 재생되는 게임 [4|5]입니다. 공통 값을 포함하는 두 타일은 함께 결합 될 수 있습니다. 위의 두 타일은 다음과 같이 결합 될 수 있습니다.

[2|4][4|5]

n결합 된 타일 시퀀스 를 길이 n 의 체인 이라고합니다. 물론, 타일은 타일 있도록 회전 될 수있다 [1|2], [1|3][5|3]체인으로 재 배열 될 수있는 [2|1][1|3][3|5]길이 3.

정수 쌍의 목록이 주어지면이 타일을 사용하여 형성 할 수있는 가장 긴 체인의 길이를 결정하십시오. 목록이 비어 있으면 정답입니다 0( 1빈 타일 목록에서 항상 길이 체인을 형성 할 수 있음 ).

샘플 입력 / 출력

[(0, -1), (1, -1), (0, 3), (3, 0), (3, 1), (-2, -1), (0, -1), (2, -2), (-1, 2), (3, -3)] -> 10
([-1|0][0|-1][-1|2][2|-2][-2|-1][-1|1][1|3][3|0][0|3][3|-3])

[(17, -7), (4, -9), (12, -3), (-17, -17), (14, -10), (-6, 17), (-16, 5), (-3, -16), (-16, 19), (12, -8)] -> 4
([5|-16][-16|-3][-3|12][12|-8])

[(1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1)] -> 7
([1|1][1|1][1|1][1|1][1|1][1|1][1|1])

[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11)] -> 1
(any chain of length 1)

[] -> 0
(no chain can be formed)

실행 시간이나 메모리에 제한이 있습니까? 모든 순열을 무차별하게 생각하라
Luis Mendo

3
@LuisMendo :이 문제가 NP 인 것이 확실 O(n!)합니다. 원하는대로 해고하십시오
shooqie

I guess it's P
l4m2

답변:


5

Brachylog , 23 바이트

s:papcb~k~c:{#=l2}al|,0

온라인으로 사용해보십시오!

설명

s:papcb~k~c:{#=l2}al|,0
s                         Check subsets of the input (longest first).
 :pa                      Check all permutations inside the input's elements
    p                     and all permutations /of/ the input's elements.
     c                    Flatten the result;
      b                   delete the first element;
       ~k                 find something that can be appended to the end so that
         ~c               the result can be unflattened into
           :{    }a       a list whose elements each have the property:
             #=             all the elements are equal
               l2           and the list has two elements.
                   l      If you can, return that list's length.
                    |,0   If all else fails, return 0.

즉,와 같은 입력의 [[1:2]:[1:3]:[5:3]]경우 유효한 chain으로 재 배열 [[2:1]:[1:3]:[3:5]]한 다음 flatten / behead / unkknife [1:1:3:3:5:_]( _알 수없는 곳을 나타냅니다) 를 생성하려고합니다 . 이를 조합 ~c하여 :{…l2}a효과적으로 두 요소 그룹으로 나누고 모든 그룹이 동일한 지 확인합니다. 우리가 평평하게 (길이를 두 배로 늘리고) 시작에서 하나의 요소를 제거하고 끝에서 하나를 추가하고 (변경 없음) 쌍으로 그룹화 (길이를 반으로)하면이 길이는 원래 도미노 체인과 동일합니다.

입력에는 도미노가없는 경우 "참수"명령이 실패합니다 (실제로, IIRC (가) :pa도 실패, a빈 목록을 싫어하는), 우리는 0 (하나의 큰 이유로 특별한 경우를 필요로하므로 사이에 우리가 비대칭이 b~k너무입니다 우리는 또한 1에 대한 특별한 경우가 필요하지 않습니다.)


1
훨씬 더 짧은 선하심…
Fatalize

4

Brachylog , 29 바이트

v0|sp:{|r}aLcbk@b:{l:2%0}a,Ll

온라인으로 사용해보십시오!

확실히 이것이 길지만, 무엇이든 확실합니다. 이것은 또한 너무 느립니다.

설명

v0                               Input = [], Output = 0
  |                              Or
   sp:{|r}aL                     L (a correct chain) must be a permutation of a subset of the
                                   Input with each tile being left as-is or reversed
           Lcbk                  Concatenate L into a single list and remove the first and
                                   last elements (the two end values don't matter)
               @b                Create a list of sublists which when concatenated results in
                                   L, and where each sublist's elements are identical
                 :{     }a,      Apply this to each sublist:
                   l:2%0           It has even length
                           Ll    Output = length(L)

이것이 가장 큰 이유는 가장 큰 s - subset것에서 가장 작은 것까지 선택 지점을 생성 하기 때문 입니다.


4

Mathematica, 191 바이트

If[#=={},0,Max[Length/@Select[Flatten[Rest@Permutations[#,∞]&/@Flatten[#,Depth[#]-4]&@Outer[List,##,1]&@@({#,Reverse@#}&/@#),1],MatchQ[Differences/@Partition[Rest@Flatten@#,2],{{0}...}]&]]]&

꽤 골프를 칠 수 있습니다. 그러나 기본적으로 Fatalize의 Brachylog answer 에서와 동일한 알고리즘으로 끝에 약간 다른 테스트가 있습니다.


-1 byte : Differences/@Rest@Flatten@#~Partition~2대신 Differences/@Partition[Rest@Flatten@#,2]( Infix보다 우선 순위가 높음 Map)
JungHwan Min

2

JavaScript (Firefox 30-57), 92 바이트

(a,l)=>Math.max(0,...(for(d of a)for(n of d)if(!(l-n))1+f(a.filter(e=>e!=d),d[0]+d[1]-n)))
  • l마지막 값이거나 undefined초기 호출입니다. l-n따라서 도미노를 재생할 수 있으면 잘못된 값입니다.
  • d 고려중인 도미노입니다.
  • n이전 도미노에 연결하기 위해 고려중인 도미노의 끝입니다. 다른 쪽 끝은로 쉽게 계산할 수 있습니다 d[0]+d[1]-n.
  • 0, 단순히 재생 가능한 도미노가없는 기본 사례를 처리합니다.

2

하스켈 , 180 134 131 117 바이트

p d=maximum$0:(f[]0d=<<d)
f u n[]c=[n]
f u n(e@(c,d):r)a@(_,b)=f(e:u)n r a++(f[](n+1)(r++u)=<<[e|b==c]++[(d,c)|b==d])

온라인으로 사용해보십시오! 새로운 접근 방식은 더 짧고 효율적이었습니다. 가능한 모든 순열 대신 모든 유효한 체인 만 작성됩니다.

편집 : 117 바이트 버전은 다시 느리지 만 여전히 무차별보다 빠릅니다.


오래된 무차별 방식 :

p(t@(a,b):r)=[i[]t,i[](b,a)]>>=(=<<p r)
p e=[e]
i h x[]=[h++[x]]
i h x(y:t)=(h++x:y:t):i(h++[y])x t
c%[]=[0]
c%((_,a):r@((b,_):_))|a/=b=1%r|c<-c+1=c:c%r
c%e=[c]
maximum.(>>=(1%)).p

이것은 가능한 모든 순열을 시도하는 무차별 구현입니다 (가능한 순열 수 는 " 짝수의 이중 계승 "인 A000165 에 의해 제공되는 것 같습니다 ). 온라인으로 시도하면 최대 길이 7의 입력을 거의 관리하지 않습니다 (7은 645120 순열에 해당하므로 인상적입니다 ).

용법:

Prelude> maximum.(>>=(1%)).p $ [(1,2),(3,2),(4,5),(6,7),(5,5),(4,2),(0,0)]
4

1

파이썬 2, 279 바이트

골프 :

l=input()
m=0
def f(a,b):
 global m
 l=len(b)
 if l>m:m=l
 for i in a:
  k=a.index(i)
  d=a[:k]+a[k+1:]
  e=[i[::-1]]
  if not b:f(d,[i])
  elif i[0]==b[-1][1]:f(d,b+[i])
  elif i[0]==b[0][0]:f(d,e+b)
  elif i[1]==b[0][0]:f(d,[i]+b)
  elif i[1]==b[-1][1]:f(d,b+e)
f(l,[])
print m

온라인으로 사용해보십시오!

몇 가지 코멘트와 같은 것 :

l=input()
m=0
def f(a,b):
 global m
 l=len(b)
 if l>m:m=l                      # if there is a larger chain
 for i in a:
  k=a.index(i)
  d=a[:k]+a[k+1:]                # list excluding i
  e=[i[::-1]]                    # reverse i
  if not b:f(d,[i])              # if b is empty
                                 # ways the domino can be placed:
  elif i[0]==b[-1][1]:f(d,b+[i]) # left side on the right
  elif i[0]==b[0][0]:f(d,e+b)    # (reversed) left side on the left
  elif i[1]==b[0][0]:f(d,[i]+b)  # right side on left
  elif i[1]==b[-1][1]:f(d,b+e)   # (reversed) right side on the right
f(l,[])
print m

나는 파이썬 답변을 보지 못했기 때문에 게시하고 있습니다 ... 누군가 내 답변을보고 혐오감에 훨씬 더 짧고 효율적인 것을 게시해야합니다.


0

클로저, 198 183 바이트

업데이트 : "최대 빈 시퀀스"처리 개선

(defn F[a C](remove(fn[i](identical? i a))C))(defn M[C](apply max 0 C))(defn L([P](M(for[p P l p](L l(F p P)))))([l R](+(M(for[r R[i j][[0 1][1 0]]:when(=(r i)l)](L(r j)(F r R))))1)))

이전 버전 :

(defn F[a C](remove(fn[i](identical? i a))C))(defn M[C](apply max 1 C))(defn L([P](if(empty? P)0(M(for[p P l p](L l(F p P))))))([l R](M(for[r R[i j][[0 1][1 0]]:when(=(r i)l)](+(L(r j)(F r R))1)))))

전화 컨벤션 및 테스트 사례 :

(L [])
(L [[2 4] [3 2] [1 4]])
(L [[3, 1] [0, 3], [1, 1]])
(L [[17 -7] [4 -9] [12 -3] [-17 -17] [14 -10] [-6 17] [-16 5] [-3 -16] [-16 19] [12 -8]])
(L [[0 -1] [1 -1] [0 3] [3 0] [3 1] [-2 -1] [0 -1] [2 -2] [-1 2] [3 -3]])
(L [[1 1] [1 1] [1 1] [1 1] [1 1] [1 1] [1 1]])

Felement C없이 list 의 요소 aM반환하고, 입력 Ingerers의 최대 값 또는 1을 반환합니다.

L하나의 인수로 호출하면 가능한 모든 시작 조각을 생성하고 각각의 최대 길이를 찾습니다. 두 개의 인수로 호출 l하면 다음 조각이 일치해야하는 R나머지 부분이 시퀀스의 첫 번째 요소입니다 .

순열을 생성하고 "하나의 요소를 선택하고 나누기로 나누기"는 간결하게 구현하기가 까다로 웠습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.