Перечислите все возможные сетки целых чисел с ограничениями


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и для каждого

+/,+⌿- проверить, соединены ли строки sums ( +/) со столбцами sums ( +⌿)

⍵≡ - соотноситься с вводом

o/⍨- фильтр o(массив матриц) по истинным значениям


Этот очень красивый ответ нуждается в объяснении (пожалуйста).

@Lembik добавил объяснение
Уриэль

Благодарю. Таким образом, вы перечисляете все возможные матрицы и проверяете те, которые соответствуют ограничениям, которые кажутся. Не самый эффективный, но работает.

1
@Lembik Да, это самое короткое. Я мог бы управлять немного более эффективным, получив все списки из 3 элементов, которые могут совпадать с суммами, затем выбрать те, которые соответствуют сумме первой строки, затем выбрать те (для каждой из предыдущих комбинаций), которые соответствуют сумме первых столбцов, и так далее туда и обратно. Это был бы общий алгоритм без грубой силы.
Уриэль

@EriktheOutgolfer спасибо, я всегда забываю обновить счетчик байтов
Уриэль

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 Создайте все сетки 3x3 с записями [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 Прочитайте раздел «Вывод» ОП. Несомненно, у него все еще есть скобки, разделяющие сетки, он мог бы также удалить их, и результат все равно не потерял бы никаких данных ...
Эрик Игрок в гольф

4

Python 2 , 149, 145, 142, 141, 138, 136 байт.

lambda s:[i for i in product(range(max(sum(s,[]))+1),repeat=9)if[map(sum,(i[j:j+3],i[j/3::3]))for j in 0,3,6]==s]
from itertools import*

Попробуйте онлайн!

Вводит в виде списка списков: [[r1, c1], [r2, c2], [r3, c3]]


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

Mathematica, 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. Попробуйте онлайн!
user202729

@ 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, и печатает матрицы в стандартный вывод.

Это очень похоже на ответ 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, и транспонирование !. Затем он "перебирает столбцы, изменяя @форму каждого из них как матрицу 3х3 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.