Có bao nhiêu hình chữ nhật trong lưới?


29

Chà, mặc dù thử thách này hóa ra là một thành công lớn, nhưng nó cũng hóa ra rất tầm thường để giải quyết. Do đó, đối với những người tìm kiếm nhiều thử thách hơn, tôi đã tạo phần tiếp theo cho thử thách này, trong đó bạn phải đếm số lượng hình chữ nhật duy nhất . Kiểm tra nó ra!

Bây giờ, đối với những người tìm cách giải quyết thách thức này , nó đến đây.


Chà, chúng tôi chưa thực sự có một thử thách như thế này, vì vậy chúng tôi đi đây.

Hãy xem xét 3 x 3lưới hình chữ nhật này:

Thí dụ

Có bao nhiêu hình chữ nhật? Chà, đếm trực quan, chúng ta có thể thấy rằng thực sự có 36hình chữ nhật, bao gồm toàn bộ mặt phẳng, tất cả được hiển thị trong GIF hoạt hình dưới đây:

Hình chữ nhật trong ví dụ

Nhiệm vụ

Việc đếm các hình chữ nhật như hình trên là nhiệm vụ. Nói cách khác, cho 2 số nguyên lớn hơn hoặc bằng 0, mn, trong đó mđại diện cho chiều rộng và nđại diện cho chiều cao, xuất ra tổng số hình chữ nhật trong m x nlưới hình chữ nhật đó.

Quy tắc

  • Việc sử dụng bất kỳ công cụ tích hợp nào trực tiếp giải quyết vấn đề này đều không được phép rõ ràng.

  • Thử thách này không phải là tìm ra câu trả lời ngắn nhất, mà là tìm ra câu trả lời ngắn nhất trong mọi ngôn ngữ. Do đó, không có câu trả lời sẽ được chấp nhận.

  • Sơ hở tiêu chuẩn bị cấm.

Các trường hợp thử nghiệm

Trình bày ở định dạng Array of Integers Input -> Integer Output:

[0,0] -> 0
[1,1] -> 1
[3,3] -> 36 (Visualized above)
[4,4] -> 100
[6,7] -> 588

Tài liệu tham khảo

Hãy nhớ rằng, đây là , vì vậy mã ngắn nhất sẽ thắng!


Tôi đã tính 588cho trường hợp thử nghiệm cuối cùng.
Leaky Nun

@LeakyNun Vậy thì, tôi đoán là tôi đã bỏ lỡ vài thứ trong khi đếm chúng. Nó đã được sửa.
R. Kap

Giá trị tối đa của đầu vào là gì?
Erik the Outgolfer

Câu trả lời:


34

Python, 22 byte

lambda m,n:m*~m*n*~n/4

Công thức m*n*(m+1)*(n+1)/4được rút ngắn bằng cách sử dụng phần bù bit ~m=-(m+1), biểu thị (m+1)*(n+1)~m*~n.

Tại sao số lượng hình chữ nhật m*n*(m+1)*(n+1)/4? Mỗi hình chữ nhật được chỉ định bởi sự lựa chọn của hai đường ngang (trên và dưới) và hai đường thẳng đứng (trái và phải). Có m+1các đường ngang, trong đó chúng tôi chọn một tập hợp con gồm hai dòng khác nhau. Vì vậy, số lượng các lựa chọn là choose(m+1,2), đó là m*(m+1)/2. Nhân với các n*(n+1)/2lựa chọn cho các đường thẳng đứng cho kết quả.


Thủ thuật +1 đó thật tuyệt vời.
David Ljung Madison Stellar

11

Thạch , 4 byte

RS€P

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

Ngoài ra, cũng 4 byte

pP€S

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


Làm tốt lắm. Đồng ý. :)
R. Kap

24
Quan tâm để giải thích?
Pureferret

Ngoài ra còn có בHP‘c2Pcó thể các lựa chọn thay thế 4 byte khác.
dặm

1
@Pureferret Điều này sử dụng công thức từ OEIS về việc đây là sản phẩm của số nthmthhình tam giác. Rchuyển đổi mỗi số thành chỉ số dựa trên 1 : [1, 2, ..., n]. Slà tổng và có nghĩa là 'mỗi' để mỗi danh sách được tóm tắt, đưa ra một danh sách như : [nth triangle number, mth triangle number]. Sau đó Plấy sản phẩm của danh sách đó, cho kết quả mong muốn.
FryAmTheEggman

1
@FryAmTheEggman vì vậy những gì bạn nói là .... Phép thuật
Pureferret


9

Toán học, 15 byte

##(1##+##+1)/4&

Đây là một hàm không tên lấy hai đối số nguyên và trả về số lượng hình chữ nhật.

Giải trình

Việc thực hiện về cơ bản là một hình thức rất golf của sản phẩm của hai số tam giác. Có thể đáng để đọc phần "Trình tự lập luận" trong bài đăng này để biết chi tiết, nhưng tôi sẽ cố gắng tóm tắt ý chính ở đây.

##mở rộng thành một chuỗi tất cả các đối số. Điều này tương tự như việc ghép hình trong các ngôn ngữ khác. Ví dụ, nếu các đối số là 34, sau đó {1, 2, ##, 5}sẽ cung cấp cho bạn {1, 2, 3, 4, 5}. Nhưng điều này không chỉ hoạt động trong danh sách, mà trong bất kỳ biểu hiện nào, ví dụ như f[1, 2, ##, 5]cũng sẽ được f[1, 2, 3, 4, 5].

Điều này trở nên thú vị khi bạn kết hợp ##với các nhà khai thác. Tất cả các toán tử trong Mathicala chỉ là các tay ngắn cho một số f[...]biểu thức giống như (có thể được lồng vào nhau). Ví dụ a+bPlus[a, b]a-bthực sự đại diện Plus[a, Times[-1, b]]. Bây giờ khi bạn kết hợp ##với các toán tử, điều Mathicala làm là mở rộng các toán tử trước, xử lý ##như một toán hạng đơn và chỉ mở rộng chúng ở cuối. Bằng cách chèn ##vào đúng chỗ, do đó chúng ta có thể sử dụng cả hai để nhân và thêm toán hạng.

Hãy làm điều này cho mã ở trên:

##(1##+##+1)/4

Mở rộng nó thành dạng đầy đủ của nó, chúng ta có được điều này:

Times[##, Plus[Times[1, ##], ##, 1], Rational[1/4]]

Hãy chèn các đối số hàm ab:

Times[a, b, Plus[Times[1, a, b], a, b, 1], Rational[1/4]]

Và bây giờ chúng tôi chuyển đổi nó trở lại thành ký hiệu toán học tiêu chuẩn:

a * b * (a * b + a + b + 1) / 4

Sắp xếp lại một chút cho thấy đây là sản phẩm của các số tam giác:

a * b * (a + 1) * (b + 1) / 4
(a * (a + 1) / 2) * (b * (b + 1) / 2)
T(a) * T(b)

Thực tế thú vị: việc triển khai này rất khó chơi, nó có cùng độ dài với tích hợp để tính toán một số tam giác duy nhất , PolygonalNumber.



8

Sứa , 16 byte

p|%/**+1
  4  Ei

Định dạng đầu vào là [x y], đầu ra chỉ là kết quả.

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

Giải pháp thay thế, cùng số byte:

pm%/*[*i
  4  +1

Giải trình

Đã đến lúc giới thiệu Jellyfish xứng đáng! :)

Sứa là ngôn ngữ của Zgarb dựa trên thử thách cú pháp 2D của anh ấy . Các ngữ nghĩa chủ yếu được lấy cảm hứng từ J, nhưng cú pháp là một tác phẩm nghệ thuật. Tất cả các chức năng là các ký tự đơn và được đặt trên một lưới. Các hàm lấy các đối số của chúng từ mã thông báo tiếp theo ở phía nam và phía đông của chúng và trả về kết quả ở phía bắc và phía tây. Điều này cho phép bạn tạo một mạng lưới chức năng thú vị trong đó bạn sử dụng lại các giá trị bằng cách chuyển chúng vào một số hàm từ nhiều hướng.

Nếu chúng ta bỏ qua thực tế là một số mã thông báo trong chương trình trên là toán tử đặc biệt (hàm cấp cao hơn), chương trình trên sẽ được viết giống như thế này bằng ngôn ngữ lành mạnh:

p(|( /*(i*(i+1)) % 4 ))

Chúng ta hãy đi qua mã từ dưới lên. Đầu vào được cung cấp bởi i, do đó đánh giá [x y].

Trên +cùng của nó nhận đầu vào này cùng với nghĩa đen 1và do đó tăng cả hai yếu tố để cung cấp [(x+1) (y+1)](hầu hết các hoạt động được xâu chuỗi tự động qua danh sách).

Giá trị khác của iđược gửi bên trái, nhưng Ephần tách là đối số phía đông bắc và tây. Điều đó có nghĩa là đầu vào bên phải *thực sự [x y][(x+1) (y+1)]vì vậy điều này tính toán [x*(x+1) y*(y+1)].

Việc tiếp theo *thực sự được sửa đổi bởi trước /đó biến nó thành một hoạt động gấp. Gấp *qua một cặp chỉ đơn giản là nhân nó, để chúng ta có được x*(x+1)*y*(y+1).

Bây giờ %chỉ là phân chia để nó tính toán x*(x+1)*y*(y+1)/4. Thật không may, điều này dẫn đến một float, vì vậy chúng ta cần làm tròn nó với unary |. Cuối cùng, giá trị này được đưa vào để pin kết quả cuối cùng.


Tôi có thể đã thề rằng tôi đã đọc một cái gì đó trong các tài liệu về phép chia số nguyên ...
Conor O'Brien

7

R, 40 35 byte

Vâng, thời gian để nhảy vào cuối sâu! Đây là mã R của tôi , lấy cảm hứng từ câu trả lời @xnor:

a=scan();(n=a[1])*(m=a[2])*(n+1)*(m+1)/4 

EDIT : Trong phiên bản này, R sẽ yêu cầu hai lần cho đầu vào.

(n=scan())*(m=scan())*(n+1)*(m+1)/4

cat(prod(choose(scan()+1,2)))là 29 byte.
Giuseppe

6

CJam, 12 10 byte

2 byte được lưu nhờ Martin.

{_:)+:*4/}

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

Đây là một khối lấy danh sách 2 phần tử từ ngăn xếp và để lại giải pháp trên ngăn xếp. Chương trình đầy đủ có thể sử dụng để thử nghiệm : riari+{_:)+:*4/}~.

Dựa trên giải pháp trăn nổi bật của xnor.

Giải trình:

{_:)+:*4/}
{        } -- Define a block
 _:)       -- Duplicate list, increment all values in new list
    +      -- Join the two lists
     :*    -- Fold multiply over all 4 elements
       4/  -- Divide by 4

2
Tôi nghĩ rằng điều này hoạt động cho 10 nếu bạn đưa vào danh sách hai yếu tố? {_:~+:*4/}
Martin Ender

Trên thực tế, không cần phải sử dụng ~tất cả trong CJam. Chỉ cần sử dụng ).
Martin Ender

5

Matlab, 23 19 byte

@(x)prod([x/2,x+1])

Thực hiện công thức m*n*(m+1)*(n+1)/4
Cách sử dụng:ans([m,n])


4

MATL , 6 byte

tQ*2/p

Đầu vào là một mảng của mẫu [m,n].

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

Giải trình

Tính toán trực tiếp dựa trên công thức m*(m+1)*n*(n+1)/4.

t     % Input array [m,n] implicitly. Duplicate
Q     % Add 1 to each entry of the copy: gives [m+1,n+1]
*     % Multiply element-wise: gives [m*(m+1),n*(n+1)]
2/    % Divide each entry by 2: [m*(m+1)/2,n*(n+1)/2]
p     % Product of the two entries: m*(m+1)*n*(n+1)/4. Display implicitly


4

Java 7, 39 38 byte

int c(int a,int b){return~a*a*b*~b/4;}

Java 8, 26 25 19 18 17 byte

a->b->a*~a*b*~b/4

Dựa trên câu trả lời tuyệt vời của @xnor . Nhiều byte được lưu nhờ @DavidConrad . Hãy thử nó ở đây.

Mã kiểm tra (Java 7):

Hãy thử nó ở đây.

class M{
  static int c(int a,int b){return~a*a*b*~b/4;}

  public static void main(String[] a){
    System.out.println(c(0, 0));
    System.out.println(c(1, 1));
    System.out.println(c(3, 3));
    System.out.println(c(4, 4));
    System.out.println(c(6, 7));
  }
}

Đầu ra:

0
1
36
100
588

1
Bạn không cần điều đó returna->b->ngắn hơn một byte (a,b)->.
David Conrad

2
Tôi cũng không nghĩ rằng bạn cần dấu chấm phẩy, vì nếu bạn truyền lambda vào một phương thức lấy Function<Integer, Function<Integer, Integer>>tham số, nó sẽ không được theo sau bởi dấu chấm phẩy.
David Conrad

2
Tôi đồng ý với @DavidConrad: Tôi không tính kết thúc ;cho một tuyên bố J8 lambdas.
CAD97

@DavidConrad Xin lỗi vì đã chỉnh sửa rất muộn, nhưng bây giờ tôi mới nhận thấy tôi đã đọc qua nhận xét của bạn để xóa return .. Ngoài ra, tôi hầu như không bao giờ lập trình trong Java 8 (vì vậy tất cả các câu trả lời Java 7 của tôi), nhưng làm cách nào để tôi a->b->làm việc? Đây là ideone cho trường hợp hiện tại.
Kevin Cruijssen

1
Xin lỗi vì đã trả lời rất muộn! Bạn cần cà ri chức năng, vì vậy bạn cần thay đổi MathOperation.operationđể chỉ lấy một int, trả về a Function<Integer, Integer>và khi bạn gọi nó, ban đầu bạn chỉ truyền tham số đầu tiên a, sau đó gọi .apply(b)vào Function. Bạn cũng cần nhập java.util.function.Function. Đây là một ideone với những thay đổi.
David Conrad

3

Ruby, 22 byte

Ăn cắp mánh khóe của @ xnor và làm cho một stabby-lambda:

r=->(m,n){m*n*~m*~n/4}

Cuộc gọi ví dụ:

r[6,7]     # => 588

Hoặc là một Proc, cũng 22 byte:

proc{|m,n|m*n*~m*~n/4}

Mà sau đó chúng ta có thể gọi:

proc{|m,n|m*n*~m*~n/4}.call(6,7)     # => 588

Bạn không cần đặt tên cho nó là các chức năng ẩn danh của Haiti là ổn theo quy ước của trang web
Conor O'Brien

3

Mê cung , 13 11 byte

*?;*_4/!
):

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

Giải trình

Điều này cũng tính toán tích của các số tam giác giống như hầu hết các câu trả lời. Khối 2x2 hàng đầu là một vòng lặp nhỏ:

*?
):

Trong lần lặp đầu tiên *không làm gì cả, để thứ tự vòng lặp thực là:

?   Read integer N from STDIN or 0 at EOF and push onto stack. If 0, exit the loop.
:   Duplicate N.
)   Increment.
*   Multiply to get N*(N+1).

Mã còn lại chỉ là tuyến tính:

;   Discard the zero that terminated the loop.
*   Multiply the other two values.
_4  Push a 4.
/   Divide.
!   Print.

Labyrinth sau đó cố gắng thực hiện /lại, điều này chấm dứt chương trình do chia cho 0.



2

05AB1E, 4 byte

€LOP

Giải trình

Sử dụng công thức được mô tả tại A096948

      # Implicit input, ex: [7,6]
€L    # Enumerate each, [[1,2,3,4,5,6,7],[1,2,3,4,5,6]]
  O   # Sum, [28,21]
   P  # Product, 588
      # Implicit display

Lấy đầu vào là [n, m] .

Dùng thử trực tuyến


1

Bình thường, 8 6 byte

Hai byte được lưu nhờ @DenkerAffe.

*FmsSd

Đầu vào dự kiến ​​là một danh sách như thế [m,n]. Hãy thử nó ở đây .

Giải trình:

          Implicit assignment of Q to eval(input).
*         Multiplication.
 F        Splat the following sequence onto the arguments of the previous function.
  m       Map the following function of d over Q (Q is implicitly added to the end).
   s      Reduce the following list with addition, initial value of 0.
    Sd    Return range(1,d+1).

1
Bạn có thể sử dụng Fthay vì .*và loại bỏ Qvì nó được thêm vào một cách giả định.
Denker

Tôi biết Fnhưng tôi không thể tìm ra cách sử dụng nó và hình dung rằng tôi cần sử dụng .*thay thế ... Cảm ơn!
Rhyzomatic

1

C #, 19 byte

(n,m)=>m*n*~m*~n/4;

Một hàm ẩn danh dựa trên câu trả lời của @ xnor.


1

Lua, 74 63 byte

x,y=...n=0 for i=1,y do for j=i,i*x,i do n=n+j end end print(n)

Hàm lấy đầu vào là tham số số.

Do cách thức thực hiện Lua, về mặt kỹ thuật, đây là một hàm, với các đối số biến, có thể được gọi bằng cách gói nó trong một câu lệnh "hàm" hoặc tải nó từ mã nguồn bằng cách sử dụng "chuỗi tải"


1
Tôi thấy rằng bạn có khá nhiều mã chỉ dành cho I / O. Có lẽ sẽ ngắn hơn nếu chỉ tạo một hàm lấy hai số và trả về câu trả lời, và loại bỏ tất cả mã I / O không cần thiết này?
Zwei

@Zwei Tôi quên rằng các chức năng được phép lấy đầu vào theo tham số. Cảm ơn đã chỉ ra rằng.
brianush1

Hàm này có thể được đặt tên giống như "f" thay vì toàn bộ tên "hàm" để lưu thêm 7 byte
Zwei

Trong Lua, từ khóa "hàm" là bắt buộc để khai báo hàm. Nếu không có tên nào được chỉ định (ví dụ: "function f ()"), thì đó là một hàm ẩn danh. (ví dụ: "hàm ()"). Do đó, "hàm" là bắt buộc để mã hoạt động.
brianush1

Ồ, tôi quên rằng lua hoạt động như vậy. Lỗi của tôi!
Zwei


1

Brain-Flak , 84 80 byte

({}<>)({({})<({}[()])>}{})<>({({})<({}[()])>}{}[()]){<>(({}))<>({}[()])}<>({{}})

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

Có lẽ rất tối ưu, đặc biệt là do việc sử dụng lại mã liên quan đến số tam giác, nhưng ít nhất chúng ta có một giải pháp Brain-Flak hoạt động.

Đáng buồn thay, nó dường như thất bại bằng cách lặp vô hạn với 0 0testcase nhưng tất cả những thứ khác hoạt động tốt.




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.