Số lượng domino


9

Viết chương trình hoặc hàm cho nm dương tính toán số lượng gạch domino khác biệt hợp lệ mà bạn có thể đặt trong một hình chữ nhật n bằng m . Đây là trình tự A099390 trong Từ điển bách khoa trực tuyến về chuỗi số nguyên . Bạn có thể lấy đầu vào dưới dạng (các) đối số chức năng, CLA hoặc trên stdin, ở bất kỳ định dạng hợp lý nào. Bạn phải trả lại hoặc in một số nguyên duy nhất làm đầu ra.

Mỗi ốp lát không được để lại bất kỳ khoảng trống nào và mọi ốp lát riêng biệt đều được tính, bao gồm các phép quay, phản xạ, v.v. Ví dụ, các lát cho 2x3 là:

|--    |||    --| 
|--    |||    --|

Ví dụ đầu vào / đầu ra:

1,  9 -> 0
2,  2 -> 2
2,  3 -> 3
4,  4 -> 36
4,  6 -> 281
6,  6 -> 6728
7, 10 -> 53175517

Về mặt lý thuyết, chương trình của bạn sẽ hoạt động cho mọi nm , nhưng nếu chương trình của bạn đòi hỏi quá nhiều bộ nhớ hoặc loại dữ liệu của bạn bị tràn thì nó đã bị loại. Tuy nhiên, chương trình của bạn phải hoạt động chính xác cho mọi n, m <= 8.


Mã ngắn nhất trong byte thắng.


Bạn có thể đã làm cho cuộc sống của chúng tôi dễ dàng hơn nhiều nếu bạn chỉ cho phép các khu vực 2n x 2m , thử thách thú vị!
flawr

Giống như câu hỏi này codegolf.stackexchange.com/q/51067/15599 chỉ ngắn hơn và chậm hơn
Level River St

@ edc65 Damnit = / Tôi dường như không thể nghĩ ra bất cứ điều gì mới lạ ... Hầu như mọi thử thách tôi nghĩ đã được thực hiện dưới một hình thức nào đó. Dù bằng cách nào, các thử thách không hoàn toàn giống nhau vì câu hỏi của tôi là môn đánh gôn và bạn không cần phải tìm những con nghiêng - chỉ có số lượng chúng. Có lẽ mọi người có thể sử dụng các công thức tốt đẹp thay vì viết một bruteforcer.
orlp

Đồng ý - sẽ xóa nhận xét khác
edc65

Sao chép bình luận của bilbo (mà anh ấy đã đăng dưới dạng câu trả lời do 1 đại diện): "Vấn đề này là một thách thức SPOJ rút ngắn: spoj.com/probols/MNTILE Mã ngắn nhất trên SPOJ là 98 byte trong awk." . Có vẻ như tôi đôi khi không có nguồn gốc - tôi không biết.
orlp

Câu trả lời:


3

Bình thường, 30 29 byte

L?bsmy-tb]dfq1.a-VThbb1y*FUMQ

Dùng thử trực tuyến: Trình diễn / Test Suite

Tất cả các đầu vào ví dụ chạy trong trình biên dịch trực tuyến. Cái cuối cùng mất vài giây.

Giải trình:

Trong mã của tôi, tôi sẽ định nghĩa một hàm đệ quy y. Hàm ynày lấy một danh sách các tọa độ 2D và trả về số lượng các góc domino khác nhau bằng các tọa độ này. Ví dụ: y([[0,0], [0,1]]) = 1(một domino ngang), y([[0,0], [1,1]]) = 0(tọa độ không liền kề) và y([[0,0], [0,1], [1,0], [1,1]]) = 2(hai domino ngang hoặc hai dọc). Sau khi xác định hàm tôi sẽ gọi nó với tất cả các tọa độ [x,y]với x in [0, 1, m-1], y in [0, 1, n-1].

Làm thế nào để chức năng đệ quy hoạt động? Nó khá đơn giản. Nếu danh sách các coords trống, có chính xác một ốp lát hợp lệ và ytrả về 1.

Mặt khác, tôi lấy tọa độ đầu tiên trong danh sách b[0]và tìm kiếm các tọa độ còn lại cho hàng xóm. Nếu không có hàng xóm b[0], thì không có khả năng ốp lát, do đó tôi trả về 0. Nếu có một hoặc nhiều hàng xóm, thì số nghiêng là (số nghiêng mà tôi kết nối b[0]với hàng xóm đầu tiên thông qua domina, cộng với số lượng nghiêng mà tôi kết nối b[0]với hàng xóm thứ hai, cộng với ...) Vì vậy, tôi gọi hàm đệ quy cho từng hàng xóm với danh sách rút gọn (bằng cách loại bỏ hai coords b[0]và hàng xóm). Sau đó tôi tổng hợp tất cả các kết quả và trả lại chúng.

Bởi vì thứ tự của các coords luôn luôn chỉ có hai hàng xóm có thể, một bên phải và một bên dưới. Nhưng thuật toán của tôi không quan tâm đến điều đó.

                          UMQ  convert the input numbers into ranges
                        *F     Cartesian product (coords of each square)
L                              define a function y(b):
 ?b                              if len(b) > 0:
           f         b             filter b for squares T, which satisfy:
              .a-VThb                Euclidean distance between T and b[0]
            q1                       is equal to 1 (direct neighbors)
    m                              map each neighbor d to:
      -tb]d                          remove d from b[1]
     y                               and call recursively y with the rest
   s                               sum all those values and return them
                                 else:
                      1            return 1 (valid domino tiling found)
                       y*FUMQ  Call y with all coords and print the result  

Bạn có thể cho chúng tôi biết thêm một chút về cách chương trình của bạn hoạt động? Tôi không thể tìm ra thuật toán của bạn từ các ý kiến.
flawr

@flawr Tôi đã thêm một lời giải thích về thuật toán của tôi.
Jakube

@Jaketube Cảm ơn bạn đã giải thích, tôi thực sự thích cách tiếp cận đệ quy!
flawr

3

Matlab, 292

Tôi chắc chắn rằng điều này có thể được rút ngắn rất nhiều chỉ bằng cách chuyển nó sang ngôn ngữ khác.

Ý tưởng cơ bản là bruteforcing: Tôi đã đưa ra một loại liệt kê tất cả các cách làm thế nào để đặt m*n/2gạch domino trên một m*nbảng. Nhưng bảng liệt kê này cũng bao gồm nhiều gạch không hợp lệ (các viên gạch chồng lên nhau hoặc đi ra ngoài bảng.) Vì vậy, chương trình xây dựng tất cả các nghiêng đó và chỉ tính các giá trị hợp lệ. Sự phức tạp thời gian chạy là về O(2^(m*n/2) * m*n). Bộ nhớ không phải là vấn đề 8x8vì nó chỉ cần O(m*n)bộ nhớ. Nhưng thời gian cần thiết 8x8là khoảng 20 ngày.

Ở đây phiên bản nhận xét đầy đủ giải thích những gì đang xảy ra.

PS: Nếu có ai biết cách làm nổi bật cú pháp Matlab, vui lòng bao gồm thẻ tương ứng trong câu trả lời này!

function C=f(m,n)
d = ceil(m*n/2);%number of dominoes
%enumeration: %the nth bit in the enumeration says whether the nth 
% domino pice is upright or not. we enumerate like this:
% firt piece goes top left:
% next piece goes to the left most column that has an empty spot, in the
% top most empty spot of that column
C=0;%counter of all valid tilings
for e=0:2^d-1 %go throu all enumerations
    %check whether each enumeration is valid
    A = ones(m,n);
    %empty spots are filled with 1
    %filled spots are 0 (or if overlapping <0) 
    v=1;%flag for the validity. hte grid is assumed to be valid until proven otherwise
    for i=1:d %go throu all pieces, place them in A
        %find the column where to place:
        c=find(sum(A)>0,1);
        %find the row where to place:
        r=find(A(:,c)>0,1);
        %find direction of piece:
        b=de2bi(e,d);
        if b(i)
            x=0;y=1;
        else
            x=1;y=0;
        end
        %fill in the piece:
        try
            A(r:r+y,c:c+x)=A(r:r+y,c:c+x)-1;
        catch z
            v=0;break;
        end
        %check whether A has no overlapping pieces
        if any(A(:)<0)
            v=0;break;
        end
    end
    %if valid, count it as valid
    if v && ~norm(A(:))
        disp(A)
        C=C+1;
    end
end

Đây là một golf đầy đủ:

function C=f(m,n);m=4;n=6;d=ceil(m*n/2);C=0;for e=0:2^d-1;A=ones(m,n);v=1;for i=1:d;c=find(sum(A)>0,1);r=find(A(:,c)>0,1);b=de2bi(e,d);if b(i);x=0;y=1;else;x=1;y=0;end;try;A(r:r+y,c:c+x)=A(r:r+y,c:c+x)-1;catch z;v=0;break;end;if any(A(:)<0);v=0;break;end;end;if v && ~norm(A(:));C=C+1;end;end

2

C89, 230 byte

f(n,m,b)int*b;{int s,i;s=i=0;
while(b[i])if(++i==n*m)return 1;
if(i/n<m-1){b[i]=b[i+n]=1;s+=f(n,m,b);b[i]=b[i+n]=0;}
if(i%n<n-1&&!(b[i]|b[i+1])){b[i]=b[i+1]=1;s+=f(n,m,b);b[i]=b[i+1]=0;}
return s;}
g(n,m){int b[99]={};return f(n,m,b);}

Để dễ đọc, tôi đã viết tay câu trả lời này - tất cả các dòng mới có thể được gỡ bỏ một cách an toàn để có được tới 230 byte.

Xác định hàm int g(int n, int m)trả về số lượng nghiêng. Nó sử dụng một hàm trợ giúp flặp đi lặp lại trên tất cả các độ nghiêng hợp lệ bằng cách đặt một domino, đệ quy và sau đó loại bỏ domino trên một bảng chia sẻ.


0

Con trăn 243

Tôi đã chọn cách tiếp cận vũ phu:

  • tạo m * n / 2 hướng;
  • thử và lắp domino trên bảng m * n.

Nếu tất cả đều phù hợp và không còn chỗ trống, chúng tôi có một mục hợp lệ.

Đây là mã:

import itertools as t
m,n=input()
c,u=0,m*n
for a in t.product([0,1],repeat=u/2):
 l,k,r,h=[' ',]*u,0,'-|',[1,m]
 for t in a:
  l[k]=r[t]
  k+=h[t]   
  if k%m<m and k/m<n and l[k]==' ':l[k]=r[t]
  k=''.join(l).find(' ',1)
 if k<0:c+=1
print c
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.