确定关系是否可传递


15

挑战说明

让我们从一些定义开始:

  • 一个关系是一组有序的元素对(在这个挑战中,我们将使用整数)

例如,[(1, 2), (5, 1), (-9, 12), (0, 0), (3, 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)]是传递的,因为没有任何2双 (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

输出:传递关系的真实值,否则为假。您可以假设输入将至少包含一对,并且这些对是唯一的。


输入是否必须为类似列表的格式,或者它可以为类似邻接关系的格式?
xnor

您应该有一个只能传递的测试用例,因为成对的是有序的。例如(1,3) (2,1) (3,4) (1,4) (2,4)。如果未订购,则不会(2,3)丢失,因为缺少。
马丁·恩德

1
@MartinEnder我认为您误解了“有序对”。我不认为这是对的顺序-我认为这意味着每对有一个顺序,然后是第二。
isaacg '16

@isaacg就是我的意思。换句话说,我的测试用例只是真实的,因为该关系不是隐式对称的。
马丁·恩德

如果第三个测试案例([(7, 8), (9, 10), (15, -5)])将不会传递性?
wnnmaw '16

Answers:


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)也存在时也进行调用。将结果与逻辑相结合and


迄今为止最易读的答案!
林恩

@Lynn查看Prolog答案,然后;-)
coredump

4

 Prolog,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。最后,它检查后一个矩阵中的条目是否不超过邻接矩阵中的条目。


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个字节。以前有四个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
您可能能够通过进行缩写,缩短第二个解决方案.every
Cyoce

@Cyoce确实,您每次写入都会节省3个字节[e],因此即使分配了8个字节也要e节省一个字节。但是,我将缩写为a.every,从而进一步节省了第二个字节。
尼尔

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]开始处置换输入,删除所有其他元素,并产生一个list [A:B:B:C]。然后,如果[A:C]不存在,则从内部谓词返回true(从整个程序返回false)。


2

CJam(22字节)

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

在线测试套件。这是一个匿名块(函数),它将元素作为两级数组,但是测试套件进行字符串操作以首先将输入放入合适的格式。

解剖

{         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个字节

通过引用参数返回的未命名lambda。要求其输入为的容器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;

}


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

此输入必须是一组两个元素的向量:

(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

这两个解决方案都是未命名函数,它们将有序对列表作为输入并返回TrueFalse

Mathematica,65个字节

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

#~Permutations~{2}]从输入创建所有有序对的所有有序对的列表,并将其Join@@@转换为有序四倍体。然后由If[#2==#3,{#,#4},Nothing]&@@@具有酷属性的函数对其进行操作:如果中间两个元素相等,则返回由第一个和最后一个数字组成的有序对;否则返回Nothing,一个特殊的Mathematica令牌自动从列表中消失。因此,结果是一组有序对,它们需要在输入中才能传递;SubsetQ[#,...]检测到该属性。

Mathematica,70个字节

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

Table[...,{i,#},{j,#}]创建一个由i和索引的2D数组j,它们直接从输入中获取(因此都是有序对)。这两个索引的功能是Last@i!=#&@@j||#~MemberQ~{#&@@i,Last@j},翻译为“或者的第二个元素i和第一个元素j不匹配,或者输入包含由的第一个元素i和的最后一个元素组成的有序对j。这将创建一个二维布尔数组,该数组将展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

一秒钟的“解决方案”遵循以下方法:

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

Common Lisp,121个字节

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

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.