Kısıtlamalarla tüm olası tamsayı ızgaralarını numaralandırma


17

Sorun

Negatif olmayan tam sayılardan oluşan bir 3'e 3 kareyi düşünün. Her satır iiçin tamsayıların toplamı olarak ayarlanır r_i. Her sütun jiçin benzer şekilde , bu sütundaki tamsayıların toplamı olarak ayarlanır c_j.

Görev, satır ve sütun toplamı kısıtlamaları göz önüne alındığında ızgaraya olası tüm tamsayı atamalarını numaralandırmak için kod yazmaktır. Kodunuz bir kerede bir ödev vermelidir.

Giriş

Kodunuz, satır kısıtlamalarını belirten negatif olmayan 3 tamsayı ve sütun kısıtlamalarını belirten negatif olmayan 3 tamsayı almalıdır. Bunların geçerli olduğunu, yani toplam veya satır kısıtlamalarının sütun sınırlamalarının toplamına eşit olduğunu varsayabilirsiniz. Kodunuz bunu uygun olan herhangi bir şekilde yapabilir.

Çıktı

Kodunuz, hesapladığı farklı 2d ızgaraları, seçtiğiniz herhangi bir insan tarafından okunabilir biçimde çıkarmalıdır. Tabii ki daha güzel. Çıktıda yinelenen ızgaralar bulunmamalıdır.

Misal

Tüm satır ve sütun kısıtlamaları aynıysa 1, sadece 6farklı olasılıklar vardır. İlk satır 1için ilk üç sütunun herhangi birine bir koyabilirsiniz , ikinci satır için şimdi 2alternatifler vardır ve son satır şimdi önceki iki tarafından tamamen belirlenir. Izgaradaki diğer her şey olarak ayarlanmalıdır 0.

Girdinin 2 1 0satırlar ve 1 1 1sütunlar için olduğunu varsayalım. APL'nin güzel çıktı formatını kullanarak, olası tamsayı ızgaraları şunlardır:

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

Şimdi girdinin 1 2 3satırlar ve 3 2 1sütunlar için olduğunu varsayalım. Olası tamsayı ızgaraları:

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

Yanıtlar:


9

APL (Dyalog) , 42 bayt

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

Çevrimiçi deneyin!

Kullanımları ⎕IO←0Birçok sistemde varsayılan olanı . Üstbilgideki diğer şeyler matrisler için güzel baskıdır (kutulu ekran).

Girdi altı değerin listesidir, önce satır toplamları, sonra sütun toplamları.

Nasıl?

o←⍳1+⌈/⍵- oaralığı girişin 0maksimum ( ⌈/) değerine getirir

,o∘.,⊢- ile kartezyen ürün ove düzleştir ( ,)

⍣8 - sekiz kez tekrarlandı

3 3∘⍴¨ - 9 maddelik listelerin her birini 3 × 3 matriste şekillendirin

¨o←- bu matrisleri ove her biri için

+/,+⌿- satırların sums ( +/) öğesinin sütun sums ( +⌿) ile birleştirilip birleştirilmediğini kontrol edin

⍵≡ - girişe karşılık gelir

o/⍨- odoğruluk değerlerine göre filtreleme (matrisler dizisi)


Bu çok hoş görünen cevabın bir açıklamaya ihtiyacı var (lütfen).

@Lembik, açıklama ekledi
Uriel

Teşekkürler. Böylece tüm olası matrisleri numaralandırır ve göründüğü kısıtlamalara uyanları kontrol edersiniz. En verimli değil, ama işe yarıyor.

1
@Lembik yup, bu en kısa. Toplamlarla eşleşebilen tüm 3 öğe listelerini alarak biraz daha verimli bir tane yönetebilir, ardından ilk satır toplamına uyanları seçebilir, ardından ilk sütun toplamıyla eşleşenleri (önceki kombinasyonların her biri için) seçebilirim, ve benzeri ileri geri. Bu kaba-kuvvet-olmayan genel algoritma olurdu.
Uriel

@EriktheOutgolfer teşekkürler, bayt sayımı her zaman güncellemeyi unuturum
Uriel

7

Kabuk , 20 17 bayt

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

@ H.PWiz sayesinde -3 bayt

xsKısıtlamaları kodlayan bir liste olarak girdi alır [r_1,r_2,r_3,c_1,c_2,c_3], çevrimiçi deneyin!

açıklama

Kaba kuvvet yaklaşımı: P 3x3 ızgaralarının tümünü girişlerle oluşturun [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 bayt

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

Çevrimiçi deneyin!

UYARI: Çirkin ÇIKTI!Korkma, hala insan tarafından okunabilir, ne kadarını açıklamam gerekmiyor. ;)

Herhangi bir nedenle mantıklı olmasını beklediğimden çok daha uzun olmalı (13 bayt):

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

Bu ikinci sürüm, eğer işe yararsa, çıktıdan girdi (yani komut satırı argümanı) alırdı.


@Riker OP'nin "Çıktı" bölümünü okuyun. Tabii, hala ızgaraları ayıran parantezleri var, onları da çıkarabilirdi ve çıktı hala veri kaybetmezdi ...
Erik Outgolfer

4

Python 2 , 149 145 142 141 138 136 bayt

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*

Çevrimiçi deneyin!

Girişi liste listesi olarak alır: [[r1, c1], [r2, c2], [r3, c3]]


4

Haskell, 94 88 84 79 bayt

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

Satır ve sütunların toplamlarını tek bir düz 6 elemanlı liste olarak alır [r1,r2,r3,c1,c2,c3] .

Çevrimiçi deneyin!

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

Test edilecek matrislerin elemanları toplamına yükseldikçe r, kod büyük satır / sütun toplamları için makul sürede bitmez. İşte maksimum rhıza ulaşan ancak 4 bayt daha uzun bir sürüm : Çevrimiçi deneyin!


3

Mathematica, 81 bayt

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

3x3 matrisini 0..Max elemanlarıyla bulur ve doğru olanları seçer,
bu (Max+1)^9matrislerin kontrol edilmesi gerektiği anlamına gelir

Çevrimiçi deneyin!


Lütfen bir açıklama ekleyebilir misiniz?

3
@Lembik, bazı test senaryoları ekledikten ve bu meydan okumayı buradaki tüm insanlar için "açık" hale getirdikten sonra tekrar açacağım, ancak yardıma ihtiyacı olan herkes için bunu daha iyi hale getirmeye
çalışmıyorsunuz

Şimdi soruya eklendi.

Hala belirsiz olan nedir? / Gridkullanarak TIO ile çalışın ToString. Çevrimiçi deneyin!
user202729

@ user202729 bana bir şey yok, ama test
senaryoları

3

R , 115110 bayt

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)

Çevrimiçi deneyin!

Girdiyi şu şekilde alır c(r1,r2,r3,c1,c2,c3) tek olarak alırvector olarak alır ve matrisleri stdout'a yazdırır.

Uriel'in APL cevabına oldukça benziyor , ancak 3x3 ızgaraları biraz farklı üretiyor.

Letting M=max(S), vektörü oluşturur 0:M, sonra rep9 kez, yani [0..M, 0...M, ..., 0...M]dokuz kez yiyor . Daha sonra, matrix, 3, 3her bir 9 kombinasyonunu bir 3x3matrise dönüştürmek ve simplify=Fbir dizi yerine bir liste döndürmeye zorlamak için , bir kerede 9 alınan yeni vektörün tüm kombinasyonlarını seçer . Daha sonra bu listeyi siler ve olarak kaydeder m.

Ardından m, satır / sütun toplamlarının girdiyle özdeş olduğu filtreleri filtreler , olmayanları yazdırır ve olmayanlar için hiçbir şey yapmaz.

choose(9*(M+1),9)Farklı olası ızgaraları hesapladığından ((M+1)^9 olasılıklardan ) , aşağıdaki daha verimli (ancak daha az golf) cevaptan daha hızlı bellek / zaman tükenir:

R , 159 bayt

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

Çevrimiçi deneyin!


R çok açığız!

3

MATL , 35 22 bayt

Luis Mendo sayesinde -13 bayt

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

Çevrimiçi deneyin!

Bağlantı, kodun biraz daha güzel yazdırılan bir versiyonudur; bu sürüm tüm matrisleri aralarında tek bir satırsonu ile yazdıracaktır.

Girdiyi şu şekilde alır [c1 c2 c3 r1 r2 r3] .

Açıkçası, bu kartezyen gücü hesaplar X^arasında 0...max(input)üs ile 9ve aktaran !. Daha sonra ", her biri @3x3'lük bir matris olarak yeniden şekillendirerek 3e, çoğaltarak t, transpoze !ederek ve yatay olarak birleştirerek sütunların üzerinden döner h. Daha sonra s, vektörle sonuçlanacak olan sütun toplamlarını hesaplar [c1 c2 c3 r1 r2 r3]. Girdi için öğe olarak eşitlik yaparız G=ve ?hepsi sıfır değilse , işleve girdiyi !kullanarak doğru matrisi kurtarırız 4M.


2

Toplu, 367 bayt

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

Sol üst 2 × 2 kare sonucu zorlar, bu nedenle en iyi yaklaşım sol üst tamsayı için tüm değerleri, sol üst ve üst orta tamsayı toplamı için geçerli tüm değerleri, üst toplamı için tüm geçerli değerleri oluşturmaktır sol ve orta sol tamsayı ve orta tamsayı için geçerli değerlerin aralığını hesaplayın, ardından tüm uygun aralıklar arasında döngü yaparak, kısıtlamalardan kalan değerleri hesaplayın.


1

Python 2 , 118 bayt

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)

Çevrimiçi deneyin!


Python 2 , 123 bayt

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.