Wymień wszystkie możliwe siatki liczb całkowitych z ograniczeniami


17

Problem

Rozważ kwadratową siatkę 3 na 3 liczb całkowitych nieujemnych. Dla każdego wiersza iustawiana jest suma liczb całkowitych r_i. Podobnie dla każdej kolumny justawiana jest suma liczb całkowitych w tej kolumnie c_j.

Zadanie polega na napisaniu kodu wyliczającego wszystkie możliwe różne liczby całkowite do siatki, biorąc pod uwagę ograniczenia sumy wierszy i kolumn. Twój kod powinien wyświetlać jedno zadanie na raz.

Wejście

Twój kod powinien przyjąć 3 nieujemne liczby całkowite określające ograniczenia wiersza i 3 nieujemne liczby całkowite określające ograniczenia kolumny. Możesz założyć, że są one poprawne, tzn. Że ograniczenia sumy lub wiersza są równe sumie ograniczeń kolumny. Twój kod może to zrobić w dowolny dogodny sposób.

Wynik

Twój kod powinien wypisywać różne siatki 2D, które oblicza, w dowolnym formacie czytelnym dla człowieka. Im ładniejsza, tym lepiej. Dane wyjściowe nie mogą zawierać zduplikowanych siatek.

Przykład

Jeśli wszystkie ograniczenia wierszy i kolumn są dokładnie takie same, 1istnieją tylko 6inne możliwości. W pierwszym rzędzie możesz umieścić a 1w dowolnej z pierwszych trzech kolumn, w drugim rzędzie są teraz 2alternatywy, a ostatni rząd jest teraz całkowicie określony przez poprzednie dwa. Wszystko inne w siatce powinno być ustawione na 0.

Powiedzmy, że dane wejściowe dotyczą 2 1 0wierszy i 1 1 1kolumn. Używając pięknego formatu wyjściowego APL, możliwe są następujące liczby całkowite:

┌─────┬─────┬─────┐
│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│
└─────┴─────┴─────┘

Powiedzmy teraz, że dane wejściowe dotyczą 1 2 3wierszy i 3 2 1kolumn. Możliwe siatki liczb całkowitych to:

┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│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│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

Odpowiedzi:


9

APL (Dyalog) , 42 bajty

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

Wypróbuj online!

Używa ⎕IO←0ustawień domyślnych w wielu systemach. Inne elementy w nagłówku to po prostu drukowanie matryc (wyświetlanie w ramkach).

Dane wejściowe to lista sześciu wartości, najpierw sumy wierszy, a następnie sumy kolumn.

W jaki sposób?

o←⍳1+⌈/⍵- opobiera zakres 0do maksimum ( ⌈/) wejścia

,o∘.,⊢- produkt kartezjański zi ospłaszczony ( ,)

⍣8 - powtarzane osiem razy

3 3∘⍴¨ - uformuj każdą listę 9-elementową w matrycę 3 × 3

¨o←- zapisz te macierze oi dla każdego

+/,+⌿- sprawdź, czy sumy wierszy ( +/) są połączone z sumami kolumn ( +⌿)

⍵≡ - korespondują z danymi wejściowymi

o/⍨- filtruj o(tablica macierzy) według prawdziwych wartości


Ta bardzo ładna odpowiedź wymaga wyjaśnienia (proszę).

@Lembik dodał wyjaśnienie
— Uriel

Dzięki. Więc wyliczyć wszystkie możliwe macierze i sprawdzić te, które pasują do ograniczeń, które się wydają. Nie najskuteczniejszy, ale działa.

1
@Lembik, tak, to jest najkrótsze. Mógłbym zarządzać nieco bardziej wydajną, uzyskując wszystkie listy 3-elementowe, które mogą pasować do sum, a następnie wybrać te, które pasują do sumy z pierwszego wiersza, a następnie wybrać te (dla każdej z poprzednich kombinacji), które pasują do sumy z pierwszych kolumn, i tak dalej. Byłby to ogólny algorytm bez użycia siły.
— Uriel

@EriktheOutgolfer dzięki, zawsze zapomniałem zaktualizować moją liczbę bajtów
— Uriel

7

Łuska , 20 17 bajtów

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

-3 bajty dzięki @ H.PWiz

Pobiera dane wejściowe jako listę xskodującą ograniczenia [r_1,r_2,r_3,c_1,c_2,c_3], spróbuj online!

Wyjaśnienie

Podejście brutalnej siły: P Wygeneruj wszystkie siatki 3x3 z wpisami [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

Brachylog , 17 bajtów

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

Wypróbuj online!

OSTRZEŻENIE: Brzydkie wyjście! Nie szukaj, to wciąż jest czytelne dla człowieka, nie muszę rozliczać się z tego, ile. ;)

Z jakiegoś powodu musi być znacznie dłuższy niż to, co miałbym sens (13 bajtów):

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

Ta ostatnia wersja, jeśli zadziała, pobierałaby dane wejściowe z danych wyjściowych (tj. Argument wiersza poleceń).


@Riker Przeczytaj rozdział „Wyjście” PO. Jasne, wciąż ma nawiasy oddzielające siatki, mógł je również rozebrać, a dane wyjściowe nadal nie
— utracą

4

Python 2 , 149 145 142 141 138 136 bajtów

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*

Wypróbuj online!

Pobiera dane wejściowe jako listę list: [[r1, c1], [r2, c2], [r3, c3]]


4

Haskell, 94 88 84 79 bajtów

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

Sumuje wiersze i kolumny jako pojedynczą płaską 6-elementową listę [r1,r2,r3,c1,c2,c3].

Wypróbuj online!

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

Ponieważ elementy testowanych macierzy dochodzą do sumy r, kod nie kończy się w rozsądnym czasie dla dużych sum wierszy / kolumn. Oto wersja, która zwiększa się do maksimum, rjest szybsza, ale o 4 bajty dłuższa: Wypróbuj online!


3

Mathematica, 81 bajtów

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

znajduje wszystkie macierze 3x3 z elementami 0..Max i wybiera odpowiednie,
co oznacza, że (Max+1)^9macierze muszą zostać sprawdzone

Wypróbuj online!


Czy możesz dodać wyjaśnienie?

3
@Lembik Zrobię to, po dodaniu kilku przypadków testowych i uczynieniu tego wyzwania „jasnym” dla wszystkich ludzi tutaj. Głosowałem za ponownym otwarciem, ale nie wydaje się, aby próbowaliście ulepszyć to dla wszystkich, którzy potrzebują pomocy
— J42161217

Dodano do pytania teraz.

Co jest nadal niejasne? / Gridrównież współpracuj z TIO, używając ToString. Wypróbuj online!
— user202729,

@ user202729 nic dla mnie, ale brakowało przypadków testowych
— J42161217,

3

R , 115 110 bajtów

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)

Wypróbuj online!

Pobiera dane wejściowe jako c(r1,r2,r3,c1,c2,c3)pojedynczy vectori wypisuje macierze na standardowe wyjście.

Jest dość podobny do odpowiedzi APL Uriela , ale generuje siatki 3x3 nieco inaczej.

Pozwalając M=max(S), generuje wektor 0:M, a następnie repje 9 razy, czyli [0..M, 0...M, ..., 0...M]dziewięć razy. Następnie wybiera wszystkie kombinacje tego nowego wektora pobranego 9 na raz, używając matrix, 3, 3do konwersji każdej 9 kombinacji na 3x3macierz i zmuszając simplify=Fdo zwrócenia listy zamiast tablicy. Następnie ujednolica tę listę i zapisuje ją jako m.

Następnie filtruje mte, w których sumy wierszy / kolumn są identyczne z danymi wejściowymi, drukując te, które są, i nie robiąc nic dla tych, które nie są.

Ponieważ oblicza choose(9*(M+1),9)różne możliwe siatki (więcej niż (M+1)^9możliwości), zabraknie pamięci / czasu szybciej niż bardziej wydajna (ale mniej golfowa) odpowiedź poniżej:

R , 159 bajtów

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))]

Wypróbuj online!


R jest bardzo mile widziane!

3

MATL , 35 22 bajtów

-13 bajtów dzięki Luisowi Mendo

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

Wypróbuj online!

Link jest wersją kodu, która drukuje się trochę ładniej; ta wersja po prostu wydrukuje wszystkie macierze z jedną nową linią między nimi.

Pobiera dane wejściowe jako [c1 c2 c3 r1 r2 r3].

Oczywiście, to oblicza kartezjański moc X^o 0...max(input)z wykładnikiem 9i transpozycji !. Następnie zapętla się "nad kolumnami, przekształcając każdą z nich @w matrycę 3x3 3e, kopiując t, transponując !i konkatenując w poziomie h. Następnie oblicza sumy kolumn s, co da wektor [c1 c2 c3 r1 r2 r3]. Robimy elementarną równość względem danych wejściowych G=, a jeśli ?wszystkie są niezerowe, odzyskujemy prawidłową macierz, wybierając dane wejściowe do funkcji !za pomocą 4M.


2

Partia, 367 bajtów

@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(

Lewy górny kwadrat 2 × 2 wymusza wynik, więc najlepszym podejściem jest wygenerowanie wszystkich wartości dla lewej górnej liczby całkowitej, wszystkich prawidłowych wartości dla sumy lewej górnej i górnej środkowej liczby całkowitej, wszystkich prawidłowych wartości dla sumy górnej lewą i środkową lewą liczbą całkowitą i oblicz zakres prawidłowych wartości dla środkowej liczby całkowitej, a następnie, po przejściu przez wszystkie odpowiednie zakresy, oblicz pozostałe wartości z ograniczeń.


1

Python 2 , 118 bajtów

def f(v,l=[],i=0):n=len(l);V=v*1;V[~n/3]-=i;V[n%3]-=i;return[l][any(V):]if n>8else V*-~min(V)and f(V,l+[i])+f(v,l,i+1)

Wypróbuj online!


Python 2 , 123 bajty

V=input()
n=max(V)+1
for k in range(n**9):
 m=[];exec"m+=[k%n,k/n%n,k/n/n%n],;k/=n**3;"*3
 if map(sum,m+zip(*m))==V:print m

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.