Maksimal Çit Düzenlemeleri


9

Arka fon

Bir çit yapmak istiyorum. Bunun için bir grup kutup topladım ve onları yere yapıştırdım. Ayrıca, gerçek çiti yapmak için direklere çakacağım birçok tahta topladım. Bir şey inşa ederken taşınmaya meyilliyim ve büyük olasılıkla tahtaları kutuplara daha fazla yerleştirene kadar direklere çivilemeye devam edeceğim. Sonunda elde edebileceğim olası çitleri numaralandırmanı istiyorum.

Giriş

Girişiniz, kutupların konumlarını herhangi bir uygun biçimde temsil eden iki boyutlu tamsayı koordinatlarının bir listesidir. Yineleme içermediğini varsayabilirsiniz, ancak siparişiyle ilgili hiçbir şey kabul edemezsiniz.

Levhalar kutuplar arasında düz çizgilerle temsil edilir ve basitlik için sadece yatay ve dikey levhaları dikkate alırız. Aralarında başka kutup veya levha yoksa iki kutup bir pano ile birleştirilebilir, yani panoların birbirini geçemez. Direklerin ve levhaların düzenlenmesi, üzerine yeni levhalar eklenemezse maksimumdur (eşdeğer olarak, yatay veya dikey olarak hizalanmış iki kutup arasında bir kutup veya bir tahta vardır).

Çıktı

Çıktınız kutuplar kullanılarak yapılabilecek maksimum düzenleme sayısıdır.

Misal

Giriş listesini düşünün

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

Üstten bakıldığında, kutupların ilgili düzeni aşağıdaki gibi görünüyor:

  o
 o o
o    o
 o o
  o

Bu kutuplar kullanılarak inşa edilebilen tam olarak üç maksimum düzenleme vardır:

  o        o        o
 o-o      o|o      o-o
o----o   o||| o   o| | o
 o-o      o|o      o-o
  o        o        o

Böylece doğru çıktı 3.

kurallar

Bir işlev veya tam bir program yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez.

Test Durumları

[] -> 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
Örneğin iki kez (-2,0) olduğu görülüyor. Bunlardan biri (2,0) olmalı mı?
isaacg

@isaacg Aslında, (0,-2)iyi yakalamalı. Şimdi değişiyor.
Zgarb

Yanıtlar:


5

Mathematica, 301 bayt

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

Bu, koordinatları iç içe olarak alan Listve bir tamsayı döndüren adsız bir işlevdir . Yani, bir ad verebilir ve arayabilir veya sadece ekleyebilirsiniz

@ {{3, 0}, {1, 1}, {0, 2}, {-1, 1}, {-2, 0}, {-1, -1}, {0, -2}, {1, -1}}

Girinti ile:

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

Bu uygulamanın ne kadar saf olduğunu ifade etmeye bile başlayamıyorum ... kesinlikle daha kaba bir güç olamazdı ...

  • Tüm (sırasız) kutup çiftlerini alın.
  • Her çifti ve tüm çiftleri standart bir düzende sıralayın.
  • Bir koordinatı paylaşmayan (yani dikey bir çizgiyle bağlanmayan) çiftleri atın.
  • Atma çiftleri iki kısa çiftten oluşturulabilir (böylece o--o--oüç yerine sadece iki çit verir).
  • Bu çiftlerin tüm alt kümelerini alın - yani tüm olası çit kombinasyonları.
  • Birbirini geçen çitleri olan kombinasyonları filtreleyin.
  • Listede katı bir üst kümenin bulunamayacağı ortaya çıkan çit seti sayısını sayın.

Şaşırtıcı bir şekilde, tüm test vakalarını neredeyse anında çözüyor.

Bunun için keşfettiğim gerçekten düzgün bir numara Orderless, eşleşmem gereken desen sayısını azaltmak için kullanılması . Aslında, çit çitleri olan çit setlerini atmak istediğimde, bir çift dikey ve yatay çit bulmam ve üzerlerindeki durumu kontrol etmem gerekiyor. Ama hangi sırayla görüneceklerini bilmiyorum. Liste kalıpları normalde sıraya bağlı olduğundan, bu gerçekten iki uzun kalıpla sonuçlanır. Yani bunun yerine bir işlevle liste çevreleyen ile değiştirin tile t @@@olduğu gibi o tutulur böylece tanımlı değil -. Ama bu işlev Orderless, bu yüzden desende tek bir sırayı kontrol edebilirim ve Mathematica tüm permütasyonlara karşı kontrol edecektir. Daha sonra listeleri tekrar yerine koydum List @@@.

Keşke a) Orderless, b) değil Listable ve c) 0 argümanları veya liste argümanları için tanımlanmamış bir yerleşik olsaydı . Sonra bunun yerine ben koyabilirim t. Ancak böyle bir operatör yok gibi görünüyor.


Mathematica'nın bunu doğru ya da yeterince hızlı yapıp yapmadığını düşündüğünüzde, cevap "evet" tir.
seequ

Bu benim referans uygulamam kadar naif. : P
Zgarb

1

Haskell, 318 bayt

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]

Kullanımı: p [(1,0),(0,1),(-1,0),(0,-1)]. Çıktı:2

Nasıl çalışır:

  • giriş listesinin tüm alt listelerini oluşturun ve iki elemanlı ve eşit x veya eşit y koordinatlarına sahip olanları saklayın. Bu, bir çitin inşa edilebileceği tüm kutup çiftlerinin bir listesidir.
  • tüm alt listelerini oluştur
  • her liste için pano ekle
  • xy koordinatının iki kez göründüğü listeleri kaldırma (tahtalar ve kutuplar)
  • doğrudan bitişik kutuplar (örn. (1,0) ve (1,1)) nedeniyle birden fazla boş listeyi işlemek için yinelenen listeleri (yalnızca panoları) kaldırın
  • başka bir listenin katı alt listesi olmayanları tut
  • kalan listeleri say
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.