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.