ระบุกริดที่เป็นไปได้ทั้งหมดของจำนวนเต็มด้วยข้อ จำกัด


17

ปัญหา

พิจารณาสแควร์ 3 คูณ 3 ตารางของจำนวนเต็มไม่เป็นลบ สำหรับแต่ละแถวผลรวมของจำนวนเต็มจะถูกกำหนดให้เป็นi r_iในทำนองเดียวกันสำหรับแต่ละคอลัมน์ผลรวมของจำนวนเต็มในคอลัมน์นั้นจะถูกกำหนดให้เป็น jc_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และสำหรับแต่ละอัน

+/,+⌿ - ตรวจสอบว่าแถวผลรวม (+/ ) ตัดแบ่งกับผลรวมคอลัมน์ ( +⌿)

⍵≡ - สอดคล้องกับอินพุต

o/⍨- ตัวกรองo(อาร์เรย์เมทริกซ์) ตามค่าความจริง


คำตอบที่ดูดีมากนี้ต้องการคำอธิบาย (โปรด)

@Lembik เพิ่มคำอธิบาย
Uriel

ขอบคุณ ดังนั้นคุณต้องระบุเมทริกซ์ที่เป็นไปได้ทั้งหมดและตรวจสอบค่าที่ตรงกับข้อ จำกัด ที่ดูเหมือน ไม่ได้มีประสิทธิภาพมากที่สุด แต่ใช้งานได้

1
@ Lembik yup นั้นสั้นที่สุด ฉันสามารถจัดการรายการที่มีประสิทธิภาพมากขึ้นเล็กน้อยโดยรับรายการทั้งหมด 3 รายการที่สามารถจับคู่ผลรวมจากนั้นเลือกรายการที่เหมาะกับผลรวมแถวแรกจากนั้นเลือกรายการ (สำหรับชุดค่าผสมก่อนหน้านี้) ที่ตรงกับผลรวมคอลัมน์แรก เป็นต้นไปมา นั่นจะเป็นอัลกอริธึมทั่วไปที่ไม่มีกำลังดุร้าย
ยูเรียล

@EriktheOutgolfer ขอบคุณฉันลืมอัปเดตจำนวนไบต์เสมอ
Uriel

7

Husk , 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

Brachylogขนาด 17 ไบต์

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

ลองออนไลน์!

คำเตือน: เอาท์พุทน่าเกลียด! อย่าเพิ่งตบเบา ๆ มันยังอ่านได้ง่ายฉันไม่จำเป็นต้องคิดมาก ;)

ด้วยเหตุผลบางอย่างมันจะต้องนานกว่าสิ่งที่ฉันคาดหวังให้สมเหตุสมผล (13 ไบต์):

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

รุ่นหลังนี้หากใช้งานได้จะได้รับอินพุตจากเอาต์พุต (เช่นอาร์กิวเมนต์บรรทัดคำสั่ง) แทน


@Riker อ่านส่วน "เอาท์พุท" ของ OP แน่นอนว่ามันยังคงมีวงเล็บแยกกริดมันสามารถถอดออกได้เช่นกันและผลลัพธ์ก็จะไม่สูญหายไปกับข้อมูลใด ๆ ...
Erik the 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&]&

ค้นหาเมทริกซ์ 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และพิมพ์เมทริกซ์เป็น stdout

มันค่อนข้างคล้ายกับคำตอบ APL ของ Urielแต่สร้างกริด 3x3 แตกต่างกันบ้าง

ปล่อยให้M=max(S)มันสร้างเวกเตอร์0:Mแล้วrepกินมัน 9 ครั้งคือ[0..M, 0...M, ..., 0...M]เก้าครั้ง จากนั้นจะเลือกชุดค่าผสมทั้งหมดของเวกเตอร์ใหม่ที่ถ่ายครั้งmatrix, 3, 3ละ 9 โดยใช้เพื่อแปลงชุดค่าผสม 9 ชุดให้เป็น3x3เมทริกซ์simplify=Fให้ส่งคืนรายการแทนที่จะเป็นอาร์เรย์ จากนั้นก็ uniquifies 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 ไบต์ขอบคุณLuis Mendo

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

ลองออนไลน์!

ลิงก์คือโค้ดเวอร์ชันที่พิมพ์ได้ดีกว่าเล็กน้อย รุ่นนี้จะพิมพ์เมทริกซ์ทั้งหมดด้วยการขึ้นบรรทัดใหม่ระหว่างกัน

ใช้อินพุตเป็น [c1 c2 c3 r1 r2 r3]จะเข้าเป็น

แน่นอนนี้คำนวณอำนาจคาร์ทีเซียนX^ของ0...max(input)กับตัวแทน9และ !transposing จากนั้นลูป"มากกว่าคอลัมน์การก่อร่างใหม่แต่ละ@เป็นเมทริกซ์ 3x3 3e, ทำซ้ำt, transposing และแนวนอนเชื่อมโยงพวกเขา! hจากนั้นก็จะคำนวณผลรวมคอลัมน์ซึ่งจะส่งผลในเวกเตอร์s [c1 c2 c3 r1 r2 r3]เราทำเช่นความเสมอภาค elementwise การป้อนข้อมูล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(

ด้านบนซ้าย 2x2 สแควร์บังคับผลดังนั้นวิธีที่ดีที่สุดคือการสร้างค่าทั้งหมดสำหรับจำนวนเต็มซ้ายด้านบนค่าที่ถูกต้องทั้งหมดสำหรับผลรวมของจำนวนเต็มซ้ายและกลางด้านบนค่าที่ถูกต้องทั้งหมดสำหรับผลรวมของด้านบน จำนวนเต็มซ้ายและกลางซ้ายและคำนวณช่วงของค่าที่ถูกต้องสำหรับจำนวนเต็มกลางจากนั้นเมื่อวนลูปผ่านช่วงที่เหมาะสมทั้งหมดให้คำนวณค่าที่เหลือจากข้อ จำกัด


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.