Негативні пробіли


13

Завдання

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

Нетехнічні

Графік - це набір вузлів, які з'єднані лініями. Кожну пару точок можна з'єднати одним рядком або жодним. "Доповнення" графа є результатом взяття графіка та з'єднання всіх вузлів, які не пов'язані між собою, та від'єднання всіх вузлів, які є.

Самодоповнюючий графік - це графік, доповнення якого можна переставити у форму оригіналу. Нижче наводиться приклад самодоповнюючого графіка та демонстрація того, як.

Ось графік з 5 вузлами:

5-вузловий графік

Ми виділимо всі місця, де з'єднання могли пройти червоними пунктирними лініями:

Виділена графіка

Тепер ми знайдемо доповнення графіка, замінивши червоні та чорні краї:

Доповнення

Це не схоже на початковий графік, але якщо ми переміщуємо вузли так (кожен крок міняє два вузли):

Ізоморфізм

Отримуємо оригінальний графік! Графік та його доповнення - той самий графік

Технічні

Самодоповнюючий графік - це графік, ізоморфний його доповненню.

Технічні умови

Ви отримаєте додатне ціле число будь-яким методом, який вам найбільше підходить. І ви виведете графік будь-яким методом, який вважатимете за потрібне , це включає, але не обмежується Матричною формою суміжності , Формою списку суміжності та, звичайно, зображеннями! Виведений графік повинен бути власним доповненням і мати стільки вузлів, скільки цілий вхід. Якщо такого графіка немає, потрібно вивести хибне значення.

Це і ви повинні прагнути мінімізувати кількість байтів.

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

Нижче наведено зображення можливих виходів для декількох n

4

5

9


Самодоповнюючий графік може існувати лише там, коли повний графік має парну кількість ребер. Ми гарантуємо це?
xnor

@xnor Я забув включити це. Виправлено зараз.
Ad Hoc Hunter Hunter

Чи потрібно обробляти негативні входи?
xnor

@xnor Ні. Я виправлю питання, яке буде конгруентним
Ad Hoc Garf Hunter

3
Перш ніж хтось здобуде ідею грунтуватися на відповіді GraphData@{"SelfComplementary",{#,1}}&, я вважаю, що просто завантажує деякі приклади низько nз бази даних Wolfram, тому це не спрацює для довільно великих даних.
Мартін Ендер

Відповіді:


9

Haskell , 77 байт

f n=[(a,b)|b<-[1..n],a<-[1..b-1],mod n 4<2,mod(a+(last$b:[a|odd n,n==b]))4<2]

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

Для визначення чіткого критерію, що дозволяє легко обчислити, для визначення того, чи (a,b)належить ребро до графіка. Вмикає цей алгоритм з перестановкою перестановки серед значень модуля 4

4*m -> 4*m+1 -> 4*m+2 -> 4*m+3 -> 4*m

Ми включаємо ребра, дві вершини кінцевих точок додають 0 або 1 модуль 4. Зауважте, що вершини на велосипеді відповідно до цієї перестановки додають по 2 модуля 4 до суми вершин на кожній, і так змінюються місцями ребра та не-ребра. Це дає перестановку вершин, що доповнює ребра.

Якщо графік має додатковий вузол, що перевищує кратне 4, він ставиться в циклі самостійно. Ми включаємо ребра з ним, коли тоді інша вершина є рівною. Перестановка вершин відвертає паритет, і таким чином графік залишається самодоповнюваним.

Якщо кількість вершин не дорівнює 0 або 1 по модулю 4, не можливий самодоповнюючий графік, оскільки в повному графіку є непарна кількість ребер

Загалом, ось такі умови:

  • Якщо вхід n не дорівнює 0 або 1 модуль 4, виведіть порожній список
  • В іншому випадку , якщо п парне, включають в себе всі ребра (a,b)з a<bі a+bрівні 0 або 1 по модулю 4.
  • В іншому випадку, якщо n є непарним, зробіть те ж саме, але замість цього додайте краї форми, (a,n)коли a є парним.

Код поєднує другий і третій випадки, замінюючи умову mod(a+b)4<2на mod(a+a)4<2коли і odd nі b==n.


5

Брахілог 2 , 24 байти

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧

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

Це функція, яка повертає пару, що складається з двох списків суміжності: один для графа, один для графа доповнення. (У інтерпретаторі Brachylog на TIO ви можете попросити його оцінити функцію, а не повну програму, шляхом надання Zв якості аргументу командного рядка.) Наприклад, вихід для введення 5:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

Ось як це виглядає як зображення (показує два графіки):

графік та його однакове доповнення на 5 елементах

Як звичайно для мов на основі Prolog, функція підтримує більше однієї схеми виклику. Зокрема, якщо ви спробуєте використовувати його як генератор, він виведе всі можливі взаємодоповнюючі графіки із заданою кількістю вершин (хоча я не доклав жодних зусиль, щоб зробити цей випадок корисним, і, зокрема, він видасть кожну з графіки багато разів кожен).

Пояснення

Це в основному лише опис проблеми, а реалізація Prolog залишає найкращий спосіб її вирішення. (Однак я сумніваюся, що в цьому конкретному випадку буде використаний алгоритм, кращий за грубу силу, тому це, ймовірно, досить неефективно, і тестування, здається, підтверджує це, показуючи, що продуктивність стає набагато гіршою, чим більший графік.)

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧
 ⟦₁                       The range [1, 2, …, ?], where ? is the input
   ⊇                      A subset of that range…
    Ċ                     …which has exactly two elements
{    }ᶠ                   A list of everything that fits the above description
{⟦₁⊇Ċ}ᶠ                   All edges that could exist in a ?-element graph
       p                  Find a permutation of these…
        ḍ                 …so that splitting it into two equal parts…
          (       ∨   )   …either:
               dl?          produces ? distinct elements
           \                after transposing it
            \ᵐ              and transposing its elements
              c             and flattening one level;
                          or:
                   ?<2      ? was less than 2
         .             ∧  Once you've found it, . specifies what to output

Між іншим, мені довелося витратити цілих 6 байт (¼ програми, символи (∨?<2)), розглядаючи особливі випадки 0 і 1. Розчарування, але така природа особливих випадків.

\\ᵐcdl?Розділ трохи важко зрозуміти, так ось оброблений приклад. Її мета - перевірити, чи є щось графіком та його доповненням, причому відповідні ребра у графіку та доповнення є в одному порядку в межах списків. Пара графіка / доповнення стає кінцевим результатом програми. Ось приклад випадку:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

Транспоніруючи це, ми отримуємо список пар відповідних ребер між графіком та доповненням:

[[[1,2],[2,5]],[[1,3],[2,3]],[[1,5],[2,4]],[[3,5],[3,4]],[[4,5],[1,4]]

Далі перекладаємо всередину елементи списку і вирівнюємо один рівень; що дає нам список пар відповідних елементів між графіком та доповненням:

[[1,2],[2,5],[1,2],[3,3],[1,2],[5,4],[3,3],[5,4],[4,1],[5,4]]

Зрозуміло, що ми хочемо тут, щоб не було більше 1 пари, починаючи від кожного елемента (таким чином доводимо, що елементи графіка та доповнення знаходяться у відповідності 1 на 1). Ми майже можемо переконатись у тому, що, констатуючи, що у списку є абсолютно ?чіткі елементи (тобто кількість чітких елементів, рівних кількості вершин). У цьому випадку тест успішний; різними елементами є:

[[1,2],[2,5],[3,3],[5,4],[4,1]]

Однак це залишає місце для потенційної проблеми; якщо вершина повністю відключена в оригінальному графіку, її відповідність не буде згадуватися, що залишає місце для дублювання кореспонденції від якоїсь іншої вершини. Якщо це так, доповнення графік повинен мати межу між цією вершиною (без обмеження спільності, припустимо , що це 1), і кожна інша вершина, і тому список відповідностей буде містити [1,2], [1,3], ..., [1, ?]. Коли ?це велика кількість, це призведе до отримання загальної кількості відповідностей, ніж у нас, тому немає жодної проблеми. Єдине питання трапляється, коли ?це 3 або менше, і тоді ми додаємо лише одну додаткову кореспонденцію (видаляючи з неї1не відображається на вході); однак це не є проблемою на практиці, оскільки на 3-елементному графі є 3 можливі ребра, що є непарним числом (аналогічно, 1 можливий край на двоелементному графіку також є непарним числом), і, таким чином, тест не вдасться на \кроці (ви не можете перенести роздрібнений список, тобто ті, елементи яких мають різну довжину).


Різниця між zі в \тому , що zциклічний поштовий, а це означає , що [[1,2,3],["a"]]буде в кінцевому підсумку [[1,"a"],[2,"a"],[3,"a"]]з z, в той час як вона НЕ буде виконана в протягом \. \зараз працює лише на квадратних матрицях; майбутня реалізація зробить це схожим z, крім циклічного.
Фаталізувати

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

2

BBC BASIC, 161 байт

Токенізований розмір файлів 140 байт

Завантажте перекладача за посиланням http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

I.m:IF2ANDm ORm<4P.0:END
r=400n=-2A.m:t=2*PI/n:F.i=1TOn*n:a=i DIVn:b=i MODn:c=b:IFa+b A.2a*=t:b*=t:L.r+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1A.m A.c DRAWr*3,0
N.

Невикористаний код

  INPUTm                           :REM get input
  IF2ANDm ORm<4PRINT0:END          :REM if m=4x+2 or 4x+3 or less than 4, print 0 and exit
  r=400                            :REM radius of diagram
  n=-2ANDm                         :REM n = m truncated to an even number
  t=2*PI/n                         :REM t = 1/n turns
  FORi=1TOn*n                      :REM for each combination of vertices
    a=i DIVn                       :REM extract a and b
    b=i MODn                       :REM make a copy of c
    c=b                            :REM if a+b MOD 4 = 2 or 3, convert a and b to angles and draw edge.
    IFa+b AND2 a*=t:b*=t:LINEr+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1ANDm ANDc DRAWr*3,0
  NEXT                             :REM if m is odd and c is odd, draw a line to the additional vertex for m=4x+1 input.

Пояснення

Для цього використовується той же алгоритм, що і Xnor, але виробляється діаграматичний вихід.

Де nє форма 4x+2або 4x+3немає рішення, оскільки кількість ребер непарне.

Де nє форма 4x, ми розташовуємо всі вершини по колу і малюємо ті ребра, де (a+b) mod 4дорівнює 2 або 3 (не 0 або 1, як у випадку Xnor, з міркувань гольфу. Тому це доповнення рішення, поданого Xnor.)

Щоб побачити це в більш пікторальному сенсі, ми беремо кожну другу вершину і малюємо краї до вершин 1 і 2 місцями в напрямку проти годинникової стрілки. Це визначає nпаралельні напрямки, половину від загальної кількості. Потім додаємо всі інші ребра, паралельні цим.

Доповнення можна знайти, додавши 1 до а і b у кожній специфікації краю, або пікторально, обертаючи діаграму 1/nповоротом.

Де nє форма 4x + 1, ми додаємо ще одну вершину, яка пов'язана з кожною другою вершиною 4x графа. Якби вона була розміщена в центрі, симетричність діаграми була б збережена, але я вирішив розмістити її поза основним колом точок для наочності.

Вихідні дані

Нижче наведено перші кілька випадків для 4х + 1. чотири випадки можна побачити, видаливши вершину праворуч внизу та пов’язані з нею ребра.

введіть тут опис зображення


1

JavaScript (ES6), 191 байт

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a

Ця функція повертає список суміжності. Він використовує два алгоритми та розрізняє порожні додаткові графіки та невиходи, повертаючись 0замість того, []коли не існує. Перший алгоритм ґрунтується на графіках Rado, побудованих за допомогою предиката BIT , і створює дійсні додаткові графіки 0-, 1-, 4- та 5 порядку. Інший алгоритм, знайдений нашими друзями з математики , конструює дійсний допоміжний графік вершин V + 4, застосовуючи додавання 4-х шляхів до дійсного додаткового графа V вершин.

Він починається з перевірки введення, щоб підтвердити існування дійсного додаткового графіка (використовуючи n*~-n/4%1), а якщо це не вдалося , повертається 0. Потім він перевіряє, чи n>5повертається до n-4випадку, щоб побудувати дійсне рішення нижчого порядку, а потім застосовує 4-додавання до повернутого списку суміжності на шляху резервного копіювання ланцюга рекурсії. І, нарешті, якщо n>5це не так, він перебирає від 0до n-1для xі y, і перевіряє , є чи (y>>x)&1це правдою. Якщо так, то ці вузли спарені.

Ось більш читабельний формат функції, з потрійними операторами, розширеними на оператори if-else та eval()s вкладеними:

// precalculate amount of required vertices in v
f = (n, a = [], v = n*~-n / 4) => {
  // if amount is non-integer
  if (v % 1) {
    // no valid complementary graph
    return 0;
  } else {
    if (n > 5) {
      // generate valid (n-4)-order complementary graph
      f(n -= 4, a);
      // apply 4-path addition
      for (i = 0; i < n;)
        a.push([i, n+1],[i++, n+2]);
      a.push([n, ++n], [n, ++n], [n, ++n]);
    } else {
      // construct Rado graph using BIT predicate
      for(l = x = 0; x < n; x++)
        for(y = x; y < n; y++)
          // if amount of pairs is less than required and xth bit of y is high
          if (l < v && (y>>x & 1))
            // vertices x and y should be paired
            a.push([x,y]);
    }
    return a;
  }
};

Демо

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a
<input type="number" onchange="o.textContent=JSON.stringify(f(this.value))"><pre id="o"></pre>

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