ゴルフ:2D座標のリストにある単位長の正方形はいくつありますか?


8

2d(x、y)座標のリストを前提として、その座標を使用して形成できる単位正方形(エッジ長1単位)の数を決定します。

  • 入力は、座標の0以上のペアの配列になります。
    例:JavaScriptの場合:numofsq([[0,0], [1,0], [1,1], [0,1]])
  • 入力に重複する座標はありません
  • 入力順序はランダムになります(ランダムな2D座標)。
  • 座標形式:[x座標、y座標](duh)
  • 座標の順序:[0,0]、[1,0]、[1,1]、[0,1]および[0,0]、[0,1]、[1,1]、[1,0 ]同じ単位の正方形を表す(1回だけ数える)
  • 座標は負または正の整数にすることができます(duh)
  • 関数は、可能な単位平方の数、0以上を返します。

テストケース:

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

スポイラーアラート:今後の解決策[JS]

ゴルフを使わない、迅速かつ汚い、力ずくのアプローチ(いくつかの指示を提供するために含まれています)。

//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]正方形は?
Johannes Kuhn

@JohannesKuhnいいえ、エッジの長さは1ではありませんが、sqrt(2)なので、単位の正方形ではありません。

ただし[-2,0],[0,-2],[2,0],[0,2]、エッジの長さは2です。平方?
Johannes Kuhn

2
@JohannesKuhn Square?はい。UNIT Square?いいえ

回答:


5

APL(ダイアログ)、30

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

まあ、ほとんどの場合、読みやすさと文字数は比例します。


出力例

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

説明

したがって、4点は、それらの相対位置が(1,1)、(1,2)、(2,1)、(2,2)
{(2-/⍵)≡2-/,⍳2 2}である場合にのみ、単位正方形を形成し、1または0を返す関数です(true / false)相対位置にあり、(1,1)、(1,2)、(2,1)、(2,2)の順にソートされているかどうかに基づいて、4つのポイントのセットを入力として指定:
⍳2 22を生成点の×2行列(1,1)、(1,2)、(2,1)、(2,2)
,その行列を点の配列に解きます
2-/ペアワイズ減算削減:(1,1)-( 1,2); (1,2)-(2,1); (2,1) - (2,2)、配列与える[(0、-1)、( - 1,1)、(0、-1)]
(2-/⍵)ペアワイズ減算入力に削減
2かどうかを確認配列が等しい

メインプログラムは
入力を受け取り、それを評価します。のようなものは(0 0)(0 1)(1 0)(1 1)、ネストされた配列に評価されます([[0,0],[0,1],[1,0],[1,1]]JSと同等)
⊂¨。すべてのポイント()について¨、スカラー()([[[0,0]],[[0,1]],[[1,0]],[[1,1]]])で囲み
∘.,⍨⍣2ます。配列の要素のすべてのペアについて、それらを連結して新しい配列を形成します。([ [[0,0],[0,0]],[[0,0],[0,1]]...)1回繰り返します。これにより、指定されたポイントを使用して作成できる4つのポイントのすべてのセットが得られます。これらのセットのいくつかでは、同じポイントが複数回使用されますが、これらは単位正方形ではないため、キーストロークを無駄にして削除する必要はありません。(,2つの配列を連結し、∘.「要素のすべてのペアに対してそれを行う」、「右のオペランドを左と右の両方のオペランドとして使用する」、⍣2「これを2回実行する」を意味します)
,前の操作は4次元配列を与えるため(APLではネストされた配列と多次元配列は異なるものであることに注意してください)、(4点の)セットの配列を取得するにはそれを解明する必要があります。
¨セットごとに、
{...}前述の機能を実行します。結果は、セットが単位正方形であるかどうかを示す0と1の配列になります。関数は順序もチェックするため、重複が排除されることに注意してください。
+/最後に、結果の配列を合計してカウントを取得します。


3

Mathematica 65文字

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

テスト

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}}]

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

説明

4ポイントのすべてのサブセットを生成し、すべてのポイント間距離をチェックします。単位正方形のソートされた点間距離は、 `{1、1、1、1、√2、√2}です。

Length 次に、単位正方形の数をカウントします。


の定義はg
alephalpha 2013年

1
これが私の短い解決策です:f=Count[#-#[[1]]&/@(Sort/@#~Subsets~{4}.{1,I}),{0,I,1,1+I}]&
alephalpha '19年

1

Ruby、164 161 153 147文字

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?}}

単位正方形であるかどうかをテストする部分を除いて、実際には非常に読みやすいです。

おそらく多くの改善が可能であり、今それらを見つけようとしています。

サンプル(すべて機能します):

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

でトリックを見つけることができるかもしれませんがtranspose、しばらくの間努力してきましたが、できません。以下がその機能です。

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]]

読みやすい部分に同意する-Rubyでプログラミングしたことがない人なので、手順を明確に理解できます。残念JSを内蔵いくつかの組み合わせ論を持っていません。

0

Python、61文字

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

サンプル:

>>> 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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.