Phân vùng lưới thành hình tam giác


18

Mục tiêu

Mục tiêu của thử thách này là tạo ra một hàm ntính toán số cách phân chia n X 1lưới thành các hình tam giác trong đó tất cả các đỉnh của các hình tam giác đều nằm trên các điểm lưới.

Thí dụ

Ví dụ: có 14 cách để phân vùng lưới 2 x 1, do đó, f(2) = 14thông qua các phân vùng sau Phân vùng 2 x 1 trong đó các phân vùng có 2, 2, 2, 2, 4 và 2 hướng khác nhau tương ứng.

Chấm điểm

Đây là , vì vậy mã ngắn nhất sẽ thắng.


10
Một số trường hợp kiểm tra bổ sung sẽ có lợi, vì vậy chúng tôi có thể xác minh bài nộp của mình là chính xác.
admBorkBork

8
Bạn có thể muốn chỉ định hình tam giác không suy biến .
Arnauld

1
Tôi đã thực hiện các chỉnh sửa cho trình tự OEIS A051708 để phản ánh cách giải thích này.
Peter Kagey

Câu trả lời:


2

05AB1E , 13 byte

·LÉœÙεÅγo;P}O

Cổng câu trả lời Jelly của @Bubbler .

Rất chậm do hoán vị dựng sẵn.

Hãy thử trực tuyến hoặc xác minh bốn đầu vào đầu tiên .

Giải trình:

·                # Double the (implicit) input
 L               # Create a list in the range [1, doubled_input]
  É              # Check for each if they're odd (1 if truthy, 0 is falsey)
                 # We now have a list of n 0s and n 1s (n being the input)
   œ             # Get all permutations of that list
    Ù            # Only leave the unique permutations
     ε     }     # Map each permutation to:
      Åγ         #  Run-length encode the current value (short for `γ€g`)
        o        #  Take 2 to the power for each
         ;       #  Halve each
          P      #  Take the product of the mapped permutation
            O    # Sum all mapped values together (and output implicitly)

19

Haskell , 60 55 54 52 byte

Sau khi vẽ và lập trình rất nhiều ví dụ, tôi nhận ra rằng đây cũng giống như vấn đề của các tân binh:

(n+1)×(n+1)(0,0)(n,n)+(1,0)+(0,1)

1×n

Cảm ơn @PeterTaylor cho -6 byte và @PostLeftGarfHunter cho -2 byte!

b 0=1
b 1=2
b n=div((10*n-6)*b(n-1)-9*(n-2)*b(n-2))n

Hãy thử trực tuyến!


Tôi tìm thấy chuỗi OEIS bằng cách tìm kiếm với một vài giá trị đầu tiên. Giải thích tốt đẹp cho lý do tại sao nó phù hợp. Bạn có muốn chỉnh sửa nó để thêm một nhận xét về giải thích kết hợp thay thế này? Nếu không, tôi có thể.
Peter Taylor

BTW bạn cần điều chỉnh việc lập chỉ mục, bởi vì câu trả lời đúng ở đây là A051708(n+1). Vì vậy, tôi đã đăng câu trả lời đúng đầu tiên :-P
Peter Taylor

Tôi lấy nó, rook di chuyển bản đồ thành hình tam giác bằng cách tạo ra hình tam giác với các cạnh trên và dưới tương ứng với di chuyển lên hoặc phải?
Neil

@PeterTaylor Chết tiệt, cảm ơn vì đã chỉ ra sai lầm của tôi :)
flawr

5
@Neil Tôi đã thêm một lời giải thích đồ họa.
flawr

8

Haskell , 42 byte

0?0=1
a?b=sum[a?i+i?a|i<-[0..b-1]]
f n=n?n

Hãy thử trực tuyến!

Một triển khai khá trực tiếp mà đệ quy trên 2 biến.

Đây là cách chúng ta có thể có được giải pháp này. Bắt đầu với mã thực hiện một công thức đệ quy trực tiếp:

54 byte

0%0=1
a%b=sum$map(a%)[0..b-1]++map(b%)[0..a-1]
f n=n%n

Hãy thử trực tuyến!

Sử dụng giải thích di chuyển tân binh của flawr , a%blà số đường dẫn đưa rook từ đó (a,b)đến (0,0), chỉ sử dụng di chuyển giảm tọa độ. Di chuyển đầu tiên giảm ahoặc giảm b, giữ nguyên khác, do đó công thức đệ quy.

49 byte

a?b=sum$map(a%)[0..b-1]
0%0=1
a%b=a?b+b?a
f n=n%n

Hãy thử trực tuyến!

Chúng ta có thể tránh sự lặp lại map(a%)[0..b-1]++map(b%)[0..a-1]bằng cách lưu ý rằng hai nửa giống nhau abhoán đổi. Cuộc gọi phụ trợ a?bđếm các đường dẫn nơi di chuyển đầu tiên giảm avà do đó, đếm các đường dẫn b?adi chuyển đầu tiên giảm b. Đây là nói chung khác nhau, và họ thêm vào a%b.

Tổng kết trong a?bcũng có thể được viết như một sự hiểu biết danh sách a?b=sum[a%i|i<-[0..b-1]].

42 byte

0?0=1
a?b=sum[a?i+i?a|i<-[0..b-1]]
f n=n?n

Hãy thử trực tuyến!

Cuối cùng, chúng tôi thoát khỏi %và chỉ viết đệ quy ?bằng cách thay thế a%ibằng a?i+i?atrong cuộc gọi đệ quy.

Trường hợp cơ sở mới khiến điều này ?mang lại kết quả gấp đôi so với ?phiên bản 49 byte, kể từ đó 0?0=1, chúng ta sẽ có 0%0=0?0+0?0=2. Điều này cho phép sử dụng xác định f n=n?nmà không cần giảm một nửa mà chúng ta cần phải làm.


Giải pháp 49 byte của bạn sử dụng đệ quy tương tự như câu trả lời của tôi, nhưng tôi vẫn chưa tìm ra giải pháp 42 byte. Một lời giải thích sẽ tốt đẹp.
Peter Taylor

Tôi nghĩ rằng tôi đã sử dụng cùng một cách tiếp cận trong một trong các chương trình trước đây của mình: Ý tưởng đang tạo (hoặc đếm) tất cả các phân vùng bằng cách tạo các đường không nằm ngang từ phải sang trái. Bạn bắt đầu với dòng dọc. Sau đó, bạn có thể lặp lại: Lấy một trong các nút cuối của dòng trước đó và kết nối nó với một nút trên đường ngang đối diện nằm xa bên trái của tất cả các nút trước đó trên dòng này.
flawr

Toán tử a%bđếm số lượng phân vùng bằng cách sử dụng các nút 0,1,...,atrên dòng trên cùng và các nút 0,1,..,btrên dòng dưới cùng. Toán tử a?bđếm số cách bạn có thể thêm một dòng mới từ nút trên cùng anếu nút dưới cùng bđã được sử dụng. (Bạn có thể kết nối avới tất cả các nút [0,1,...,b-1], nhưng sau đó bạn phải lặp lại cho từng nút đó.)
flawr

@flawr, đó là cái 49 byte mà tôi hiểu. Đó là một ?trong 42 byte mà tôi không có, và điều đặc biệt tò mò là nó không đối xứng.
Peter Taylor

@PeterTaylor Xin lỗi vì sự nhầm lẫn, bằng cách nào đó tôi đã trộn lẫn hai giải pháp. Tôi nghĩ rằng chúng ta có thể dễ dàng chuyển đổi hai giải pháp thành nhau: Trong bước đầu tiên, chúng ta có thể thay thế map...bằng cách hiểu danh sách, trong bước thứ hai chúng ta chỉ cần đưa vào định nghĩa về %:a?b=sum$map(a%)[0..b-1], a%b=a?b+b?a a?b=sum[a%i|i<-[0..b-1]], a%b=a?b+b?a a?b=sum[a?i+i?a|i<-[0..b-1]]
flawr

7

CJam (24 byte)

{2,*e!{e`0f=:(1b2\#}%1b}

Bản demo trực tuyến

Điều này sử dụng cách tiếp cận của Bubbler về tổng các hoán vị n0 và n1.

Mổ xẻ

{         e# Define a block
  2,*     e#   Given input n, create an array of n 0s and n 1s
  e!      e#   Generate all permutations of that array
  {       e#   Map:
    e`    e#     Run-length encode
    0f=:( e#     Extract just the lengths and decrement them
    1b    e#     Sum
    2\#   e#     Raise 2 to the power of that sum
  }%
  1b      e#  Sum the mapped values
}

Cách tiếp cận khác (28 byte)

{_1aa{_2$,f{j}@@,f{j}+1b}2j}

Bản demo trực tuyến

Mổ xẻ

Các hình tam giác đều có một cạnh ngang và hai cạnh liên kết các đường ngang. Dán nhãn các cạnh không nằm ngang bằng một tuple của hai hợp âm x của chúng và sắp xếp theo từ vựng. Sau đó, cạnh đầu tiên là (0,0), cạnh cuối cùng (n,n)và hai cạnh liên tiếp khác nhau ở một trong hai vị trí. Điều này tạo ra một đệ quy đơn giản, mà tôi đã thực hiện bằng cách sử dụng toán tử đệ quy được ghi nhớ j:

{            e# Define a block
  _          e#   Duplicate the argument to get n n
  1aa        e#   Base case for recursion: 0 0 => 1
  {          e#   Recursive body taking args a b
    _2$,f{j} e#     Recurse on 0 b up to a-1 b
    @@,f{j}  e#     Recurse on a 0 up to a b-1
    +1b      e#     Combine and sum
  }2j        e#   Memoised recursion with 2 args
}

chú thích

Đây không phải là lần đầu tiên tôi muốn fjđược hỗ trợ trong CJam. Ở đây nó cũng sẽ đưa số điểm xuống còn 24 byte. Có lẽ tôi nên thử viết một bản vá ...


Yay, tôi đã đánh bại bạn sau 10 giây, tôi không nghĩ mình đã từng đến gần như vậy :)
flawr

@flawr, tôi đã xem xét việc đăng bài trước khi viết một bài mổ xẻ, nhưng tôi nghĩ rằng tôi đã có thời gian để loại nó ra một cách nhanh chóng. Sau đó, tôi thấy "Câu trả lời mới", vì vậy tôi đã xóa phần mổ xẻ bằng văn bản của mình, đăng và chỉnh sửa.
Peter Taylor

1
Cảm ơn vì -5 byte btw: D
flawr

4

Thạch , 15 14 byte

Ø.xŒ!QŒɠ€’§2*S

Hãy thử trực tuyến!

-1 byte dựa trên nhận xét của Peter Taylor.

Sử dụng minh họa của flawr trực tiếp, thay vì công thức kết quả.

Làm thế nào nó hoạt động

Ø.xŒ!QŒɠ€’§2*S    Main link (monad). Input: positive integer N.
Ø.x               Make an array containing N zeros and ones
   Œ!Q            All unique permutations
      Œɠ€         Run-length encode on each permutation
         ’§       Decrement and sum each
           2*S    Raise to power of 2 and sum

Đi tất cả các tuyến đường có thể trên một lưới vuông. Số cách để di chuyển các đơn vị L theo một hướng là một rook là 2**(L-1). Áp dụng điều này cho mọi tuyến đường và tổng hợp số cách để đi qua từng tuyến đường.


Cách tiếp cận tốt đẹp. Khi tôi chuyển nó cho CJam, nó ngắn hơn để giảm độ dài, tổng, và sau đó tăng 2 lên tổng; thay vì tăng 2 đến chiều dài, giảm một nửa, và sau đó nhân lên. Không biết liệu nó có thể giúp bạn tiết kiệm một byte không.
Peter Taylor

3

Than , 44 31 byte

gạch bỏ 44 vẫn là thường xuyên 44

F⊕θ«≔⟦⟧ηF⊕θ⊞ηΣ∨⁺ηEυ§λκ¹⊞υη»I⊟⊟υ

Hãy thử trực tuyến! Giải thích: Hoạt động bằng cách tính toán số cách để phân chia một hình thang có độ dài cạnh đối diện m,nthành các hình tam giác mà tất cả nằm trên các số nguyên. Đây chỉ đơn giản là một trường hợp chung của hình chữ nhật có kích thước ntrong câu hỏi. Số lượng phân vùng được đưa ra đệ quy dưới dạng tổng của số lượng phân vùng cho tất cả các mặt m,0..n-1n,0..m-1. Điều này tương đương với vấn đề tổng quát của các tân binh, OEIS A035002 . Mã chỉ đơn giản là tính toán số lượng phân vùng làm việc 0,0cho đến khi n,nsử dụng các giá trị được tính toán trước đó.

F⊕θ«

Vòng qua các hàng 0..n.

≔⟦⟧η

Bắt đầu với một hàng trống.

F⊕θ

Vòng qua các cột trong hàng 0..n.

⊞ηΣ∨⁺ηEυ§λκ¹

Lấy hàng cho đến nay và các giá trị trong các hàng trước tại cột hiện tại và thêm tổng cộng vào hàng hiện tại. Tuy nhiên, nếu không có giá trị nào cả, thì thay thế 1bằng tổng.

⊞υη»

Thêm hàng đã hoàn thành vào danh sách các hàng cho đến nay.

I⊟⊟υ

Xuất giá trị cuối cùng được tính toán.




Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.