Hitung semua kisi-kisi integer yang mungkin dengan batasan


17

Masalah

Pertimbangkan kotak 3 x 3 bilangan bulat non-negatif. Untuk setiap baris ijumlah bilangan bulat ditetapkan menjadi r_i. Demikian pula untuk setiap kolom j, jumlah bilangan bulat dalam kolom itu ditetapkan c_j.

Tugasnya adalah menulis kode untuk menyebutkan semua kemungkinan penugasan bilangan bulat yang berbeda ke kisi mengingat batasan jumlah baris dan kolom. Kode Anda harus menampilkan satu tugas pada satu waktu.

Memasukkan

Kode Anda harus mengambil 3 bilangan bulat non-negatif menentukan batasan baris dan 3 bilangan bulat non-negatif menentukan batasan kolom. Anda dapat mengasumsikan bahwa ini valid, yaitu batasan jumlah atau baris sama dengan jumlah batasan kolom. Kode Anda dapat melakukan ini dengan cara apa pun yang nyaman.

Keluaran

Kode Anda harus menampilkan grid 2d yang berbeda yang dihitungnya dalam format yang dapat dibaca manusia pilihan Anda. Semakin cantik tentu saja lebih baik. Output tidak boleh mengandung duplikat grid.

Contoh

Jika semua batasan baris dan kolom persis 1maka hanya ada 6kemungkinan yang berbeda. Untuk baris pertama, Anda dapat menempatkan 1di salah satu dari tiga kolom pertama, untuk baris kedua sekarang ada2 alternatif dan baris terakhir sekarang sepenuhnya ditentukan oleh dua kolom sebelumnya. Segala sesuatu yang lain di grid harus diatur ke 0.

Katakanlah input 2 1 0untuk baris dan 1 1 1kolom. Menggunakan format output APL yang indah, kisi-kisi integer yang mungkin adalah:

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

Sekarang katakan input 1 2 3untuk baris dan 3 2 1kolom. Grid integer yang mungkin adalah:

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

Jawaban:


9

APL (Dyalog) , 42 byte

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

Cobalah online!

Menggunakan ⎕IO←0yang standar pada banyak sistem. Hal-hal lain di header hanya cukup mencetak untuk matriks (tampilan kotak).

Input adalah daftar enam nilai, jumlah baris pertama, lalu jumlah kolom.

Bagaimana?

o←⍳1+⌈/⍵- omendapatkan kisaran 0ke maksimum ( ⌈/) input

,o∘.,⊢- produk cartesian dengan odan ratakan ( ,)

⍣8 - Diulang selama delapan kali

3 3∘⍴¨ - bentuk setiap daftar 9-item ke dalam matriks 3 × 3

¨o←- simpan matriks ini untuk o, dan untuk masing-masing

+/,+⌿- periksa apakah jumlah baris ( +/) disatukan dengan jumlah kolom ( +⌿)

⍵≡ - sesuai dengan input

o/⍨- filter o(array matriks) dengan nilai-nilai yang sebenarnya


Jawaban yang sangat bagus ini perlu penjelasan (tolong).

@Lembik menambahkan penjelasan
Uriel

Terima kasih. Jadi Anda menghitung semua matriks yang mungkin dan memeriksa yang sesuai dengan kendala tampaknya. Bukan yang paling efisien, tetapi berhasil.

1
@Lembik yup, itu yang terpendek. Saya dapat mengelola yang sedikit lebih efisien dengan mendapatkan semua daftar 3-item yang dapat cocok dengan jumlah, kemudian memilih yang cocok dengan jumlah baris pertama kemudian memilih yang (untuk setiap kombinasi sebelumnya) yang cocok dengan jumlah kolom pertama, dan sebagainya bolak-balik. Itu akan menjadi algoritma umum non-brute-force.
Uriel

@EriktheOutgolfer terima kasih, saya selalu lupa untuk memperbarui jumlah byte saya
Uriel

7

Sekam , 20 17 byte

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

-3 byte terima kasih kepada @ H.PWiz

Mengambil input sebagai daftar yang xsmengkodekan kendala [r_1,r_2,r_3,c_1,c_2,c_3], coba online!

Penjelasan

Pendekatan kekerasan: P Hasilkan semua kisi 3x3 dengan entri [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 byte

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

Cobalah online!

PERINGATAN: OUTPUT JELEK!Jangan main-main, itu masih bisa dibaca manusia, saya tidak diharuskan menghitung berapa. ;)

Untuk beberapa alasan itu harus lebih lama dari apa yang saya harapkan masuk akal (13 byte):

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

Versi terakhir ini, jika berhasil, akan mengambil input dari output (yaitu argumen command-line) sebagai gantinya.


@Riker Baca bagian "Output" dari OP. Tentu, ia masih memiliki tanda kurung yang memisahkan kisi-kisi, itu bisa melucuti mereka juga dan hasilnya masih belum kehilangan data apa pun ...
Erik the Outgolfer

4

Python 2 , 149 145 142 141 138 136 byte

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*

Cobalah online!

Mengambil input sebagai daftar daftar: [[r1, c1], [r2, c2], [r3, c3]]


4

Haskell, 94 88 84 79 byte

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

Mengambil jumlah baris dan kolom sebagai daftar 6 elemen datar tunggal [r1,r2,r3,c1,c2,c3] .

Cobalah 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

Karena elemen-elemen dari matriks untuk menguji naik ke jumlah r, kode tidak selesai dalam waktu yang wajar untuk jumlah baris / kolom yang besar. Berikut ini adalah versi yang lebih tinggi ryang lebih cepat, tetapi lebih lama 4 byte: Coba online!


3

Mathematica, 81 byte

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

menemukan semua matriks 3x3 dengan elemen 0..Max dan memilih yang benar
ini berarti bahwa (Max+1)^9matriks harus diperiksa

Cobalah online!


Bisakah Anda menambahkan penjelasan?

3
@Lembik Saya akan, setelah Anda menambahkan beberapa test case dan membuat tantangan ini "jelas" untuk semua orang di sini. Saya memilih untuk membuka kembali tetapi Anda sepertinya tidak mencoba untuk membuat ini lebih baik untuk semua yang membutuhkan bantuan
J42161217

Ditambahkan ke pertanyaan sekarang.

Apa yang masih belum jelas? Saya Gridjuga bekerja dengan TIO, menggunakan ToString. Cobalah online!
user202729

@ user202729 tidak ada apa-apanya bagi saya, tetapi kasus tes tidak ada
J42161217

3

R , 115 110 byte

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)

Cobalah online!

Mengambil input sebagai c(r1,r2,r3,c1,c2,c3), tunggalvector , dan mencetak matriks ke stdout.

Ini sangat mirip dengan jawaban APL Uriel , tetapi menghasilkan grid 3x3 agak berbeda.

Membiarkannya M=max(S), ia menghasilkan vektor 0:M, lalu repmemakannya 9 kali, yaitu [0..M, 0...M, ..., 0...M]sembilan kali. Kemudian ia memilih semua kombinasi vektor baru yang diambil 9 pada satu waktu, menggunakan matrix, 3, 3untuk mengkonversi masing-masing 9-kombinasi ke dalam 3x3matriks, dan memaksa simplify=Funtuk mengembalikan daftar daripada array. Itu kemudian menyatukan daftar ini dan menyimpannya sebagaim .

Kemudian filter muntuk mereka yang jumlah baris / kolomnya identik dengan input, mencetak yang ada dan tidak melakukan apa pun untuk yang tidak.

Karena menghitung choose(9*(M+1),9)grid yang berbeda mungkin (lebih dari(M+1)^9 kemungkinan), itu akan kehabisan memori / waktu lebih cepat daripada jawaban yang lebih efisien (tapi kurang golf) di bawah:

R , 159 byte

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

Cobalah online!


R sangat welcome!

3

MATL , 35 22 byte

-13 byte berkat Luis Mendo

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

Cobalah online!

Tautan adalah ke versi kode yang mencetak sedikit lebih baik; versi ini hanya akan mencetak semua matriks dengan satu baris baru di antara mereka.

Mengambil input sebagai [c1 c2 c3 r1 r2 r3].

Jelas, ini menghitung kekuatan Cartesian X^dari 0...max(input)dengan eksponen 9, dan mentransposisi !. Kemudian loop di "atas kolom, membentuk kembali masing-masing@ - sebagai matriks 3x3 3e, menggandakan t, mentransposisi !, dan menyatukannya secara horizontal h. Kemudian menghitung jumlah kolom s, yang akan menghasilkan vektor [c1 c2 c3 r1 r2 r3]. Kami melakukan kesetaraan elemen ke input G=, dan jika ?semua bukan nol, kami memulihkan matriks yang benar dengan memilih input ke fungsi !dengan menggunakan 4M.


2

Batch, 367 byte

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

Kuadrat kiri 2 × 2 memaksa hasil, jadi pendekatan terbaik adalah untuk menghasilkan semua nilai untuk integer kiri atas, semua nilai yang valid untuk jumlah dari kiri atas dan integer tengah atas, semua nilai yang valid untuk jumlah atas integer kiri dan kiri tengah, dan menghitung rentang nilai yang valid untuk integer tengah, kemudian, setelah melewati semua rentang yang sesuai, hitung nilai yang tersisa dari kendala.


1

Python 2 , 118 byte

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)

Cobalah online!


Python 2 , 123 byte

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

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.