Chuỗi domino dài nhất


31

Mô tả thử thách

Dominoes là một trò chơi được chơi với các ô có hai giá trị trên đó - một ở bên trái, một ở bên phải, ví dụ [2|4]hoặc [4|5]. Hai gạch có thể được nối với nhau nếu chúng chứa một giá trị chung. Hai gạch ở trên có thể được nối như thế này:

[2|4][4|5]

Chúng ta sẽ gọi một chuỗi các nô đã nối là một chuỗi có độ dài n. Tất nhiên, gạch có thể được luân chuyển, vì vậy gạch [1|2], [1|3][5|3]có thể được sắp xếp lại thành một chuỗi [2|1][1|3][3|5]có độ dài 3.

Đưa ra một danh sách các cặp số nguyên, xác định độ dài của chuỗi dài nhất có thể được hình thành bằng cách sử dụng các ô này. Nếu danh sách trống, câu trả lời đúng là 0(lưu ý rằng bạn luôn có thể tạo thành một chuỗi độ dài 1từ danh sách gạch không trống).

Đầu vào / đầu ra mẫu

[(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)

Bất kỳ hạn chế về thời gian chạy hoặc bộ nhớ? Hãy suy nghĩ vũ phu buộc tất cả các hoán vị
Luis Mendo

3
@LuisMendo: Khá chắc chắn rằng vấn đề này là NP, vì vậy hãy kích hoạt bạn O(n!)như bạn muốn
shooqie

I guess it's P
l4m2

Câu trả lời:


5

Brachylog , 23 byte

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

Hãy thử trực tuyến!

Giải trình

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.

Vì vậy, nói cách khác, đối với đầu vào như thế nào [[1:2]:[1:3]:[5:3]], chúng tôi cố gắng sắp xếp lại nó thành một chuỗi hợp lệ [[2:1]:[1:3]:[3:5]], sau đó làm phẳng / chặt đầu / unkknife để sản xuất [1:1:3:3:5:_](trong đó _đại diện cho một ẩn số). Sự kết hợp ~c:{…l2}aphân chia hiệu quả điều này thành các nhóm gồm 2 yếu tố và chúng tôi đảm bảo rằng tất cả các nhóm đều bằng nhau. Khi chúng ta làm phẳng (nhân đôi chiều dài), loại bỏ một phần tử khỏi phần đầu và thêm phần tử ở phần cuối (không thay đổi) và được nhóm thành cặp (giảm một nửa chiều dài), phần này sẽ có cùng độ dài với chuỗi domino ban đầu.

Lệnh "chặt đầu" sẽ thất bại nếu không có domino trong đầu vào (thực ra, IIRC :pa cũng sẽ thất bại; akhông thích các danh sách trống), vì vậy chúng tôi cần một trường hợp đặc biệt cho 0. (Một lý do lớn khiến chúng tôi có sự bất cân xứng giữa b~kvì vậy rằng chúng tôi cũng không cần một trường hợp đặc biệt cho 1.)


1
Trời ơi, ngắn hơn rất nhiều
Giảm béo vào

4

Brachylog , 29 byte

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

Hãy thử trực tuyến!

Khá chắc chắn rằng điều này là rất dài, nhưng bất cứ điều gì. Điều này cũng rất chậm.

Giải trình

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)

Lý do điều này sẽ tìm ra cái lớn nhất là vì s - subsettạo ra các điểm lựa chọn từ tập hợp con lớn nhất đến nhỏ nhất.


4

Toán học, 191 byte

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

Có thể chơi golf một chút công bằng, tôi chắc chắn. Nhưng về cơ bản, thuật toán tương tự như trong câu trả lời Brachylog của Fatalize , với một bài kiểm tra hơi khác ở cuối.


-1 byte : Differences/@Rest@Flatten@#~Partition~2, thay vì Differences/@Partition[Rest@Flatten@#,2]( Infixcó quyền ưu tiên cao hơn Map)
JungHwan Min

2

JavaScript (Firefox 30-57), 92 byte

(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)))
  • llà giá trị cuối cùng, hoặc undefinedcho lệnh gọi ban đầu. l-ndo đó là một giá trị giả nếu domino có thể được chơi.
  • d là domino đang được xem xét.
  • nlà sự kết thúc của domino đang được xem xét để xâu chuỗi với domino trước đó. Đầu kia có thể dễ dàng được tính là d[0]+d[1]-n.
  • 0, chỉ đơn giản là xử lý trường hợp cơ bản của không có domino có thể chơi được.

2

Haskell , 180 134 131 117 byte

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])

Hãy thử trực tuyến! Cách tiếp cận mới hóa ra vừa ngắn vừa hiệu quả hơn. Thay vì tất cả các hoán vị có thể, chỉ có tất cả các chuỗi hợp lệ được xây dựng.

Chỉnh sửa: Phiên bản 117 byte chậm hơn nhiều lần, nhưng vẫn nhanh hơn so với lực lượng vũ phu.


Phương pháp vũ phu cũ:

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

Đây là một triển khai vũ lực cố gắng thử tất cả các hoán vị có thể (Số lượng hoán vị có thể được đưa ra bởi A000165 , " giai thừa kép của các số chẵn "). Dùng thử trực tuyến hầu như không quản lý đầu vào lên đến độ dài 7 (tương tự như 7 ấn tượng tương ứng với 645120 hoán vị).

Sử dụng:

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

1

Python 2, 279 byte

Chơi gôn

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

Hãy thử trực tuyến!

Điều tương tự với một số ý kiến:

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

Tôi đang đăng bài vì tôi không thấy bất kỳ câu trả lời nào về con trăn ... ai đó sẽ thấy câu trả lời của tôi và, trong sự ghê tởm, bị buộc phải đăng một cái gì đó ngắn hơn và hiệu quả.


0

Clojure, 198 183 byte

Cập nhật: Xử lý tốt hơn "tối đa chuỗi có thể trống"

(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)))

Phiên bản trước đó:

(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)))))

Gọi hội nghị và trường hợp thử nghiệm:

(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]])

Ftrả về các phần tử của danh sách Cmà không có phần tử a, Mtrả về tối đa các phần tử nhập hoặc 1.

Llà hàm chính, khi được gọi với một đối số duy nhất, nó tạo ra tất cả các phần bắt đầu có thể và tìm độ dài tối đa cho mỗi đối số. Khi được gọi với hai đối số, đây llà phần tử đầu tiên của chuỗi mà phần tiếp theo phải khớp và Rlà phần còn lại của các phần.

Tạo hoán vị và "chọn một yếu tố và phân chia để nghỉ ngơi" khá khó khăn để thực hiện ngắn gọn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.