制約付きで可能なすべての整数のグリッドを列挙する


17

問題

非負整数の3 x 3の正方形グリッドを考えてください。各行iの整数の合計はに設定されますr_i。同様に、各列jの整数の合計はに設定されますc_j

タスクは、行と列の合計の制約が与えられた場合の、グリッドへの可能なすべての整数の割り当てを列挙するコードを記述することです。コードは一度に1つの割り当てを出力する必要があります。

入力

コードは、行制約を指定する3つの非負整数と、列制約を指定する3つの非負整数を取る必要があります。これらは有効であると仮定できます。つまり、合計または行の制約が列の制約の合計に等しいと仮定できます。コードはこれを便利な方法で実行できます。

出力

コードは、計算したさまざまな2Dグリッドを、人間が読める形式で選択して出力する必要があります。もちろん、きれいなほうがいい。出力に重複したグリッドを含めることはできません。

すべての行と列の制約が正確で1ある場合、6異なる可能性のみがあります。最初の行について1は、最初の3つの列のいずれかに入力できます。2番目の行については2選択肢があり、最後の行は前の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多くのシステムでデフォルトである使用。ヘッダーのその他のものは、マトリックスのきれいな印刷です(ボックス表示)。

入力は6つの値のリストで、最初に行が合計され、次に列が合計されます。

どうやって?

o←⍳1+⌈/⍵- 入力の最大()までoの範囲0を取得し⌈/ます

,o∘.,⊢-デカルト積oと平坦化(,

⍣8 -8回繰り返された

3 3∘⍴¨ -すべての9項目リストを3×3マトリックスに整形する

¨o←-これらの行列をoに保存し、それぞれについて

+/,+⌿-行の合計(もしチェック+/列合計に連結)( +⌿

⍵≡ -入力に対応

o/⍨- o真理値によるフィルター(行列配列)


この非常に見栄えの良い答えには説明が必要です(お願い)。

@Lembikは説明追加
ウリエル

ありがとう。したがって、考えられるすべての行列を列挙し、考えられる制約に適合する行列をチェックします。最も効率的ではありませんが、機能します。

1
@Lembikうん、それは最短です。合計に一致するすべての3項目リストを取得し、最初の行の合計に適合するものを選択してから、最初の列の合計に一致するもの(以前の各組み合わせ)を選択することで、もう少し効率的なものを管理できます。等々。それは非総当たり攻撃の一般的なアルゴリズムです。
ウリエル

@EriktheOutgolferのおかげで、私はいつも私のバイト数に更新することを忘れて
ウリエル

7

20 17バイト

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

@ H.PWizのおかげで-3バイト

入力を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

Brachylog、17バイト

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

オンラインでお試しください!

警告:い出力!だまされないでください、それはまだ人間が読むことができます、私はいくらを説明する必要はありません。;)

何らかの理由で、私が理にかなっていると思っているよりもはるかに長くなければなりません(13バイト):

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

この後者のバージョンは、機能する場合は、代わりに出力(つまり、コマンドライン引数)から入力を取得します。


@Riker OPの「出力」セクションを読んでください。確かに、それはまだグリッドを分離するブラケットを持って、それは同様に、それらを取り除いていたかもしれないと出力は、まだすべてのデータを失っていないでしょう...
エリック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

Mathematica、81バイト

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

0..Maxの要素を持つすべての3x3行列を見つけて、正しい行列を選択します。
これは、(Max+1)^9行列をチェックする必要があることを意味します

オンラインでお試しください!


説明を追加してください。

3
@Lembikいくつかのテストケースを追加し、この課題をすべての人に「明確」にした後、再開することに投票しましたが、助けを必要とするすべての人にこれを改善しようとは思わない
J42161217

質問に追加されました。

まだ不明な点は何ですか?/ Gridも使用してTIOで動作しToStringます。オンラインでお試しください!
user202729

@ user202729の私には何もが、テストケースが欠落していた
J42161217

3

R115 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、行列を標準出力に出力します。

UrielのAPLの回答と非常によく似ていますが、3x3グリッドの生成方法が多少異なります。

まかせM=max(S)、それはベクトルを生成し0:M、その後、repすなわち、それを9回食べる[0..M, 0...M, ..., 0...M]9回。次に、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

MATL35 22バイト

ルイスメンドーのおかげで-13バイト

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

オンラインでお試しください!

リンクは、もう少しうまく印刷できるコードのバージョンへのリンクです。このバージョンでは、すべての行列が1つの改行で区切られて印刷されます。

入力をとして受け取ります[c1 c2 c3 r1 r2 r3]

明らかに、これはexponent とtransposingのデカルト力X^を計算します。次に、列をループし、それぞれを3x3行列として再形成し、複製し、転置します0...max(input)9!"@3et!、および水平に連結します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の正方形は結果を強制するため、最良のアプローチは、左上の整数のすべての値、左上の整数と上の中央の整数の合計のすべての有効な値、および上の合計のすべての有効な値を生成することです左と中央の左の整数、および中央の整数の有効な値の範囲を計算し、すべての適切な範囲をループして、制約から残りの値を計算します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.