7

The following is a visual problem I came across today. The question here is simply how many squares there are in the picture.

How would you go about solving something like this though code ? Furthermore, if the actual picture isn't processed, how would you go about modelling it ?

squares puzzle

P.S: I sense that the actual resolution would require a rule to define what can be considered as a square. Something along the lines of saying that sides are equal in length and can be composed of any number of segments as long as they fit within the enclosing square. I'm not sure how you could represent a position though.

James P.
  • 19,313
  • 27
  • 97
  • 155
  • I see lots and lots of squares, but I suspect that many of them are just artifacts from using lossy JPEG compression instead of the more suitable PNG format. – Mark Byers Jul 25 '12 at 00:55
  • I see some very elusive little white squares at each intersection of black lines: when I try to focus on them, they disappear. – AnT stands with Russia Jul 25 '12 at 01:05
  • @MarkByers Yeah, sorry about the quality. It came off that social network where JPEG is often the norm. For the sake of the question only solid black lines should be considered. – James P. Jul 25 '12 at 01:08
  • Just from looking at it I think this is trick question. When you know what a quadtree or kd-tree or a space filling curve is then this symbol doesn't make any sense but only proof that you can sometimes mix counting and numbers. – Micromega Jul 25 '12 at 01:26
  • Are there not 40 squares? including each grouping of 4, it seems to me there is 1 4x4, 4 3x3, 9 2x2, 18 1x1, and 8 .5x.5 –  Jul 30 '12 at 15:56
  • I know this does not fully answer your question, but I think that this answer on SO might lead you in the right direction for what you are looking for: http://stackoverflow.com/a/11628969/337315 I believe that looking for the line segments from a starting point (say one of the corners) and then following the square, you can create a matrix in code based on your findings. Then you can derive from that matrix what the number of squares are. – CodeLikeBeaker Jul 25 '12 at 01:04

4 Answers4

1

Encoding: what you have is a network. Encode this as a network connecting nodes situated in a discrete two-dimensional space.

The question is really asking you to count the number of paths that meet the following properties:

  1. There are 3 turns
  2. The length between each such turn is equal
  3. The beginning and end of the path are the same.

A turn in this case is when either (a) if the previous move resulted in a change in the y-co-ordinate, this move results in a change in the x-co-ordinate; or (b) if the previous move resulted in a change in the x-co-ordinate, this move results in a change in the y-co-ordinate.

As to keeping track of the process: The best suggestions I've seen on this page are simply to iterate over each node, and for each such node to check all possible sizes of square. That should obviate the need to keep track any further.

If you have a smarter method, as long as your paths are always left-handed or always right-handed, each square is uniquely identified by the starting vertex, and length of side.

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • It is a network and I understand the approach. Do you have a suggestion for keeping track of the squares that have already been counted ? – James P. Jul 25 '12 at 15:28
  • 1
    @JamesPoulson The best suggestions I've seen on this page are simply to iterate over each node, and for each such node to check all possible sizes of square. That should obviate the need to keep track any further. If you have a smarter method, as long as your paths are always left-handed or always right-handed, each square is uniquely identified by the starting vertex, and length of side. – Marcin Jul 25 '12 at 17:13
  • @JamesPoulson Also, if you do finally code this, I encourage you to post it as an answer. – Marcin Jul 25 '12 at 17:14
  • 1
    Yes, can't promise anything in the upcoming weeks but I will post an answer if I get round to a solution through the answers that have been posted here. – James P. Jul 25 '12 at 20:54
1

If you can model this as a matrix, then the only information you need is the position of vertices. Then for every vertex check all the vertices in the same row and for each of found vertex check their column. then delete the processed vertex. Do the same column-wise. The worst case complexity would be n! (?)

I added the code for clarification.

public class SqFinder {
        int calculateSquares(int[][] vertices, int n) {
            int count = 0;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (vertices[i][j] == 1) {
                        for (int k = 1; k < n-j; k++) {
                            if (i + k < n && vertices[i][j+k] == 1 && vertices[i + k][j] == 1 && vertices[i + k][j + k] == 1)
                                count++;
                        }
                    }
                    vertices[i][j] =0;
                }
            }
            return count;
        }

        public static void main(String[] args) {
            SqFinder a = new SqFinder();
    //      int [][] test = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
            int [][] test = {{1,1,1},{1,1,1},{1,1,1}};
            System.out.println(a.calculateSquares(test, 3));
        }
    }
hashtpaa
  • 389
  • 2
  • 11
  • Either your explanation is too subtle for me, or it's incomprehensible. I'm pretty certain that it's the latter, as you don't even describe how to identify or count any squares. – Marcin Jul 25 '12 at 02:13
  • @Marcin : Identifying a square: lets say we are in row x. having two vertices in the same row in columns y and y+j .then there should be two other vertices in (x+j,y) and (x+j,y+j). In this case you would have a square. After counting all squares which include point (x,j) remove it to avoid redundancy. – hashtpaa Jul 25 '12 at 02:20
  • You do realise that by posting this comment you are merely demonstrating that your answer is incomplete? – Marcin Jul 25 '12 at 02:23
  • @Marcin : I added the code. I hope it is helpful. – hashtpaa Jul 25 '12 at 02:47
1

The simplest way would be to loop through every vertex, and check to see if it can be the upper-left vertex of a square of width 1, then of width 2, of 3, etc.

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
0

Something like this ought to do it:

int line_width = 1; //the width of the square line
int squares = 0;
for (int x = 0; x < width; ++x)
{
    for (int y = 0; y < height; ++y)
    {
        for (int size = line_width; x + size < width && y + size < height; ++x)
        {
            if (valid_square_at(x, y, x + size, y + size, line_width))
            {
                ++squares;
            }
        }
    }
}
return squares;

bool valid_square_at(x_0, y_0, x_1, y_1, width) 
{
    return valid_line(x_0, y_0, x_0_ x_1, width)
        && valid_line(x_0, y_0, x_1_ x_0, width)
        && valid_line(x_0, y_1, x_1_ x_1, width)
        && valid_line(x_1, y_0, x_1_ x_1, width);
}

bool valid_line(x_0, y_0, x_1, y_1, width) 
{
    //check that all pixel in that line are black...
}

Basically for every point in the picture, you check for every possible size of square, if a square of that size starts on that pixel. That's pretty easy since your squares are all "aligned" with the borders... The problem would be if they weren't...

Marcin
  • 48,559
  • 18
  • 128
  • 201
user1494736
  • 2,425
  • 16
  • 8
  • Is there a reason you chose not to use a representation of the figure? Once you have a representation, it's possible to do something other than brute force. – Marcin Jul 25 '12 at 02:09
  • What do you mean by the representation of the figure? Anyway, It's O(n^4)... It's not that bad... – user1494736 Jul 25 '12 at 02:12
  • I mean a representation of the figure that encodes the information in any way other than as a bitmap. – Marcin Jul 25 '12 at 02:13
  • If you use a representation, you have to check how your different figures "merge" (you may have 2 triangles that intercept ant they create a square). So you'll need to decode all to "lines" or "points" (If you allow curves you'll need to use "points")... And you'll need to implement a lot of cases, or render it to a bitmap to see how all the figures merge together.... So back to square one :) – user1494736 Jul 25 '12 at 02:19
  • It is possible to find cycles in a graph without rendering to a bitmap, or using anything like a triangle. – Marcin Jul 25 '12 at 02:22
  • a graph of graph theory? I don't understand what you mean – user1494736 Jul 25 '12 at 02:24