関係が推移的かどうかを判別


15

チャレンジの説明

いくつかの定義から始めましょう:

  • 関係は、要素の順序対の集合である(この課題では、我々は整数を使用することがあります)

たとえば[(1, 2), (5, 1), (-9, 12), (0, 0), (3, 2)]、関係です。

  • 関係は、要素の任意の2つのペアに対して推移的と呼ばれ(a, b)(b, c)この関係で、ペアが(a, c)また存在し、

  • [(1, 2), (2, 4), (6, 5), (1, 4)]それが含まれているため、推移的である(1, 2)(2, 4)、しかし、(1, 4)同様に、

  • [(7, 8), (9, 10), (15, -5)]任意の二つのペアが存在しないため、推移的であり (a, b)(c, d)本ようb=cです。

  • [(5, 9), (9, 54), (0, 0)]は推移的では(5, 9)あり(9, 54)ません。(5, 54)

整数のペアのリストを指定して、関係が推移的かどうかを判断します。

入出力

合理的な形式の整数のペアのリストが提供されます。関係を考える

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

次の形式は同等です。

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

出力:推移的関係の真の値、それ以外の場合は偽。入力は少なくとも1つのペアで構成され、ペアは一意であると想定できます。


入力はリストのような形式である必要がありますか、それとも隣接関係のマトリックスのような形式である必要がありますか?
-xnor

ペアが順序付けられているため、推移的のみのテストケースが必要です。例(1,3) (2,1) (3,4) (1,4) (2,4)。ペアが注文されなかった場合、これ(2,3)は欠落しているため推移的ではありません。
マーティンエンダー

1
@MartinEnder「順序付けられたペア」を誤って解釈したと思います。私はそれが順序でペアを意味するとは思わない-私はそれが各ペアが最初に、2番目に順序を持っていることを意味すると思う。
isaacg

@isaacgそれが私が意味したことです。言い換えると、関係が暗黙的に対称ではないため、私のテストケースは真実です。
マーティンエンダー

3番目のテストケース([(7, 8), (9, 10), (15, -5)]推移的ではありませんか?
wnnmaw

回答:


8

Haskell、42バイト

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

使用例:f [(1,2), (2,4), (6,5), (1,4)]-> True

すべてのペアに対する(外側)ループ(a,b)と同じペアに対する(内側)ループ。現在呼び出さ(c,d)れており、b==cチェック(a,d)が存在するペアでもあるたびにループします。結果をlogicalと結合しますand


これまでで最も読みやすい答え!
リン

@ Lynn、Prologの回答を確認してから;-)
coredump

4

 プロローグ、66バイト

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

(A、C)が成り立たないように(A、B)と(B、C)が見つかると、関係は推移的ではありません。


4

MATL27 25バイト

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

入力形式は;、リレーションの各ペアが列であるマトリックス(行セパレーターとして使用)です。たとえば、テストケース

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

それぞれとして入力されます

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

真の出力は、1によって形成される行列です。Falsyは、少なくとも1つのゼロを含む行列です。

オンラインでお試しください!

説明

コードは最初に入力整数を一意の1ベースの整数値に減らします。それらの値から、隣接行列を生成します。それ自体を行列乗算します。結果行列の非ゼロ値を1に変換します。最後に、後者のマトリックスのエントリが隣接マトリックスのエントリを超えていないことを確認します。


3

JavaScript(ES6)、69 67バイト

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

@Cyoceのアイデアのおかげで2バイト節約されました。以前の4つの69バイトの定式化がありました。

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
次の短縮形を作成することにより、2番目のソリューションを短縮できる場合があります.every
Cyoce

@Cyoce確かに、を書き込むこと[e]で毎回3バイトe節約できるため、割り当てに8バイトかかりますが、それでも1バイト節約できます。しかし、私はさらに一歩進んで、の略語を作成しa.every、2番目のバイトを節約しました。
ニール

3

Brachylog、24バイト

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

オンラインでお試しください!

説明:

'{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

入力ペアが含まれている場合は、他の言葉では、[A:B][B:C]、私たちは入れて入力を並べ替えることができます[A:B]し、 [B:C]開始時に、他のすべての要素を削除し、リストを作ります[A:B:B:C]。次に、[A:C]存在しない場合は、内側の述語から真実(プログラム全体から偽)を返します。


2

CJam(22バイト)

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

オンラインテストスイート。これは、要素を2レベルの配列としてとる匿名ブロック(関数)ですが、テストスイートは文字列操作を行って、入力を適切な形式に最初に入れます。

解剖

{         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バイト

!-eMfqFhTCM*_M

テストスイート

入力形式は [[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バイト

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

ペアのリストを取る純粋な関数。入力リストに含まれ{a,b}ている{b,c}{a,c}、一部のものa, b, cではない場合、それをに置き換え0ます。Truthyは入力リスト、falsyは入力リストです0


1

C ++ 14、140バイト

参照パラメーターを介して戻る名前のないラムダとして。入力はのコンテナである必要がありますpair<int,int>。退屈なO(n ^ 3)アプローチを採用しています。

[](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;}}

ゴルフをしないと使用法:

#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;

}

1

Pythonの291の 67 55のバイト

lambda s:all(b-c or(a,d)in s for a,b in s for c,d in s)

オンラインでお試しください!

Leaky Nunのおかげで-24バイト
バブラーのおかげで-12バイト


67バイト(および。に変更lambda xすることでコードを修正しましたlambda s
Leaky Nun

@LeakyNunおっと、それは私の愚かな愚かだった。ありがとう!
ハイパーニュートリノ

forsでアンパックして55バイト
バブラー

@Bubblerああ、ありがとう
-HyperNeutrino

0

公理103バイト

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)

なし:

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

演習

(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バイト

更新:使用する代わりに:when[a b] [c d]いずれかのすべてのペアについて、b != cまたは[a d]入力セットから見つかったことを確認します。

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

元の:

うわー、Clojure forループはクールです:Dこれは、forループが偽の値を生成しないことをチェックします[a d]。入力セットから見つからない場合に発生します。

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

この入力は、2要素ベクトルのセットでなければなりません。

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

入力をリストのようにする必要がある場合(%[a d])は、((set %)[a d])6バイト余分に置き換える必要があります。


0

これらのソリューションは両方とも、入力として順序付けられたペアのリストを受け取り、Trueまたはを返す名前のない関数Falseです。

Mathematica、65バイト

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

#~Permutations~{2}]入力から順序付きペアのすべての順序付きペアのリストを作成し、Join@@@それらを順序付き4倍に変換します。これらはIf[#2==#3,{#,#4},Nothing]&@@@、クールなプロパティを持つ関数によって操作されます。中央の2つの要素が等しい場合、最初と最後の数字で構成される順序付けられたペアを返します。それ以外の場合はNothing、リストから自動的に消える特別なMathematicaトークンを返します。したがって、結果は、推移的であるために入力にある必要がある順序付けられたペアのセットです。SubsetQ[#,...]そのプロパティを検出します。

Mathematica、70バイト

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

Table[...,{i,#},{j,#}] によってインデックス付けされた2D配列を作成します ijで。これらは入力から直接取得されます(したがって、両方とも順序付けられたペアです)。これらの2つのインデックスの機能はLast@i!=#&@@j||#~MemberQ~{#&@@i,Last@j}、です。これは、「の2番目の要素iと最初の要素がj一致しないか、または入力の最初の要素iと最後の要素j」からなる順序付きペアを含みます。これにより、ブール値の2D配列が作成And@@And@@@され、単一のブール値に平坦化されます。


0

APL(NARS)、39文字、78バイト

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

テスト:

  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

1秒の「解決策」はgotoの方法に従います。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.