Перерахуйте всі можливі сітки цілих чисел із обмеженнями


17

Проблема

Розглянемо квадрат 3 на 3 сітки невід’ємних цілих чисел. Для кожного рядка iвстановлюється сума цілих чисел r_i. Аналогічно для кожного стовпця jвстановлюється сума цілих чисел у цьому стовпці c_j.

Завдання полягає в написанні коду для перерахування всіх можливих різних призначень цілих чисел до сітки з урахуванням обмежень суми рядків і стовпців. Ваш код повинен виводити по одному завдання одночасно.

Вхідні дані

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

Вихідні дані

Ваш код повинен виводити різні 2d сітки, які він обчислює, у будь-якому читаному для людини форматі на ваш вибір. Чим красивіше, тим краще, звичайно. Вихідні дані не повинні містити повторюваних сіток.

Приклад

Якщо всі обмеження рядків і стовпців точно такі, 1то існують лише 6різні можливості. Для першого ряду ви можете помістити 1будь-який із перших трьох стовпців, для другого ряду - зараз2 альтернативи, а останній ряд тепер повністю визначається попередніми двома. Все інше в сітці повинно бути встановлено 0.

Скажімо, вхід 2 1 0для рядків та 1 1 1стовпців. Використовуючи прекрасний вихідний формат APL, можливими цілими сітками є:

┌─────┬─────┬─────┐
│0 1 1│1 0 1│1 1 0│
│1 0 0│0 1 0│0 0 1│
│0 0 0│0 0 0│0 0 0│
└─────┴─────┴─────┘

Тепер скажіть, що введення призначено 1 2 3для рядків та 3 2 1стовпців. Можливі цілі сітки:

┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│
│0 2 0│1 1 0│2 0 0│0 1 1│1 0 1│1 1 0│2 0 0│0 1 1│0 2 0│1 0 1│1 1 0│2 0 0│
│3 0 0│2 1 0│1 2 0│3 0 0│2 1 0│2 0 1│1 1 1│2 1 0│2 0 1│1 2 0│1 1 1│0 2 1│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

Відповіді:


9

APL (Dyalog) , 42 байти

{o/⍨(⍵≡+/,+⌿)¨o←3 3∘⍴¨(,o∘.,⊢)⍣8⊢o←⍳1+⌈/⍵}

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

Використання ⎕IO←0 за замовчуванням у багатьох системах. Інший матеріал у заголовку - це просто гарне друк для матриць (коробчастий дисплей).

Введення - це список із шести значень, спочатку підсумовуються рядки, потім підсумовуються стовпці.

Як?

o←⍳1+⌈/⍵- oотримує діапазон 0до максимуму ( ⌈/) введення

,o∘.,⊢- декартовий продукт із oі сплющують ( ,)

⍣8 - повторювали вісім разів

3 3∘⍴¨ - сформуйте кожен 9-ти список списку в матрицю розміром 3 × 3

¨o←- збережіть ці матриці до oі для кожної

+/,+⌿- перевірити, чи рядки сум ( +/) приєднані до суми стовпців ( +⌿)

⍵≡ - відповідають з введенням

o/⍨- фільтр o(масив матриць) за трибунними значеннями


Ця дуже красива відповідь потребує пояснення (будь ласка).

@Lembik додав пояснення
Уріель

Спасибі. Таким чином, ви перераховуєте всі можливі матриці і перевіряєте ті, що відповідають обмеженням, що здається. Не найефективніший, але він працює.

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

@EriktheOutgolfer спасибі, я завжди забуваю оновити кількість байтів
Uriel

7

Лушпиння , 20 17 байт

fȯ=⁰mΣS+Tπ3π3Θḣ▲⁰

-3 байти завдяки @ H.PWiz

Приймає введення як список, що xsкодує обмеження [r_1,r_2,r_3,c_1,c_2,c_3], спробуйте в Інтернеті!

Пояснення

Підхід грубої сили: P Створіть усі сітки 3х3 із записами [0..max xs]:

f(=⁰mΣS+T)π3π3Θḣ▲⁰  -- input ⁰, for example: [1,1,1,1,1,1]
                ▲⁰  -- max of all constraints: 1
               ḣ    -- range [1..max]: [1]
              Θ     -- prepend 0: [0,1]
            π3      -- 3d cartesian power: [[0,0,0],...,[1,1,1]]
          π3        -- 3d cartesian power: list of all 3x3 matrices with entries [0..max] (too many)
f(       )          -- filter by the following predicate (eg. on [[0,0,1],[1,0,0],[0,1,0]]):
      S+            --   append to itself, itself..: [[0,0,1],[1,0,0],[0,1,0],..
        T           --   .. transposed:             ..[0,1,0],[0,0,1],[1,0,0]]
      mΣ            --   map sum: [1,1,1,1,1,1]
    =⁰              --   is it equal to the input: 1

6

Брахілог , 17 байт

{~⟨ṁ₃{ℕᵐ+}ᵐ²\⟩≜}ᶠ

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

ПОПЕРЕДЖЕННЯ.Не вигадуйте, це все ще читається по-людськи, я не зобов’язаний рахувати скільки. ;)

Чомусь це має бути набагато довше, ніж те, що я б очікував, що має сенс (13 байт):

⟨ṁ₃{ℕᵐ+}ᵐ²\⟩ᶠ

Ця остання версія, якби вона працювала, замість цього брала б дані з виводу (тобто аргументу командного рядка).


@Riker Прочитайте розділ "Вихідні дані" ОП. Звичайно, у нього все ще є дужки, що розділяють сітки, він також міг їх позбавити, і вихід все одно не втратив би жодних даних ...
Erik the Outgolfer


4

Haskell, 94 88 84 79 байт

q=mapM id.(<$"abc")
f r=[k|k<-q$q$[0..sum r],(sum<$>k)++foldr1(zipWith(+))k==r]

Приймає суми рядків і стовпців як єдиний плоский 6-елементний список [r1,r2,r3,c1,c2,c3] .

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

q=mapM id.(<$"abc")         -- helper function 

f r =                       -- 
  [k | k <-   ,    ]        -- keep all k
    q$q$[0..sum r]          --   from the list of all possible matrices with
                            --   elements from 0 to the sum of r
                            -- where
    (sum<$>k) ++            --   the list of sums of the rows followed by
    foldr1(zipWith(+))k     --   the list of sums of the columns
    == r                    -- equals the input r

Оскільки елементи матриць для тестування досягають суми r, код не закінчується в розумні строки для великих сум рядків / стовпців. Ось версія, яка досягає максимуму, rяка швидша, але на 4 байти довше: Спробуйте в Інтернеті!


3

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

Select[0~Range~Max[s=#,t=#2]~g~3~(g=Tuples)~3,(T=Total)@#==s&&T@Transpose@#==t&]&

знаходить усі матриці 3x3 з елементами 0..Max і вибирає правильні,
це означає, що (Max+1)^9матриці потрібно перевірити

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


Чи можете ви додати пояснення, будь ласка.

3
@Lembik Я, після того, як ви додасте кілька тестових випадків і зробить цей виклик "зрозумілим" для всіх людей тут. Я проголосував за повторне відкриття, але ви, схоже, не намагаєтесь зробити це кращим для всіх, хто потребує допомоги
J42161217

Додано до питання зараз.

Що ще незрозуміло? / Gridтакож працювати з TIO, використовуючи ToString. Спробуйте в Інтернеті!
користувач202729

@ user202729 мені нічого, але тестових справ не вистачало
J42161217

3

R , 115 110 байт

function(S)for(m in unique(combn(rep(0:max(S),9),9,matrix,F,3,3)))if(all(c(rowSums(m),colSums(m))==S))print(m)

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

Приймає введення як c(r1,r2,r3,c1,c2,c3)одиничнеvector і друкує матриці для stdout.

Це досить схоже на відповідь Уріеля APL , але генерує сітки 3x3 дещо інакше.

Випускаючи M=max(S), він генерує вектор 0:M, потім repз'їдає його 9 разів, тобто [0..M, 0...M, ..., 0...M]дев'ять разів. Потім він вибирає всі комбінації того нового вектора, взятого 9 за один раз, використовуючи matrix, 3, 3для перетворення кожної 9-комбінації в 3x3матрицю, і змушує simplify=Fповернути список, а не масив. Потім він уніфікує цей список і зберігає його якm .

Потім він фільтрує m за тими, де суми рядків / стовпців ідентичні вхідним, друкуючи ті, що є, і нічого не роблячи для тих, хто не є.

Оскільки він обчислює choose(9*(M+1),9)різні можливі сітки (більше (M+1)^9можливостей), у нього втрачається пам'ять / час швидше, ніж більш ефективний (але менш гострий) відповідь нижче:

R , 159 байт

function(S,K=t(t(expand.grid(rep(list(0:max(S)),9)))))(m=lapply(1:nrow(K),function(x)matrix(K[x,],3,3)))[sapply(m,function(x)all(c(rowSums(x),colSums(x))==S))]

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


R дуже вітаємо!

3

MATL , 35 22 байт

-13 байт завдяки Луїсу Мендо

X>Q:q9Z^!"@3et!hsG=?4M

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

Посилання - на версію коду, яка друкує трохи приємніше; ця версія буде просто надрукувати всі матриці з єдиним новим рядком між ними.

Вводиться як " [c1 c2 c3 r1 r2 r3] .

Очевидно, що це обчислює декартово потужність X^з 0...max(input)з показником 9, і транспонування !. Потім вона "перекидається на стовпчики, переробляючи кожну @як матрицю 3x3 3e, дублюючи t, транспонуючи !та з'єднуючи їх по горизонталі h. Потім він обчислює суми стовпців s, що призведе до вектора [c1 c2 c3 r1 r2 r3]. Ми робимо елементарно рівність вводу G=, і якщо ?всі ненульові, ми відновлюємо правильну матрицю, вибираючи вхід до функції !за допомогою 4M.


2

Пакетна, 367 байт

@echo off
for /l %%i in (0,1,%1)do for /l %%j in (%%i,1,%1)do for /l %%k in (%%i,1,%4)do call:c %* %%i %%j %%k
exit/b
:c
set/a"a=%1-%8,c=%4-%9,f=%8-%7,g=%9-%7,l=%5-f,m=%2-g,l^=m-l>>31&(m^l),m=%5+c-%3-f,m&=~m>>31
for /l %%l in (%m%,1,%l%)do set/a"b=%2-g-%%l,d=%5-f-%%l,e=%6-a-b"&call:l %7 %%l
exit/b
:l
echo %1 %f% %a%
echo %g% %2 %b%
echo %c% %d% %e%
echo(

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


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