Chơi gôn: Có bao nhiêu hình vuông có độ dài đơn vị trong danh sách tọa độ 2d?


8

Đưa ra một danh sách các tọa độ 2d (x, y), xác định có bao nhiêu hình vuông đơn vị (độ dài cạnh 1 đơn vị) có thể được hình thành bằng cách sử dụng tọa độ.

  • Đầu vào sẽ là một mảng gồm 0 hoặc nhiều cặp tọa độ:
    vd: trong JavaScript:numofsq([[0,0], [1,0], [1,1], [0,1]])
  • Không có tọa độ trùng lặp trong đầu vào
  • Thứ tự đầu vào sẽ là ngẫu nhiên (tọa độ 2d ngẫu nhiên).
  • Dạng tọa độ: [tọa độ x, tọa độ y] (duh)
  • Thứ tự tọa độ: [0,0], [1,0], [1,1], [0,1] và [0,0], [0,1], [1,1], [1,0 ] biểu thị cùng một đơn vị vuông (sẽ được tính chỉ một lần)
  • Tọa độ có thể là số nguyên âm hoặc dương (duh)
  • Hàm sẽ chỉ trả về số lượng hình vuông đơn vị có thể, 0 trở lên.

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

Input Coordinates Pairs                                               Expected Output
[0,0], [0,1], [1,1], [1,0], [0,2], [1,2]                              2
[0,0], [0,1], [1,1], [1,0], [0,2], [1,2], [2,2], [2,1]                3
[0,0], [0,1], [1,1], [1,0], [0,2], [1,2], [2,2], [2,1], [2,0]         4
[0,0], [0,1], [1,1], [1,0], [0,2], [1,2], [2,2], [2,1], [2,0], [9,9]  4

Spoiler Alert: Giải pháp công cụ từ đây trở đi [JS]

Phương pháp tiếp cận vũ phu, không nhanh nhẹn và bẩn thỉu (bao gồm để cung cấp một số hướng).

//cartesian distance function
function dist(a, b) {
    if (b === undefined) {
        b = [0, 0];
    }
    return Math.sqrt((b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1]));
}

//accepts 4 coordinate pairs and checks if they form a unit square
//this could be optimized by matching x,y coordinates of the 4 coordinates
function isUnitSquare(a) {
    var r = a.slice(),
        d = [],
        c = [],
        i,
        j = 0,
        counter = 0;

    for (i = 1; i < 4; i++) {
        if (dist(a[0], a[i]) === 1) {
            d.push(a[i]);
            r[i] = undefined;
            counter++;
        }
    }
    r[0] = undefined;
    c = d.concat(r.filter(function(a) {return undefined !== a}));

    if (dist(c[0], c[1]) === 1) {j++};
    if (dist(c[1], c[2]) === 1) {j++};
    if (dist(c[2], c[0]) === 1) {j++};
    return counter === 2 && j === 2;
}

//a powerset function (from rosetta code)
//however, we will need only "sets of 4 coordinates"
//and not all possible length combinations (sets of 3 coords or
//sets of 5 coords not required). Also, order doesn't matter.
function powerset(ary) {
    var ps = [[]];
    for (var i=0; i < ary.length; i++) {
        for (var j = 0, len = ps.length; j < len; j++) {
            ps.push(ps[j].concat(ary[i]));
        }
    }
    return ps;
}

//so to capture only sets of 4 coordinates, we do
var res = powerset([[0,0], [0,1], [1,1], [1,0], [0,2], [1,2], [2,2], [2,1], [2,0]])
          .filter(function (a) {return a.length === 8;});

//and a little bit of hoopla to have a nice set of sets of 4 coordinates.
//(Dizzy yet? Wait for the generalized, 3D, cube of any edge length version ;))
var squareQuads = res.map(function(ary) {
    return ary.join().match(/\d\,\d/g)
       .map(function(e) {
           return [+e.split(',')[0], +e.split(',')[1]];
        });
});

//Finally, the last bit
var howManyUnitSquares = 0;
squareQuads.map(function(quad) {
    if (isUnitSquare(quad)) {
        howManyUnitSquares++;
    }
});

console.log(howManyUnitSquares);

//Cleaning up and putting those in-line stuff into a function
function howManySquares(r) { //r = [[x,y], [x,y], [x,y], [x,y], ......];
    var res = powerset(r)
          .filter(function (a) {return a.length === 8;});
    var squareQuads = res.map(function(ary) {
        return ary.join().match(/\d\,\d/g)
               .map(function(e) {
                   return [+e.split(',')[0], +e.split(',')[1]];
                });
    });

    var answer = 0;
    squareQuads.map(function(quad) {
        if (isUnitSquare(quad)) {
            answer++;
        }
    });

    return answer;
}

1
[-1,0],[0,-1],[1,0],[0,1]hình vuông?
Julian Kuhn

@JohannesKuhn Không, độ dài cạnh của chúng không phải là sự thống nhất, mà là sqrt (2), vì vậy chúng không phải là hình vuông đơn vị.

Nhưng [-2,0],[0,-2],[2,0],[0,2]có chiều dài cạnh 2. Quảng trường?
Julian Kuhn

2
@JohannesKuhn Quảng trường? Đúng. ĐƠN VỊ ? Số

Câu trả lời:


5

APL (Dyalog), 30

+/{(2-/⍵)≡2-/,⍳2 2}¨,∘.,⍨⍣2⊂¨⎕

Vâng, trong hầu hết các trường hợp, khả năng đọc và số char là tỷ lệ thuận.


Đầu ra mẫu

⎕:
      (0 0)(0 1)(1 0)(1 1)(0 2)(1 2)(2 2)(2 1)(2 0)
4

Giải thích

Vì vậy, 4 điểm tạo thành một hình vuông đơn vị khi và chỉ khi vị trí tương đối của chúng là (1,1), (1,2), (2,1), (2,2)
{(2-/⍵)≡2-/,⍳2 2}là một hàm trả về 1 hoặc 0 (đúng / sai) đưa ra một bộ 4 điểm làm đầu vào dựa trên việc chúng có ở vị trí tương đối hay không và được sắp xếp theo thứ tự (1,1), (1,2), (2,1), (2,2):
⍳2 2Tạo 2 Ma trận × 2 của các điểm (1,1), (1,2), (2,1), (2,2) Làm
,sáng tỏ ma trận đó thành một mảng các điểm
2-/trừ trừ khôn ngoan theo cặp: (1,1) - ( 1,2); (1,2) - (2,1); (2.1) - (2.2), cung cấp cho mảng [(0, -1), (- 1,1), (0, -1)]
(2-/⍵)Phép trừ cặp khôn ngoan giảm trên đầu vào
Kiểm tra xem hai mảng bằng nhau

Chương trình chính
Đưa đầu vào và đánh bại nó. Những thứ như (0 0)(0 1)(1 0)(1 1)đánh giá một mảng lồng nhau (Tương đương [[0,0],[0,1],[1,0],[1,1]]trong JS)
⊂¨Với mỗi điểm ( ¨), hãy đặt nó vào một vô hướng ( ) ( [[[0,0]],[[0,1]],[[1,0]],[[1,1]]])
∘.,⍨⍣2Đối với mỗi cặp phần tử của mảng, nối chúng để tạo thành một mảng mới. ( [ [[0,0],[0,0]],[[0,0],[0,1]]...) Lặp lại một lần. Điều này cung cấp cho tất cả các bộ 4 điểm có thể được thực hiện bằng cách sử dụng các điểm đã cho. Trong một số bộ này, cùng một điểm sẽ được sử dụng nhiều lần, nhưng đây không phải là các ô vuông đơn vị nên không cần lãng phí tổ hợp phím để loại bỏ chúng. ( ,nối 2 mảng, ∘.có nghĩa là "làm điều đó cho mọi cặp phần tử", có nghĩa là "sử dụng toán hạng bên phải như cả hai toán hạng bên trái và bên phải" và ⍣2có nghĩa là "làm điều này hai lần")
,Vì thao tác trước sẽ cung cấp một mảng 4 chiều (lưu ý rằng các mảng lồng nhau và mảng đa chiều là những thứ khác nhau trong APL), chúng ta phải làm sáng tỏ nó để có được một mảng các tập hợp (gồm 4 điểm).
¨Đối với mỗi bộ,
{...}thực hiện chức năng nói trên. Kết quả sẽ là một mảng 0 và 1 cho biết tập hợp có phải là một hình vuông đơn vị hay không. Lưu ý rằng vì chức năng cũng kiểm tra thứ tự, trùng lặp được loại bỏ.
+/Cuối cùng, tổng kết quả mảng để có được số đếm.


3

Toán học 65 ký tự

f@d_ := Length@Select[Subsets[d, {4}], Sort[g@#] == {1, 1, 1, 1, √2, √2} &]

Xét nghiệm

f[{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 2}, {1, 2}}]

2

f[{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 2}, {1, 2}, {2, 2}, {2, 1}}]

3

f[{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 2}, {1, 2}, {2, 2}, {2, 1}, {2,0}}]

4

f[{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 2}, {1, 2}, {2, 2}, {2, 1}, {2,0}, {9, 9}}]

4

Giải trình

Tạo tất cả các tập hợp con gồm 4 điểm và kiểm tra tất cả các khoảng cách giữa các điểm. Khoảng cách giữa các điểm được sắp xếp cho một hình vuông đơn vị là: `{1, 1, 1, 1, 2, 2}.

Length sau đó đếm số ô vuông đơn vị.


Định nghĩa của là ggì?
alephalpha

1
Đây là giải pháp ngắn hơn của tôi:f=Count[#-#[[1]]&/@(Sort/@#~Subsets~{4}.{1,I}),{0,I,1,1+I}]&
alephalpha

1

Ruby, 164 161 153 147 ký tự

f=->a{a.combination(4).map(&:sort).uniq.count{|x|[x[1][0]==l=x[0][0],x[3][0]==m=x[2][0],x[2][1]==n=x[0][1],x[3][1]==o=x[1][1],m-l==1,o-n==1].all?}}

Nó thực sự rất dễ đọc, ngoại trừ phần kiểm tra xem đó có phải là một hình vuông đơn vị hay không.

Có lẽ nhiều cải tiến có thể, cố gắng tìm chúng ngay bây giờ.

Các mẫu (tất cả đều hoạt động):

puts f[[[0,0], [0,1], [1,1], [1,0], [0,2], [1,2]]]                             #--> 2
puts f[[[0,0], [0,1], [1,1], [1,0], [0,2], [1,2], [2,2], [2,1]]]               #--> 3
puts f[[[0,0], [0,1], [1,1], [1,0], [0,2], [1,2], [2,2], [2,1], [2,0]]]        #--> 4
puts f[[[0,0], [0,1], [1,1], [1,0], [0,2], [1,2], [2,2], [2,1], [2,0], [9,9]]] #--> 4

Tôi có thể tìm thấy một mẹo với transpose, nhưng tôi đã thử một lúc và tôi không thể. Đây là những gì nó làm:

irb(main):001:0> a = [[5, 10], [5, 11], [6, 10], [6, 11]]
=> [[5, 10], [5, 11], [6, 10], [6, 11]]
irb(main):002:0> a.transpose
=> [[5, 5, 6, 6], [10, 11, 10, 11]]

Đồng ý với phần có thể đọc được - Là một người chưa bao giờ lập trình trong Ruby, tôi vẫn có thể hiểu rõ các bước. Quá tệ, JS không có một số tổ hợp được tích hợp.

0

Python, 61 ký tự

f=lambda l:sum(1for x,y in l if{(x+1,y),(x,y+1),(x+1,y+1)}<l)

Mẫu vật:

>>> f({(0,0), (0,1), (1,1), (1,0), (0,2), (1,2)})
2
>>> f({(0,0), (0,1), (1,1), (1,0), (0,2), (1,2), (2,2), (2,1)})
3
>>> f({(0,0), (0,1), (1,1), (1,0), (0,2), (1,2), (2,2), (2,1), (2,0)})
4
>>> f({(0,0), (0,1), (1,1), (1,0), (0,2), (1,2), (2,2), (2,1), (2,0), (9,9)})
4

0

Toán học, 56 ký tự

f=Count[#-#[[1]]&/@Subsets[{}⋃#.{1,I},{4}],{0,I,1,1+I}]&
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.