Bir ilişkinin geçişli olup olmadığını belirleme


15

Meydan okuma açıklaması

Bazı tanımlarla başlayalım:

  • bir ilişki sıralı eleman çiftidir (bu meydan okumada tamsayıları kullanacağız)

Örneğin [(1, 2), (5, 1), (-9, 12), (0, 0), (3, 2)], bir ilişkidir.

  • herhangi bir iki çift öğe için bir ilişki geçişli olarak adlandırılır (a, b)ve (b, c)bu ilişkide bir çift (a, c)de bulunur,

  • [(1, 2), (2, 4), (6, 5), (1, 4)]geçişlidir, çünkü içerdiği (1, 2)ve (2, 4)aynı (1, 4)zamanda

  • [(7, 8), (9, 10), (15, -5)]herhangi iki çift değildir çünkü, geçişlidir (a, b), (c, d)mevcut olacağı şekilde b= c.

  • [(5, 9), (9, 54), (0, 0)]geçişli değildir, çünkü içerdiği (5, 9)ve içermediği (9, 54)için(5, 54)

Bir tam sayı çifti listesi verildiğinde, bir ilişkinin geçişli olup olmadığını belirleyin.

Giriş çıkış

Herhangi bir makul biçimde tamsayı çiftleri listesi verilecektir. Bir ilişki düşünün

[(1, 6), (9, 1), (6, 5), (0, 0)]

Aşağıdaki biçimler eşdeğerdir:

[(1, 6), (9, 1), (6, 5), (0, 0)] # list of pairs (2-tuples)
[1, 9, 6, 0], [6, 1, 5, 0] # two lists [x1, x2, ..., xn] [y1, y2, ..., yn]
[[1, 6], [9, 1], [6, 5], [0, 0] # two-dimentional int array
[4, 1, 6, 9, 1, 6, 5, 0, 0] # (n, x1, y1, ..., xn, yn)
[1+6i, 9+i, 6+5i, 0+0i] # list of complex numbers

... many others, whatever best suits golfing purposes

Çıktı: geçişli bir ilişki için gerçek bir değer, aksi halde yanlış. Girişin en az bir çift içereceğini ve çiftlerin benzersiz olduğunu varsayabilirsiniz.


Girdi liste benzeri bir biçim olmalı mı yoksa bitişik - matris benzeri bir biçim olabilir mi?
xnor

Çiftler sipariş edildiği için sadece geçişli bir test durumunuz olmalıdır. Örn (1,3) (2,1) (3,4) (1,4) (2,4). Çiftler sipariş edilmemiş olsaydı, bu geçişli olmazdı çünkü (2,3)eksik.
Martin Ender

1
@MartinEnder "Sipariş edilen çiftleri" yanlış yorumladığınızı düşünüyorum. Bunun bir çiftteki sıralar anlamına geldiğini sanmıyorum - sanırım her çiftin önce bir sırası var, sonra ikincisi var.
isaacg

@isaacg demek istediğim buydu. Başka bir deyişle, test durumum sadece doğrudur çünkü ilişki dolaylı olarak simetrik değildir.
Martin Ender

Üçüncü test durumu ( [(7, 8), (9, 10), (15, -5)]) geçişli olmamalı mı?
16:02

Yanıtlar:


8

Haskell, 42 bayt

f x=and[elem(a,d)x|(a,b)<-x,(c,d)<-x,b==c]

Kullanım örneği: f [(1,2), (2,4), (6,5), (1,4)]-> True.

Tüm çiftler üzerinde (a,b)(dış) döngü ve aynı çiftler üzerinde (iç) döngü, şimdi (c,d)ve her zaman var olan bir çift b==colup olmadığını kontrol ederken (a,d). Sonuçları mantıksal olarak birleştirin and.


Şimdiye kadarki en okunabilir cevap!
Lynn

@Lynn Prolog cevabına bir göz atın, ardından ;-)
coredump

4

 Prolog, 66 bayt

t(L):-not((member((A,B),L),member((B,C),L),not(member((A,C),L)))).

(A, B) ve (B, C) 'yi bulabilirsek , ilişki (A, C)' nin tutamayacağı şekilde geçişli değildir.


4

MATL , 27 25 bayt

7#u2e!l6MX>thl4$XQttY*g<~

Girdi biçimi, ;ilişkinin her çiftinin bir sütun olduğu bir matristir ( satır ayırıcı olarak kullanılır ). Örneğin, test senaryoları

[(1, 2), (2, 4), (6, 5), (1, 4)]
[(7, 8), (9, 10), (15, -5)]
[(5, 9), (9, 54), (0, 0)]

sırasıyla girdi olarak

[1 2 6 1; 2 4 5 4]
[7 9 15; 8 10 -5]
[5 9 0; 9 54 0]

Doğruluk çıktısı, birimlerin oluşturduğu bir matristir. Falsy , en az bir sıfır içeren bir matristir.

Çevrimiçi deneyin!

açıklama

Kod önce giriş tam sayılarını benzersiz, 1 tabanlı tamsayı değerlerine indirir. Bu değerlerden bitişiklik matrisini üretir; matris bunu kendi kendine çarpar; ve sonuç matrisindeki sıfır olmayan değerleri bunlara dönüştürür. Son olarak, ikinci matristeki hiçbir girişin bitişik matristeki girişi aşmadığını kontrol eder.


3

JavaScript (ES6), 69 67 bayt

a=>(g=f=>a.every(f))(([b,c])=>g(([d,e])=>c-d|!g(([d,c])=>b-d|c-e)))

@Cyoce tarafından geliştirilen bir fikir sayesinde 2 bayt kaydedildi. Daha önce 69 baytlık dört formülasyon vardı:

a=>a.every(([b,c])=>a.every(([d,e])=>c-d|a.some(([d,c])=>b==d&c==e)))
a=>!a.some(([b,c])=>!a.some(([d,e])=>c==d&a.every(([d,c])=>b-d|c-e)))
a=>a.every(([b,c])=>a.every(([d,e])=>c-d|!a.every(([d,c])=>b-d|c-e)))
(a,g=f=>a.every(f))=>g(([b,c])=>g(([d,e])=>c-d|!g(([d,c])=>b-d|c-e)))

1
Kısaltması yaparak ikinci çözümü kısaltabilirsiniz.every
Cyoce

@Cyoce Gerçekten de, her seferinde yazarak 3 bayt tasarruf edersiniz [e], bu yüzden atamanızın 8 bayt olmasına rağmen ehala bir bayt kaydedersiniz. Ancak, a.everyikinci bir bayt kaydeden bir kısaltma yaparak bir adım daha ilerledim .
Neil

3

Brachylog , 24 bayt

'{psc[A:B:B:C],?'e[A:C]}

Çevrimiçi deneyin!

Açıklama:

'{psc[A:B:B:C],?'e[A:C]}
'{                     } it is impossible to find
    c                    a flattened
   s                     subset of
  p                      a permutation of the input
     [A:B:B:C]           that has four elements, with the second and third equal
              ,?         and such that the input
                'e       does not contain
                  [A:C]  a list formed of the first and fourth element

Diğer bir deyişle, giriş çiftler içeriyorsa [A:B]ve [B:C]girişin başlangıçta koymasına [A:B]ve [B:C]diğer tüm öğelerin silinmesine ve bir liste üretmesine izin verebiliriz [A:B:B:C]. Sonra [A:C]orada değilse , iç yüklemden (tüm programdan falsey) gerçeği döndürürüz .


2

CJam (22 bayt)

{__Wf%m*{z~~=*}%\-e_!}

Çevrimiçi test takımı . Bu, öğeleri iki düzeyli bir dizi olarak alan anonim bir bloktur (işlev), ancak test paketi, girdiyi önce uygun bir biçime koymak için dize manipülasyonu yapar.

teşrih

{         e# Begin a block
  _       e#   Duplicate the argument
  _Wf%    e#   Duplicate again and reverse each pair in this copy
  m*      e#   Cartesian product
  {       e#   Map over arrays of the form [[a b][d c]] where [a b] and [c d]
          e#   are in the relation
    z~~=* e#     b==c ? [a d] : []
  }%
  \-      e#   Remove those transitive pairs which were in the original relation
  e_!     e#   Test that we're only left with empty arrays
}

2

Pyth, 14 bayt

!-eMfqFhTCM*_M

Test odası

Girdi biçiminin [[0, 0], [0, 1], ... ]

!-eMfqFhTCM*_M
!-eMfqFhTCM*_MQQQ    Variable introduction
            _MQ      Reverse all of the pairs
           *   Q     Cartesian product with all of the pairs
         CM          Transpose. We now have [[A2, B1], [A1, B2]] for each pair
                     [A1, A2], [B1, B2] in the input.
    f                Filter on
       hT            The first element (the middle two values)
     qF              Being equal
  eM                 Take the end of all remaining elements (other two values)
 -              Q    Remove the pairs that are in the input
!                    Negate. True if no transitive pairs were not in the input

2

Mathematica, 49 bayt

#/.{x=___,{a_,b_},x,{b_,c_},x}/;#~FreeQ~{a,c}:>0&

Çiftlerin listesini alan saf işlev. Giriş listesi bazılarını içeriyorsa {a,b}, {b,c}ancak {a,c}bazılarını a, b, ciçermiyorsa, listeyle değiştirir 0. Doğruluk girdi listesidir, yanlıştır 0.


1

C ++ 14, 140 bayt

Adsız lambda referans parametresi ile döner. Girdisinin bir kapsayıcı olmasını gerektirir pair<int,int>. Sıkıcı O (n ^ 3) yaklaşımının kullanılması.

[](auto m,int&r){r=1;for(auto a:m)for(auto b:m)if (a.second==b.first){int i=0;for(auto c:m)i+=a.first==c.first&&b.second==c.second;r*=i>0;}}

Ungolfed ve kullanımı:

#include<vector>
#include<iostream>

auto f=
[](auto m,int&r){
  r=1;                         //set return flag to true
  for(auto a:m)                //for each element
    for(auto b:m)              //check with second element
      if (a.second==b.first){  //do they chain?
        int i=0;               //flag for local transitivity
        for(auto c:m)          //search for a third element
          i+=a.first==c.first&&b.second==c.second;
        r*=i>0;                //multiply with flag>0, resulting in 0 forever if one was not found
      }
}
;

int main(){
 std::vector<std::pair<int,int>> m={
  {1, 2}, {2, 4}, {6, 5}, {1, 4}
 };

 int r;
 f(m,r);
 std::cout << r << std::endl;

 m.emplace_back(3,6);
 f(m,r);
 std::cout << r << std::endl;

 m.emplace_back(3,5);
 f(m,r);
 std::cout << r << std::endl;

}


0

Axiom 103 bayt

c(x)==(for i in x repeat for j in x repeat if i.2=j.1 and ~member?([i.1, j.2],x)then return false;true)

ungolfed:

c(x)==
  for i in x repeat
    for j in x repeat
       if i.2=j.1 and ~member?([i.1, j.2],x) then return false
  true

                                                                   Type: Void

alıştırmalar

(2) -> c([[1,2],[2,4],[6,5],[1,4]])
   Compiling function c with type List List PositiveInteger -> Boolean
   (2)  true
                                                                Type: Boolean
(3) -> c([[7,8],[9,10],[15,-5]])
   Compiling function c with type List List Integer -> Boolean
   (3)  true
                                                            Type: Boolean
(4) -> c([[5,9],[9,54],[0,0]])
   Compiling function c with type List List NonNegativeInteger ->
      Boolean
   (4)  false


0

Clojure, 56 53 bayt

Güncelleme: Kullanmak yerine, ya :whentüm çiftler için [a b] [c d]ya b != cda [a d]girdi setinde bulunup bulunmadığını kontrol edeceğim .

#(every? not(for[[a b]%[c d]%](=[b nil][c(%[a d])])))

Orijinal:

Vay canına, döngüler için Clojure soğuk: D Bu, fordöngünün [a d]giriş kümesinde bulunmazsa oluşan bir falsy değeri üretmediğini kontrol eder .

#(not(some not(for[[a b]%[c d]% :when(= b c)](%[a d]))))

Bu girdi iki elemanlı bir vektörler kümesi olmalıdır:

(f (set [[1, 2], [2, 4], [6, 5], [1, 4]]))
(f (set [[7, 8], [9, 10], [15, -5]]))
(f (set [[5, 9], [9, 54], [0, 0]]))

Girişin liste benzeri olması gerekiyorsa , fazladan 6 bayt için (%[a d])değiştirilmelidir ((set %)[a d]).


0

Her iki çözüm giriş ve geri olarak sipariş çiftlerinin bir listesini almak isimsiz işlevlerdir Trueveya False.

Mathematica, 65 bayt

SubsetQ[#,If[#2==#3,{#,#4},Nothing]&@@@Join@@@#~Permutations~{2}]&

#~Permutations~{2}]girişten tüm sıralı çift çiftlerinin listesini oluşturur ve Join@@@bunları sıralı dörtlülere dönüştürür. Bunlar daha sonra If[#2==#3,{#,#4},Nothing]&@@@serin bir özelliğe sahip olan fonksiyon tarafından çalıştırılır : eğer ortadaki iki eleman eşitse, ilk ve son sayılardan oluşan sıralı çifti döndürür; aksi takdirde Nothing, listelerden otomatik olarak kaybolan özel bir Mathematica belirteci döner . Sonuç, geçişli olması için girdide olması gereken sıralı çiftler kümesidir; SubsetQ[#,...]o özelliği algılar.

Mathematica, 70 bayt

And@@And@@@Table[Last@i!=#&@@j||#~MemberQ~{#&@@i,Last@j},{i,#},{j,#}]&

Table[...,{i,#},{j,#}]2B tarafından indekslenen bir dizi oluşturur ive jgiriş (dolayısıyla hem sipariş çiftleridir) doğrudan alınır. Bu iki endeksin işlevi Last@i!=#&@@j||#~MemberQ~{#&@@i,Last@j}, "ya ikinci öğesinin ihem de ilk öğesinin jeşleşmemesi anlamına gelir, aksi takdirde girdi, öğenin ilk öğesinden oluşan sıralı çifti içerir.i ve son öğesinden . j" Bu, And@@And@@@tek bir boole içine düzleşen 2D bir dizi boolean oluşturur.


0

APL (NARS), 39 karakter, 78 bayt

{∼∨/{(=/⍵[2 3])∧∼(⊂⍵[1 4])∊w}¨,⍵∘.,w←⍵}

Ölçek:

  f←{∼∨/{(=/⍵[2 3])∧∼(⊂⍵[1 4])∊w}¨,⍵∘.,w←⍵}
  f (1 2) (2 4) (6 5) (1 4)
1
  f (7 8) (9 10) (15 ¯5)
1
  f (5 9) (9 54) (0 0)
0

bir saniyelik 'çözüm' goto yollarını takip eder:

r←q w;i;j;t;v
r←1⋄i←0⋄k←↑⍴w⋄→3
r←0⋄→0
→0×⍳k<i+←1⋄t←i⊃w⋄j←0
→3×⍳k<j+←1⋄v←j⊃w⋄→4×⍳t[2]≠v[1]⋄→2×⍳∼(⊂t[1]v[2])∊w

0

Ortak Lisp, 121 bayt

(lambda(x)(not(loop for(a b)in x thereis(loop for(c d)in x do(if(= b c)(return(not(member`(,a ,d) x :test #'equal))))))))

Çevrimiçi deneyin!

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.