Quantcast
Viewing latest article 6
Browse Latest Browse All 6

Golfing: How many unit-length squares in a list of 2d coordinates?

Given a list of 2d (x, y) coordinates, determine how many unit squares (edge length 1 unit) can be formed using the coordinates.

  • Input will be an array of 0 or more pairs of coordinates:
    e.g. in JavaScript: numofsq([[0,0], [1,0], [1,1], [0,1]])
  • No duplicate coordinates in input
  • Input order will be random (random 2d coordinates).
  • Coordinate form: [x-coordinate, y-coordinate] (duh)
  • Order of coordinates: [0,0], [1,0], [1,1], [0,1] and [0,0], [0,1], [1,1], [1,0] denote the same unit square (to be counted just once)
  • Coordinates can be negative or positive integers (duh)
  • Function will return just the number of unit squares possible, 0 or more.

Test cases:

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: Solution stuff here-onwards [JS]

Non-Golfed, quick and dirty, brute-force approach (included to provide some directions).

//cartesian distance functionfunction 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 coordinatesfunction 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 dovar 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 bitvar howManyUnitSquares = 0;squareQuads.map(function(quad) {    if (isUnitSquare(quad)) {        howManyUnitSquares++;    }});console.log(howManyUnitSquares);

//Cleaning up and putting those in-line stuff into a functionfunction 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;}

Viewing latest article 6
Browse Latest Browse All 6

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>