นับการจัดการรั้วสูงสุด


9

พื้นหลัง

ฉันต้องการสร้างรั้ว ด้วยเหตุนี้ฉันจึงรวบรวมเสาจำนวนมากและติดมันกับพื้น ฉันได้รวบรวมกระดานมากมายที่ฉันจะตอกตะปูกับเสาเพื่อทำรั้วจริง ฉันมักจะถูกพาตัวไปสร้างสิ่งต่าง ๆ และส่วนใหญ่ฉันจะเอาไม้กระดานไปไว้ที่เสาจนกว่าจะไม่มีที่ว่างสำหรับใส่มัน ฉันต้องการให้คุณแจกแจงรั้วที่เป็นไปได้ที่ฉันสามารถท้ายด้วย

อินพุต

อินพุตของคุณคือรายการของพิกัดจำนวนเต็มสองมิติที่แสดงถึงตำแหน่งของเสาในรูปแบบที่สะดวก คุณสามารถสันนิษฐานได้ว่ามันไม่มีสิ่งที่ซ้ำกัน แต่คุณไม่สามารถคิดอะไรเกี่ยวกับคำสั่งซื้อ

บอร์ดถูกแสดงโดยเส้นตรงระหว่างเสาและเพื่อความง่ายเราพิจารณาเฉพาะบอร์ดแนวนอนและแนวตั้ง สองขั้วสามารถเข้าร่วมโดยคณะกรรมการหากไม่มีเสาอื่น ๆ หรือบอร์ดระหว่างพวกเขาหมายความว่าบอร์ดไม่สามารถข้ามกันและกัน การจัดเรียงของเสาและแผงเป็นสูงสุดถ้าไม่มีบอร์ดใหม่ที่สามารถเพิ่มลงไป (เท่ากันมีทั้งเสาหรือคณะกรรมการใด ๆ ระหว่างสองขั้วในแนวนอนหรือแนวตั้งชิดก)

เอาท์พุต

ผลลัพธ์ของคุณคือจำนวนข้อตกลงสูงสุดที่สามารถสร้างขึ้นได้โดยใช้เสา

ตัวอย่าง

พิจารณารายการอินพุต

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

มองจากด้านบนการจัดเรียงที่สอดคล้องกันของเสามีลักษณะดังนี้:

  o
 o o
o    o
 o o
  o

มีการจัดเรียงสูงสุดสามอย่างที่สามารถสร้างได้โดยใช้เสาเหล่านี้:

  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 bytes

(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--oผลเพียงสองรั้วแทนสาม)
  • รับเซตย่อยทั้งหมดของคู่เหล่านั้น - เช่นชุดค่าผสมที่เป็นไปได้ทั้งหมด
  • กรองชุดค่าผสมที่มีรั้วข้ามซึ่งกันและกัน
  • นับจำนวนชุดรั้วที่เกิดขึ้นซึ่งไม่สามารถหาซูเปอร์เซ็ตที่เข้มงวดได้ในรายการ

น่าแปลกที่มันสามารถแก้ปัญหากรณีทดสอบทั้งหมดได้ทันที

กลเม็ดเด็ดพรายที่ฉันค้นพบสำหรับสิ่งนี้คือการใช้Orderlessการลดจำนวนรูปแบบที่ฉันต้องจับคู่ โดยพื้นฐานแล้วเมื่อฉันต้องการที่จะขุดรั้วชุดที่มีรั้วข้ามฉันต้องการหาคู่ของรั้วแนวตั้งและแนวนอนและตรวจสอบเงื่อนไขกับพวกเขา แต่ฉันไม่รู้ว่าคำสั่งซื้อใดจะปรากฏตามปกติเนื่องจากรูปแบบรายการจะขึ้นอยู่กับลำดับซึ่งจะส่งผลให้มีสองรูปแบบที่ยาวมาก ๆ ดังนั้นแทนที่ฉันจะแทนที่ด้วยรายการที่อยู่รอบ ๆ ด้วยฟังก์ชั่นtด้วยt @@@- ซึ่งไม่ได้กำหนดไว้ดังนั้นจึงถูกเก็บไว้เหมือนเดิม แต่ฟังก์ชั่นนั้นเป็นOrderlessดังนั้นฉันสามารถตรวจสอบคำสั่งเดียวในรูปแบบและ Mathematica จะตรวจสอบกับเรียงสับเปลี่ยนทั้งหมด List @@@หลังจากนั้นฉันใส่รายชื่อกลับมาอยู่ในสถานที่ที่มี

ฉันหวังว่าจะมีในตัวนั่นคือ a) Orderless, b) ไม่ Listableและ c) ไม่ได้กำหนดไว้สำหรับอาร์กิวเมนต์ 0 รายการหรืออาร์กิวเมนต์ จากนั้นฉันก็สามารถแทนที่tมันได้ แต่ดูเหมือนว่าจะไม่มีผู้ประกอบการดังกล่าว


เมื่อคุณคิดว่า Mathematica ทำถูกหรือเร็วพอคำตอบคือ "ใช่"
seequ

นั่นมันไร้เดียงสาพอ ๆ กับการใช้อ้างอิงของฉัน : P
Zgarb

1

Haskell, 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.