En uzun domino zinciri


31

Meydan açıklaması

Domino , üzerinde iki değere sahip çini ile oynanan bir oyundur - biri solda, biri sağda, örneğin [2|4]veya [4|5]. Ortak bir değer içeriyorlarsa iki kiremit birleştirilebilir. Yukarıdaki iki fayans şu şekilde birleştirilebilir:

[2|4][4|5]

nBirleştirilmiş karolar dizisini n uzunluklu bir zincir olarak adlandıracağız. Tabii ki, fayans çinileri, böylece döndürülebilir [1|2], [1|3]ve [5|3]bir zincir haline yeniden düzenlenebilir [2|1][1|3][3|5]uzunluğu 3.

Bir tamsayı çifti listesi göz önüne alındığında, bu karolar kullanılarak oluşturulabilecek en uzun zincirin uzunluğunu belirleyin. Liste boşsa, doğru cevap 0( 1boş olmayan bir döşeme listesinden her zaman bir uzunluk zinciri oluşturabileceğinizi unutmayın ).

Örnek giriş / çıkış

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

Çalışma süresi veya hafızada herhangi bir kısıtlama var mı? Tüm permütasyonları kaba bir şekilde zorlamayı düşünün
Luis Mendo,

3
@LuisMendo: Bu sorunun NP olduğundan eminim, O(n!)istediğin gibi ateş et
shooqie

I guess it's P
14m2'de

Yanıtlar:


5

Brachylog , 23 bayt

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

Çevrimiçi deneyin!

açıklama

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.

Başka bir deyişle, bunun gibi bir giriş [[1:2]:[1:3]:[5:3]]için geçerli bir zincire göre yeniden düzenlemeye çalışırız [[2:1]:[1:3]:[3:5]], sonra üretmek için düzleştirir / başını kaldırır [1:1:3:3:5:_]( unkknife) ( _bilinmeyenleri temsil eder). Kombinasyonu ~cve :{…l2}aetkili bir şekilde bunu 2 element grubuna ayırır ve tüm grupların eşit olmasını sağlarız. Düzleştikçe (uzunluğu iki katına çıkardıkça), bir elemanı baştan kaldırdık ve sonunda bir tane ekledik (değişiklik yok) ve çiftler halinde gruplandırılmış (uzunluğu yarıya indirerek), bu orijinal domino zinciri ile aynı uzunluğa sahip olacak.

Girişteki hiçbir domino varsa "kafasını" talimatı başarısız olur (aslında, IIRC :pada başarısız olur; aboş listeleri sevmediği), biz 0. (Bir büyük nedeni ile bazı özellikler kutusu gerekecek böylece arasına biz asimetrisi vardır bve ~kböyledir ayrıca 1 için özel bir davaya ihtiyacımız yok.)


1
Çok daha kısa olan iyilik…
17'yi

4

Brachylog , 29 bayt

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

Çevrimiçi deneyin!

Oldukça uzun, ama her neyse. Bu da çok yavaş.

açıklama

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)

Bunun en büyüğünü bulma nedeni s - subset, en büyüğünden en küçüğüne kadar seçim noktaları oluşturmasıdır.


4

Mathematica, 191 bayt

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

Eminim biraz golf oynayabilirsin. Fakat temelde, Fatalize Brachylog cevabındaki algoritma ile aynı test biraz daha farklı oldu.


-1 bayt: Differences/@Rest@Flatten@#~Partition~2yerine Differences/@Partition[Rest@Flatten@#,2]( Infixönceliğinden daha yüksek Map)
JungHwan Min

2

JavaScript (Firefox 30-57), 92 bayt

(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)))
  • lson değer veya undefinedilk çağrı için l-nDomino oynanabilirse bu nedenle sahte bir değerdir.
  • d ele alınan dominodur.
  • nönceki dominoya zincirleme yapmak üzere değerlendirilen domino sonudur. Diğer uç kolayca olarak hesaplanabilir d[0]+d[1]-n.
  • 0, basitçe oynanabilir domino olmayan temel durumu ele alır.

2

Haskell , 180 134 131 117 bayt

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

Çevrimiçi deneyin! Yeni yaklaşımın hem daha kısa hem de daha etkili olduğu ortaya çıktı. Tüm olası izinlerin yerine yalnızca tüm geçerli zincirler oluşturulur.

Düzenleme: 117 bayt sürümü daha yavaş, ama yine de kaba kuvvetten daha hızlı.


Eski kaba kuvvet metodu:

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

Bu, tüm olası izinleri deneyen kaba kuvvet uygulamasıdır (Olası izinlerin sayısı , " çift sayıların çift faktörü " olan A000165 tarafından verilmektedir .) Çevrimiçi olarak deneyin , uzunluğu 7'ye kadar olan girişleri zorlukla yönetir (7, 645120 permütasyona karşılık gelir .

Kullanımı:

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

1

Python 2,279 bayt

golfed:

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

Çevrimiçi deneyin!

Bazı yorumlar ile aynı şey:

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

Gönderiyorum çünkü herhangi bir python cevabı görmedim ... birisi cevabımı görecek ve iğrenme halinde çok daha kısa ve verimli bir şeyler göndermek zorunda kalacak.


0

Clojure, 198 183 bayt

Güncelleme: "maksimum olası boş dizinin" daha iyi kullanılması

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

Önceki Sürüm:

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

Kongre çağrısı ve test durumları:

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

FListenin döner elemanlar Celemanı olmadan a, Mgiriş ingerers veya 1 maksimum döner.

LAna fonksiyon, tek bir argüman ile çağrıldığında olası tüm başlangıç ​​parçalarını oluşturur ve her biri için maksimum uzunluğu bulur. İki argüman ile çağrıldığında l, bir sonraki parçanın eşleşmesi gereken ve dizinin Rkalan parçaları olan dizinin ilk elemanıdır .

Üretken permütasyonlar ve "bir element seçin ve dinlenmeye ayırın" özlü bir şekilde uygulamak oldukça zordu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.