Kare bir ızgarayı eşit alandaki bölümlere ayırın


17

Bu meydan okuma aşağıdaki bulmaca dayanmaktadır: Bir verilir ntarafından ngrid nişaretli hücrelerin. İşiniz, ızgarayı, nher bölümün tam nolarak bir işaretli hücre içerdiği , tam olarak hücrelerden oluştuğu bölümlere ayırmaktır .

Misal

İşte solda bir bulmaca ve sağda (benzersiz) çözümü:

bulmaca çözüm

Meydan okuma

nHerhangi bir makul biçimde bir dizi sıfır indeksli koordinat verilecektir .

[(0,0), (0,3), (1,0), (1,1), (2,2)]

Ve işiniz, geçerli herhangi bir bölümü (yine makul bir biçimde) döndüren bir program yazmaktır.

[
  [(0,0), (0,1), (0,2), (1,2), (1,3)],
  [(0,3), (0,4), (1,4), (2,4), (3,4)],
  [(1,0), (2,0), (3,0), (4,0), (4,1)],
  [(1,1), (2,1), (3,1), (3,2), (4,2)],
  [(2,2), (2,3), (3,3), (4,3), (4,4)]
]

Bulmacanın çözümü yoksa, program bir hata atarak veya boş bir çözüm döndürerek bunu belirtmelidir.

Giriş / Çıkış Örnekleri

[(0,0)]               => [[(0,0)]]

[(0,0), (1,1)]        => [
                          [(0,0), (1,0)], 
                          [(0,1), (1,1)]
                         ]

[(0,0), (0,1), (1,0)] => [] (no solution)

[(0,0), (0,1), (0,2)] => [
                          [(0,0), (1,0), (2,0)], 
                          [(0,1), (1,1), (2,1)],
                          [(0,2), (1,2), (2,2)],
                         ]

[(0,0), (0,2), (1,2)] => [
                          [(0,0), (1,0), (2,0)], 
                          [(0,1), (0,2), (1,1)],
                          [(1,2), (2,1), (2,2)],
                         ]

puanlama

Bu , bu yüzden en kısa kod kazanır.



@Arnauld, Shikaku bulmacalarına benziyor, "amaç ızgarayı dikdörtgen ve kare parçalara bölmektir". Bu durumda, böyle bir kısıtlama yoktur.
— Peter Kagey

Karışıklık için özür dilerim. Sanırım kum havuzunun herhangi bir yerinde bir Shikaku zorluğu olabilir, ya da belki bir noktada kendim bir tane yapmayı planlıyordum - kesin olarak hatırlayamıyorum. Her iki durumda da, ilk bakışta aynı şey olduğunu düşündüm.
— Arnauld

Sonuç neden 2d koordinat dizisidir? Orada ne ifade ediliyor anlamıyorum ... dizi dizinin 2d dizi olamaz mı? Örneğin, satır 3, sütun 2, dizin 4?
— Olivier Grégoire

Her bir alanın örnekte belirtildiği gibi referans koordinatlarından başlayarak çizilebileceğini varsayabilir miyiz? Az önce bunu bilinçsiz olarak bunu kabul ettiğimi fark ettim.
— Arnauld

Yanıtlar:


11

JavaScript (ES7), 166 bayt

Bölümü tanımlayan bir tamsayılar matrisi çıkarır veya fbirlse çözüm yoksa.

a=>(m=a.map(_=>[...a]),g=(n,X,Y,j=0,i)=>a[n]?a[j]?m.some((r,y)=>r.some((v,x)=>++v|(X-x)**2+(Y-y)**2-1?0:g(r[x]=n,x,y,j+1,i|x+[,y]==a[n])?1:r[x]=v)):i&&g(n+1):1)(0)&&m

Çevrimiçi deneyin!

Nasıl?

İlk önce bir kare matris oluşturuyoruz m büyüklüğünde N-xN-, nerede N- girişin uzunluğu:

m = a.map(_ => [...a])

Her satır m girdinin bir kopyasından oluşur; N-koordinat çiftleri. Buradaki önemli nokta, tüm hücrelerinmsayısal olmayan değerlere sıfırlanır. Önek artış operatörünü uygulayarak bunları tespit edebileceğiz ++.

Özyinelemeli işlev g bir işaretçi alır n girdiye, koordinatlar (X,Y) önceki hücrenin, bir sayaç j geçerli alandaki doldurulmuş hücre sayısını ve bir bayrağı tutar ben işaretli hücre alanda bulunduğunda ayarlanır:

g = (n, X, Y, j = 0, i) => a[n] ? a[j] ? ... : i && g(n + 1) : 1

Test ediyoruz bir[n] tüm alanların işlenip işlenmediğini bilmek ve test etmek bir[j] mevcut alana yeterli hücrenin doldurulup doldurulmadığını bilmek.

Ana kısmı g sonraki hücresini arar m hepsini yineleyerek doldurmak için:

m.some((r, y) =>          // for each row r[] at position y in m[]:
  r.some((v, x) =>        //   for each cell of value v at position x in r[]:
    ++v |                 //     if this cell is already filled (i.e. v is numeric)
    (X - x) ** 2 +        //     or the squared Euclidean distance between
    (Y - y) ** 2 -        //     (X, Y) and (x, y)
    1 ?                   //     is not equal to 1:
      0                   //       this is an invalid target square: do nothing
    :                     //     else:
      g(                  //       do a recursive call to g:
        r[x] = n,         //         pass n unchanged and fill the cell with n
        x, y,             //         pass the coordinates of the current cell
        j + 1,            //         increment j
        i |               //         update i:
        x + [,y] == a[n]  //         set it if (x, y) = a[n]
      ) ?                 //       if the result of the call is truthy:
        1                 //         return 1
      :                   //       else:
        r[x] = v          //         reset the cell to NaN
  )                       //   end of inner map()
)                         // end of outer map()
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.