Bir Dikdörtgen İçinde Eşsiz Tuğla Eğimler


14

Stackoverflow'a göz atıyordum ve bir MxN dikdörtgeni döşemekle ilgili bu soruyu gördüm ve golf için harika olacağını düşündüm. İşte görev.

M ve N boyutu göz önüne alındığında, bu kısıtlamalar göz önüne alındığında, bir MxN dikdörtgeni (N sütun sayısı değil, satır sayısıdır. Gerçekten önemli değil) kaç benzersiz yolla sonuçlanan bir program yazın.

  1. Tüm karolar 2x1 veya 3x1
  2. Tüm karolar sıralarında kalır (yani hepsi yataydır)
  3. Her iki bitişik satır arasında, iki uç hariç, karolar hizalanmamalıdır
  4. M ve N'nin en az 1 olması garanti edilmektedir.

Örneğin, 8x3'lük bir matrisin geçerli bir döşemesi

  2    3     3
  |    |     |
  v    v     v
 _______________
|___|_____|_____| 
|_____|_____|___|
|___|_____|_____|

Ancak satırlar hizalandığı için aşağıdakiler geçersiz olur

  2    3     3
  |    |     |
  v    v     v
 _______________
|___|_____|_____| 
|_____|___|_____|
|_____|_____|___|

Test senaryoları:

8x3: 4

3x1: 1

1x1: 0

9x4: 10

Kod golf, çok kısa cevap kazanır.


2
Fayansların boyutuyla ilgili açıklamanız, dikdörtgenin boyutundan farklı bir kural kullanıyor gibi görünüyor. Fayanslar gerçekten mi 2x1yoksa 3x1? Ayrıca çıktı 4x1sıfır mı?
FryAmTheEggman

1
Hoşgeldiniz. Güzel meydan okuma kavramı, ancak meydan okuma fikirlerini anaya göndermeden önce çekiçlemek için genellikle kum havuzunu kullanmak en iyisidir .
Beefster

OP çalıştı gibi görünüyor @FryAmTheEggman |gibi gösterimi kullanılarak, s üst üste uzunluğuna katkıda bu (bir boru (var değilse, |), bir boşluk vardır).
Outgolfer Erik


1
SO üzerinde atıfta bulunulan soru artık değil.
Arnauld

Yanıtlar:


5

Jöle , 20 bayt

2*ḃ€2‘ÄṪ⁼¥Ƈ⁸ṗfƝẸ$€ċ0

Çevrimiçi deneyin!


Hızın spesifikasyonun bir parçası olmadığını biliyorum, ama bu tio'da çalışırken 11x10'da zaman aşımına uğradı. Nedenini anlamak için bir açıklama ile ilgilenirim.
Nick Kennedy

@NickKennedy Bu çok büyük bir girdi. Genişlik 11 için, her sıra 9 farklı eğimden birine sahip olabilir. Genişlik 11 ve yükseklik 10 için, geçersiz olanlar dahil 9¹⁰ = 3486784401 olası duvarlar vardır. Kartezyen güç böyle çalışır. Açıkçası, TIO, çözümümün tüm duvar dizisini hesaplamasına izin verecek zamana sahip değil (60 saniye sonra zaman aşımına uğradı). Zamanı bulduğumda bir açıklama ekleyeceğim.
Outgolfer Erik

Teşekkürler. Jöleye biraz baktım, ama şu anda insanların kodlarının ne yaptığını anlamak için açıklamalara güveniyorum. Ben kod kaba kaba çözüm gereksinimlerini en aza indirmenin mantıklı bir yol olan çözümü zorladı zaman sorunu göz önüne alındığında.
Nick Kennedy

Faiz dışında Jelly kodunu ilk kodunu kullanarak R kodumu yöntemi yeniden. Hiç de oluyor çevrimiçi deneyin! ve sizinkinden çok daha uzun olsa da, daha büyük sayıları işler. Şu anda 1 satırı düzgün işlemediğini unutmayın. Çok daha özlü olabileceğinden şüpheleniyorum, ama Jelly'de yeniyim.
Nick Kennedy

4

JavaScript (ES6), 119110106  96  91 bayt

Girişi .(N,M)

f=(n,m,p=0,g=(w,h=x=>g(p[g[w-=x]=1,w]||w)*g[w]--)=>w>3?h(2)+h(1):w>1&&f(n,m-1,g))=>m?g(n):1

Çevrimiçi deneyin!

Yorumlananlar

Not: Bu kod, birbirini çağıran 3 farklı işlev kullanır. Bu, değişkenlerin kapsamını takip etmeyi biraz zorlaştırır. Göz önünde bulundurun kapsamında tanımlandığı ve kapsamında tanımlanmıştır .gfhg

f = (                    // f is a recursive function taking:
  n,                     //   n = number of columns
  m,                     //   m = number of rows
  p = 0,                 //   p = object holding the previous row
  g = (                  //   g = recursive function taking:
    w,                   //     w = remaining width that needs to be filled in the
                         //         current row
    h = x =>             //     h = helper function taking x
                         // h body:
      g(                 //   recursive call to g:
        p[g[w -= x] = 1, //     subtract either 2 or 1 from w and mark this width as used
          w              //     test p[w]
        ]                //     pass p[w] if p[w] = 1 (which will force the next iteration
                         //     to fail immediately)
        || w             //     otherwise, pass w
      )                  //   end of recursive call
      * g[w]--           //   then restore g[w] to 0
  ) =>                   // g body:
    w > 3 ?              //   if w > 3, we need to insert at least 2 more bricks:
      h(2) + h(1)        //     invoke h with x = 2 and x = 1
    :                    //   else:
      w > 1              //     this is the last brick; we just check if it can be inserted
      &&                 //     abort if w is equal to 1 (a brick does not fit in there)
      f(                 //     otherwise, do a recursive call to f:
        n,               //       n is unchanged
        m - 1,           //       decrement m
        g                //       pass g as the new reference row
      )                  //     end of recursive call
) =>                     // f body:
  m ? g(n) : 1           //   yield 1 if we made it to the last row or call g otherwise

1

R , 243231 bayt

function(m,n,i=2*0:(m%/%6)+m%%2,j=i+(m-3*i)/2,M=Map)`if`(m<2,0,sum((e=eigen(lengths(outer(p<-unlist(M(M,list(function(x,y)cumsum(2+1:y%in%x)),M(combn,j,i,s=F),j),F),p,Vectorize(intersect)))<2))$ve%*%diag(e$va^(n-1))%*%solve(e$ve)))

Çevrimiçi deneyin!

Satır sonlu sürüm:

function(m,n,i=2*0:(m%/%6)+m%%2,j=i+(m-3*i)/2,M=Map)`if`(m<2,0,
sum((e=eigen(lengths(outer(p<-unlist(M(M,list(function(x,y)cumsum(2+1:y%in%x)),
M(combn,j,i,s=F),j),F),p,Vectorize(intersect)))<2))$ve%*%diag(e$va^(n-1))%*%solve(e$ve)))

Özyineleme olmadığına dikkat edin ve oldukça büyük m ve n değerlerini işler (örneğin 24x20 -> 3.3e19)

İşte yukarıdakilerle hemen hemen aynı şekilde çalışan yorumlanmış bir cevap, ancak aslında tüm fonksiyonları unnested ettim, bu yüzden gerçekten okunabilir:

f <- function(m,n) {
  # First work out what potential combinations of 2s and 3s add up to m
  i <- 2*0:(m %/% 6) + m %% 2 # Vector with numbers of possible 3s
  j <- i + (m - 3 * i) / 2 # Vector with total number of 2s and 3s
  if (m < 2) {
    0 # If wall less than 2 wide, no point in continuing because answer is 0
  } else {
    # Work out all possible positions of threes for each set
    positions_of_threes <- Map(combn, j, i, simplify = FALSE)
    # Function to work out the cumulative distance along the wall for a given
    # Set of three positions and number of bricks
    make_cumulative_bricks <- function(pos_threes, n_bricks) {
      bricks <- 1:n_bricks %in% pos_threes
      cumsum(2 + bricks)
    }
    # Find all possible rows with cumulative width of wall
    # Note because this is a `Map` with depth two that needs to be vectorised
    # for both `positions_of_threes` and `j`, and we're using base R, the
    # function `make_cumulative_bricks` needs to be placed in a list
    cum_bricks <- Map(Map, list(make_cumulative_bricks), positions_of_threes, j)
    # Finally we have the list of possible rows of bricks as a flat list
    cum_bricks_unlisted <- unlist(cum_bricks, recursive = FALSE)
    # Vectorise the intersect function
    intersect_v <- Vectorize(intersect, SIMPLIFY = FALSE)
    # Find the length of all possible intersects between rows
    intersections <- outer(cum_bricks_unlisted, cum_bricks_unlisted, intersect_v)
    n_intersections <- lengths(intersections)
    # The ones not lined up will only have a single intersect at `m`
    not_lined_up <- n_intersections == 1
    # Now use method described at /programming//a/9459540/4998761
    # to calculate the (matrix of TRUE/FALSE for lined-up) to the power of `n`
    eigen_nlu <- eigen(not_lined_up)
    final_mat <- eigen_nlu$vectors %*%
      diag(eigen_nlu$values ^ (n - 1)) %*%
      solve(eigen_nlu$vectors)
    # The sum of this matrix is what we're looking for
    sum(final_mat)
  }
}
f(20,20)

Bir matris alma ve tekrar tekrar kendi başına çoğaltma yöntemi, yığın akışı ile ilgili bir sorudur . Bu yaklaşım burada işe yarar çünkü farklı olası tuğla sıraları boyunca kümülatif dal sayısını etkili bir şekilde hesaplar.

Harici paketlere izin verilirse, 192'ye indirebilirim:

function(m,n,i=2*0:(m%/%6)+m%%2,j=i+(m-3*i)/2,M=purrr::map2)`if`(m<2,0,sum(expm::`%^%`(lengths(outer(p<-unlist(M(M(j,i,combn,s=F),j,M,~cumsum(2+1:.y%in%.)),F),p,Vectorize(intersect)))<2,n-1)))

1

Jöle , 26 bayt

2*ḃ€2‘ÄṪ⁼¥Ƈ⁸œ&L¬ɗþ`æ*⁴’¤SS

Çevrimiçi deneyin!

Bozuldu:

Olası duvarların bir listesini, sonu kaldırılmış olarak toplamlar olarak oluşturun:

2*ḃ€2‘ÄṪ⁼¥Ƈ⁸

Herhangi bir kesişme noktası olmayan tüm olası duvarların dış tablosunu bulun:

œ&L¬ɗþ`

Bu matrisi (N-1) 'in gücüne götürün ve sonra hepsini toplayın:

æ*⁴’¤SS

Olası duvarların listesini oluşturmak için @ EriktheOutgolfer'ın cevabındaki ilk biti kullanır ve sonra R cevabımdaki matris kavşak ve matris üs alma yaklaşımını kullanır. Bu nedenle, büyük N ile bile iyi çalışır. Bu benim ilk Jelly cevabım ve daha fazla golf oynayabileceğinden şüpheleniyorum. Ayrıca ilk bölümü değiştirmek istiyorum, böylece zaman ve bellek gereksinimleri M ile katlanarak ölçeklenmiyor.


0

05AB1E , 42 bayt

Åœʒ23yåP}€œ€`Ùε.¥¦¨}IиI.ÆÙεøyíø‚€€üQOO_P}O

Bunu göndermek için neredeyse çok utanıyorum ve kesinlikle farklı bir yaklaşımla AOT tarafından golf edilebilir, ancak tamamlanması biraz zaman aldığı için yine de göndermeye ve buradan golf oynamaya karar verdim. Zorluk imo'dan daha kolay görünüyor, ama kesinlikle burada yanlış bir yaklaşım kullanıyorum ve 05AB1E'nin yaklaşık 25 bayt yapabileceği hissine sahibim.

Çevrimiçi deneyin. NOT: 9x4Test durumu TIO'da yaklaşık 40 saniye içinde çalıştığı için sadece uzun değil, aynı zamanda verimsizdir .

Açıklama:

Ŝ             # Get all possible ways to sum to the (first) implicit input
               #  i.e. 8 → [[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,2],[1,1,1,1,1,3],[1,1,1,1,2,2],[1,1,1,1,4],[1,1,1,2,3],[1,1,1,5],[1,1,2,2,2],[1,1,2,4],[1,1,3,3],[1,1,6],[1,2,2,3],[1,2,5],[1,3,4],[1,7],[2,2,2,2],[2,2,4],[2,3,3],[2,6],[3,5],[4,4],[8]]
  ʒ23yåP}      # Only leave those consisting of 2s and/or 3s
               #  → [[2,2,2,2],[2,3,3]]
         €œ    # For each: get all permutations
           €`  # Flatten this list of lists once
             Ù # And uniquify it (leaving all possible distinct rows of bricks)
               #  → [[2,2,2,2],[3,3,2],[3,2,3],[2,3,3]]
ε    }         # For each:
             #  Get the cumulative sum
   ¦¨          #  With the leading 0 and trailing first input removed
               #   → [[2,4,6],[3,6],[3,5],[2,5]]
      Iи       # Repeat this list the second input amount of times
               #  i.e. 3 → [[2,4,6],[3,6],[3,5],[2,5],[2,4,6],[3,6],[3,5],[2,5],[2,4,6],[3,6],[3,5],[2,5]]
        I    # Get all combinations of lists the size of the second input
           Ù   # And uniquify the result (leaving all possible distinct walls)
               #  → [[[2,4,6],[3,6],[3,5]],[[2,4,6],[3,6],[2,5]],[[2,4,6],[3,6],[2,4,6]],[[2,4,6],[3,6],[3,6]],[[2,4,6],[3,5],[2,5]],[[2,4,6],[3,5],[2,4,6]],[[2,4,6],[3,5],[3,6]],[[2,4,6],[3,5],[3,5]],[[2,4,6],[2,5],[2,4,6]],[[2,4,6],[2,5],[3,6]],[[2,4,6],[2,5],[3,5]],[[2,4,6],[2,5],[2,5]],[[2,4,6],[2,4,6],[3,6]],[[2,4,6],[2,4,6],[3,5]],[[2,4,6],[2,4,6],[2,5]],[[2,4,6],[2,4,6],[2,4,6]],[[3,6],[3,5],[2,5]],[[3,6],[3,5],[2,4,6]],[[3,6],[3,5],[3,6]],[[3,6],[3,5],[3,5]],[[3,6],[2,5],[2,4,6]],[[3,6],[2,5],[3,6]],[[3,6],[2,5],[3,5]],[[3,6],[2,5],[2,5]],[[3,6],[2,4,6],[3,6]],[[3,6],[2,4,6],[3,5]],[[3,6],[2,4,6],[2,5]],[[3,6],[2,4,6],[2,4,6]],[[3,6],[3,6],[3,5]],[[3,6],[3,6],[2,5]],[[3,6],[3,6],[2,4,6]],[[3,6],[3,6],[3,6]],[[3,5],[2,5],[2,4,6]],[[3,5],[2,5],[3,6]],[[3,5],[2,5],[3,5]],[[3,5],[2,5],[2,5]],[[3,5],[2,4,6],[3,6]],[[3,5],[2,4,6],[3,5]],[[3,5],[2,4,6],[2,5]],[[3,5],[2,4,6],[2,4,6]],[[3,5],[3,6],[3,5]],[[3,5],[3,6],[2,5]],[[3,5],[3,6],[2,4,6]],[[3,5],[3,6],[3,6]],[[3,5],[3,5],[2,5]],[[3,5],[3,5],[2,4,6]],[[3,5],[3,5],[3,6]],[[3,5],[3,5],[3,5]],[[2,5],[2,4,6],[3,6]],[[2,5],[2,4,6],[3,5]],[[2,5],[2,4,6],[2,5]],[[2,5],[2,4,6],[2,4,6]],[[2,5],[3,6],[3,5]],[[2,5],[3,6],[2,5]],[[2,5],[3,6],[2,4,6]],[[2,5],[3,6],[3,6]],[[2,5],[3,5],[2,5]],[[2,5],[3,5],[2,4,6]],[[2,5],[3,5],[3,6]],[[2,5],[3,5],[3,5]],[[2,5],[2,5],[2,4,6]],[[2,5],[2,5],[3,6]],[[2,5],[2,5],[3,5]],[[2,5],[2,5],[2,5]]]
ε              # Map all walls `y` to:
 ø             #  Zip/transpose; swapping rows and columns
 yí            #  Reverse each row in a wall `y`
   ø           #  Also zip/transpose those; swapping rows and columns
              #  Pair both
              #  For both:
              #   For each column:
    ü          #    For each pair of bricks in a column:
     Q         #     Check if they are equal to each other (1 if truthy; 0 if falsey)
    O          #    Then take the sum of these checked pairs for each column
   O           #   Take the sum of that entire column
   _           #   Then check which sums are exactly 0 (1 if 0; 0 if anything else)
   P           #   And check for which walls this is only truthy by taking the product
}O             # After the map: sum the resulting list
               # (and output it implicitly as result)

0

Kömür , 89 bayt

Nθ⊞υ⟦⟧≔⟦⟧ηFυF⟦²¦³⟧«≧⁺∧Lι§ι⁰κ¿⁼κθ⊞ηι¿‹κθ⊞υ⁺⟦κ⟧ι»≔Eη⟦ι⟧ζF⊖N«≔ζι≔⟦⟧ζFιFη¿¬⊙§κ⁰№λμ⊞ζ⁺⟦λ⟧κ»ILζ

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. TIO'da yaklaşık 12 boyuta kadar dikdörtgenler için çalışır, ancak liste kesişimi yerine bit döndürme kullanılarak 2 bayt maliyetle yaklaşık üç kat daha hızlı yapılabilir. Açıklama:

Nθ

Genişliği girin.

⊞υ⟦⟧

Tuğlasız bir satır ile başlayın.

≔⟦⟧η

Tamamlanmış satır olmadan başlayın.

Fυ

Satırların üzerinden geçin.

F⟦²¦³⟧«

Tuğlaların üzerinden geçin.

≧⁺∧Lι§ι⁰κ

Tuğla genişliğini geçerli satır genişliğine ekleyin.

¿⁼κθ⊞ηι

Bu giriş genişliğine yol açarsa, bu satırı tamamlanan satırlar listesine ekleyin.

¿‹κθ⊞υ⁺⟦κ⟧ι»

Aksi takdirde, bu hala giriş genişliğinden daha azsa, yeni satırı satır listesine ekleyin, böylece daha sonraki bir yineleme tarafından alınmasına neden olun.

≔Eη⟦ι⟧ζ

Bir sıradaki duvarların bir listesini yapın.

F⊖N«

Yükseklikten bir daha az döngü.

≔ζι

Duvar listesini kaydedin.

≔⟦⟧ζ

Duvarların listesini temizle.

Fι

Kaydedilmiş duvarlar listesine dönün.

Fη

Tamamlanan satırların üzerinden geçin.

¿¬⊙§κ⁰№λμ⊞ζ⁺⟦λ⟧κ»

Satır bu duvara eklenebilirse, bunu duvar listesine ekleyin.

ILζ

Son duvar listesinin uzunluğunu çıktılar.

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.