Клітини діаграми Венна


12

З урахуванням декількох наборів, наприклад s1={2,3,7}, s2={1,2,4,7,8}і s3={4,7}, діаграма Венна візуалізує кожен набір із закритою кривою та набір елементів, які знаходяться всередині або поза периметром кривої, залежно від того, є вони елементом множини чи ні. Оскільки всі елементи множини з'являються лише один раз на діаграмі Венна, криві, що представляють кожен набір, повинні перекриватися, якщо елемент присутній у більшій одній множині. Ми називаємо кожне таке перекриття комірки діаграми Венна.

Це пояснення може бути трохи заплутаним, тому давайте подивимось на приклад.

Приклад

Діаграма Венна для наборів s1, s2і s3може виглядати так:

Клітини цієї діаграми Венна є (читається зверху вниз, зліва направо) {1,8}, {2}, {7}, {4}, {3}, {}і {}.

На практиці часто зустрічаються лише діаграми Венна з двох-трьох множин, оскільки представлення діаграм Венна з чотирьох і більше множин не дуже чітке. Однак вони існують, наприклад, для шести наборів:

CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=1472309

Завдання

Враховуючи не порожній набір наборів натуральних чисел у будь-якому розумному поданні, поверніть набір комірок діаграми Венна наборів. Зокрема, не потрібне графічне зображення.

  • Ви можете написати повну програму або функцію.
  • Ви можете повернути стільки порожніх наборів, скільки є порожніх комірок (тобто список усіх комірок) замість лише одного порожнього набору (тобто набору комірок).
  • Деякі розумні способи введення для наведеного вище прикладу , включають , але не обмежуються ними {{2,3,7},{1,2,4,7,8},{4,7}}, [[2,3,7],[1,2,4,7,8],[4,7]], "2,3,7;1,2,4,7,8;4,7"або "2 3 7\n1 2 4 7 8\n4 7". Якщо ви сумніваєтесь у прийнятному обраному вами форматі введення, сміливо запитайте у коментарі.
  • Ваш вихідний формат повинен відповідати формату введення, якщо це можливо. Зауважте, що це правило вимагає, щоб ваш формат міг однозначно відображати порожні набори.
  • Це , тому постарайтеся використовувати якомога менше байтів мовою, яку ви обрали. Щоб заохотити конкуренцію за мову, а не між мовами, я не прийму відповіді.

Випробування

Ось деякі входи разом з можливими виходами:

input -> output
{{2,3,7},{1,2,4,7,8},{4,7}} -> {{1,8},{2},{7},{4},{3},{}} (or {{1,8},{2},{7},{4},{3},{},{}})
{{1,2,3},{4,5,6},{7,8,9}} -> {{1,2,3},{4,5,6},{7,8,9},{}}
{{}} -> {{}}
{{1,2,3},{1,2}} -> {{1,2},{3},{}}
{{4,3,8},{1,2,9,3},{14,7,8,5},{6,11,3,8},{10},{9,4,3,7,10}} -> {{6,11},{10},{4},{3},{8},{5,14},{1,2},{9},{7},{}}
{{2,3,4,7},{},{1,3,7,5,6},{2,3,7,5},{7,2,4,3,6},{1,4,5}} -> {{},{4},{2},{7,3},{1},{6},{5}}
{{1,2,3,4},{1,2,5,6},{1,3,5,7}} -> {{4},{3},{2},{1},{6},{5},{7}}

Я припускаю, що це правда через визначення набору, але чи можна вважати, що дублікатів в одному з підмножин не буде?
HyperNeutrino

@Hyper Neutrino Так, ви можете вважати, що всі набори безкоштовні.
Лайконі

Можливо, ви можете додати тестовий випадок, коли жодна з комірок не порожня. Напр. {{1,2,3,4}, {1,2,5,6}, {1,3,5,7}}.
Ørjan Johansen

Як другий не дає {{1,2,3},{4,5,6},{7,8,9},{},{},{},{}}?
Leaky Nun

1
@carusocomputing При більш детальному огляді ви побачите, що це не справжня схема Венна, оскільки відсутні деякі можливі перекриття.
Лайконі

Відповіді:


8

Haskell , 71 байт

Анонімна функція, яка бере список списків цілих чисел і повертає аналогічний список.

Використовувати як (foldr(\x r->(x\\(id=<<r)):([intersect x,(\\x)]<*>r))[])[[1,2,3],[1,2]].

import Data.List
foldr(\x r->(x\\(id=<<r)):([intersect x,(\\x)]<*>r))[]

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

Як це працює

  • Використовує задані операції \\(різниця) та intersectвід Data.List.
  • Складає список "наборів" (представлений у вигляді списків) у список комірок, починаючи з порожнього списку [].
  • x- це поточний набір, який потрібно додати до діаграми, і rє списком комірок, що вже побудовані.
    • x\\(id=<<r)- це підмножина елементів x, яких немає в жодній із вже побудованих комірок.
    • [intersect x,(\\x)]<*>rрозбиває кожну клітинку rвідповідно до того, є її елементи xчи ні.
  • Більшість, безумовно, не намагається об'єднати порожні комірки, тому таких у виході є зовсім небагато.

Та сама ідея, що і моя реалізація, але на два байти коротше. Молодці!
Лайконі

4

Желе , 14 17 байт

FṀ‘³iþ¬Ḅµ;ṀḶ$ĠṖṖ€

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

Подання функції (оскільки формат, який друкує Jelly, списки за замовчуванням, не є зворотним - він не може прочитати власний формат виводу - але функція вводить і виводить у тому ж форматі). Посилання TIO містить колонтитул, який виконує функцію і друкує її вихід у тому ж форматі, що і вхід, який аналізується.

Пояснення

FṀ‘³iþ¬Ḅµ;ṀḶ$ĠṖṖ€
FṀ‘               Find the largest number that appears in any of the input sets, + 1
   ³ þ            For each number from 1 to that number, and each of the input sets
    i ¬             find whether the number is missing from the set
       Ḅ          Convert the list of missing sets into a single number using binary
         ;        Append
        µ ṀḶ$     all numbers from 0 to the maximum value minus 1
             Ġ    Group indexes by values
              ṖṖ€ Delete the last group and last element of other groups

Вимога, що ми виводимо щонайменше один порожній набір, якщо не використовуються всі розділи діаграми Венна, вдається зайняти понад половину програми тут (це відповідає за те, що гарантує, що у нас є принаймні одна група для невідповідних елементів, що дозволяє нам щоб відстежувати, скільки наборів було спочатку плюс останні дев'ять байтів вихідного коду, за винятком Ġ). Основний спосіб, яким ми його реалізуємо, - це забезпечити, щоб усі підмножини діаграми 2 ^ n Venn мали принаймні один запис, додавши фіктивний запис, який заповнить розділ "без наборів" та (пізніше) макетний запис до кожного інший розділ, то Ġвиведе групу для кожного підмножини, яку ми можемо видалити за допомогою ṖṖ€.


Гм, немає обмежень на щонайбільше 7 наборів, і в одному з тестових випадків є більше.
Ørjan Johansen

Я припускав, що початковий набір мав довжину 3, тому що так працюють діаграми Венна, але, мабуть, ні? У такому випадку, можливо, мені потрібен інший спосіб додати порожній набір, тільки якщо заповнені не всі розділи діаграми Венна. Це щось неприємне вада в тому, що інакше є досить елегантним питанням.

Ну, ви можете замінити 7 на 2 ^ n-1, я припускаю.
Ørjan Johansen

Я знайшов спосіб отримати значення 2 ^ n-1, яке відповідає специфікації, але це болісно довго. Сподіваємось, існує коротший шлях, але навіть це питання викликає розчарування.

4

Perl 5, 79 байт

sub{for$.(0..@_){$x{$_}+=2**$.for@{$_[$.]}};push@{$h{$x{$_}}},$_ for keys%x;%h}

Вводиться як список анонімних масивів типу ([2,3,7], [1,2,4,7,8], [4,7]). Виводить хеш, де ключі є мітками, а значення - анонімними масивами, що відповідають виводам наборів.

У рамках повної програми:

*x=
sub{for$.(0..@_){$x{$_}+=2**$.for@{$_[$.]}};push@{$h{$x{$_}}},$_ for keys%x;%h};
%x=x([2,3,7],[1,2,4,7,8],[4,7]);
print"Set $_:@{$x{$_}}\n"for keys%x;

Пояснення:

Дає кожен набір ціле число в якості мітки, $.. Створює хеш, який зберігає ціле число для кожного унікального елемента $_. Додає 2**$.для кожного набору, що $_з’являється в, ефективно роблячи двійкову карту, що показує, які набори відображаються в кожному елементі. Нарешті, робить анонімний масив для кожної комірки діаграми Venn і виштовхує елементи, що з’являються у відповідних наборах, до масиву. Отже, кожен елемент кожного масиву існує в одних і тих же наборах і, отже, однакова комірка діаграми Венна.


3

Pyth , 11 байт

m-@Fds-Qdty

Тестовий набір.

Як це працює

Кожна область діаграми Венна представляє елементи, які знаходяться в [певних комбінаціях множин], але не в [інших множинах].

Отже, ми генеруємо всі можливі комбінації (і видаляємо порожні комбінації), знаходячи набір потужності вводу.

Для кожної створеної комбінації ми знаходимо перетин множин у комбінації та фільтруємо елементи, що знаходяться в інших наборах.

m-@Fds-Qdty  input as Q
          y  power set
         t   remove the first one (empty combination)
m            for each combination d:
  @Fd            find the intersection of all the sets in d
 -               filter out those who are in
     s               the union of
      -Qd            the sets not in the combination
                     (input minus combination)

2

JavaScript (ES6), 123 байти

a=>a.map((b,i)=>b.map(e=>m[e]|=1<<i),m=[])&&[...Array(1<<a.length)].map((_,i)=>m.map((e,j)=>e==i&&j).filter(j=>j)).slice(1)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.