Визначте, чи є відношення перехідним


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)]є транзитивним, оскільки немає двох пар (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

@isaacg ось що я мав на увазі. Іншими словами, мій тестовий випадок є лише правдою, оскільки відношення не є неявно симетричним.
Мартін Ендер

Чи повинен третій тестовий випадок ( [(7, 8), (9, 10), (15, -5)]) не бути перехідним?
wnnmaw

Відповіді:


8

Хаскелл, 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

 Пролог, 66 байт

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

Співвідношення не є транзитивним, якщо ми можемо знайти (A, B) і (B, C) такі, що (A, C) не виконують.


4

MATL , 27 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]

Вихідний результат - це матриця, утворена ними. Falsy - це матриця, яка містить принаймні один нуль.

Спробуйте в Інтернеті!

Пояснення

Код спочатку зводить цілі числа введення до унікальних цілих значень на основі 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)))

Збережено 2 байти завдяки ідеї @Cyoce. Існували чотири попередні 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

Брахілог , 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]. Тоді ми повертаємо truthy з внутрішнього предиката (фальси з усієї програми), якщо [A:C]його немає.


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

Піт, 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

Математика, 49 байт

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

Чиста функція, яка займає список пар. Якщо список містить вхідний {a,b}і , {b,c}але не {a,c}для деяких a, b, c, замінює його 0. Truthy - це вхідний список, хибний - 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 2 , 91 67 55 байт

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

Спробуйте в Інтернеті!

-24 байти завдяки Leaky Nun
-12 байт завдяки Bubbler


67 байт (і виправили свій код, змінивши lambda xна lambda s.
Leaky Nun,

@LeakyNun О, ого, це було думати про мене дурним. Спасибі!
HyperNeutrino

55 байт , розпакувавши в fors.
Бубон

@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 для циклів є класним: 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

Обидва ці рішення є неназваними функціями, що приймають список упорядкованих пар як вхідні та повернені TrueабоFalse .

Математика, 65 байт

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

#~Permutations~{2}]створює список всіх упорядкованих пар із упорядкованих пар із вхідних даних та Join@@@перетворює їх у впорядковані чотиривірші. Потім ними керує функція If[#2==#3,{#,#4},Nothing]&@@@, яка має класну властивість: якщо середні два елементи рівні, він повертає впорядковану пару, що складається з першого і останнього чисел; в іншому випадку він повертається Nothing, спеціальний маркер Mathematica, який автоматично зникає зі списків. Таким чином, результат - це набір упорядкованих пар, який повинен бути на вході, щоб він був перехідним; SubsetQ[#,...]виявляє цю власність.

Математика, 70 байт

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

Table[...,{i,#},{j,#}]створює 2D масив, індексований iі j, які взяті безпосередньо з вхідних даних (звідси обидві впорядковані пари). Функція цих двох індексів полягає в тому Last@i!=#&@@j||#~MemberQ~{#&@@i,Last@j}, що перекладається на "або другий елемент 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

одне секундне "рішення" виконайте 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.