โซ่โดมิโนที่ยาวที่สุด


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: สวยแน่ใจว่าปัญหานี้เป็นปัญหาเพื่อให้ไฟขึ้นของคุณ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]]เราพยายามที่จะจัดเรียงไว้ในห่วงโซ่ที่ถูกต้อง[[2:1]:[1:3]:[3:5]]แล้วแบน / behead / unkknife ในการผลิต[1:1:3:3:5:_](ซึ่ง_หมายถึงไม่ทราบ) การรวมกัน~cและ:{…l2}aแยกสิ่งนี้ได้อย่างมีประสิทธิภาพในกลุ่มของ 2 องค์ประกอบและเรามั่นใจว่ากลุ่มทั้งหมดมีความเท่าเทียมกัน ในขณะที่เราแบน (เพิ่มความยาวเป็นสองเท่า) ลบองค์ประกอบหนึ่งจากจุดเริ่มต้นและเพิ่มส่วนท้าย (ไม่มีการเปลี่ยนแปลง) และจัดกลุ่มเป็นคู่ (ลดความยาวลงครึ่งหนึ่ง) สิ่งนี้จะมีความยาวเท่ากับห่วงโซ่ดั้งเดิมของแต้ม

คำสั่ง "behead" จะล้มเหลวหากไม่มีโดมิโนในอินพุต (จริง ๆ แล้ว IIRC the :paจะล้มเหลว; aไม่ชอบรายการที่ว่างเปล่า) ดังนั้นเราจึงจำเป็นต้องมีกรณีพิเศษสำหรับ 0 (เหตุผลใหญ่อย่างหนึ่งที่เรามีความไม่สมดุลระหว่างbและ~kเป็นเช่นนั้น เราไม่จำเป็นต้องมีกรณีพิเศษสำหรับ 1. )


1
ความดีที่สั้นลงมาก…
ทำให้เสียชีวิต

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}...}]&]]]&

สามารถเล่นกอล์ฟได้พอใช้ฉันแน่ใจ แต่โดยทั่วไปแล้วอัลกอริธึมแบบเดียวกับในคำตอบของ Brachylog ของ Fatalizeด้วยการทดสอบที่แตกต่างกันเล็กน้อยในตอนท้าย


-1 ไบต์: 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

Haskell , 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 byte version ช้ากว่าเดิมมาก แต่ก็ยังเร็วกว่าแรงเดรัจฉาน


วิธีการบังคับเดรัจฉานแบบเก่า:

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ที่ " คู่ factorial ของแม้ตัวเลข ") ลองใช้ออนไลน์แทบจะจัดการอินพุตไม่เกินความยาว 7 (ซึ่งเป็นประเภทที่น่าประทับใจเมื่อ 7 สอดคล้องกับ645120พีชคณิต)

การใช้งาน:

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

1

Python 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

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

Fองค์ประกอบของรายการผลตอบแทนCโดยไม่ต้ององค์ประกอบa, Mผลตอบแทนสูงสุด ingerers อินพุทหรือ 1

Lเป็นฟังก์ชั่นหลักเมื่อถูกเรียกด้วยอาร์กิวเมนต์ตัวเดียวมันจะสร้างชิ้นส่วนเริ่มต้นที่เป็นไปได้ทั้งหมดและค้นหาความยาวสูงสุดสำหรับแต่ละชิ้นส่วน เมื่อเรียกว่ามีสองอาร์กิวเมนต์lเป็นองค์ประกอบแรกของลำดับที่ชิ้นต่อไปจะต้องจับคู่และRเป็นชิ้นส่วนที่เหลือ

การสร้างพีชคณิตและ "เลือกองค์ประกอบหนึ่งและแยกไปพัก" ค่อนข้างยุ่งยากในการใช้งานรวบรัด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.