// File: lioncedric[P]cimpressGridCoverage/src/squares.cc
// Function: clear_squares(int*, int, int*, int*)
int clear_squares(int * puzzle, const int width, int * area, int * squares_removed) {
    int nb_squares_removed = 0;
    int first_col = area[0];
    int first_row = area[1];
    int last_col = area[2];
    int last_row = area[3];

    const int * ptrLineMax = puzzle + last_row * width;
    int row = first_row;
    for (int* ptrLine = puzzle + (first_row) * width; ptrLine <= ptrLineMax; ptrLine += width) {
        const int * ptrColMax = ptrLine + last_col;
        int col = first_col;
        for (int* ptrCol = ptrLine + first_col; ptrCol <= ptrColMax; ++ptrCol) {

            if (*ptrCol > 1) {
                const int id = *ptrCol;

                int size = 1;
                int xoffset = 0;
                int yoffset = 0;
                int* gridPos = ptrCol - width;

                while (*gridPos == id) {
                    gridPos -= width;
                    yoffset -= 1;
                }
                gridPos = ptrCol - 1;
                while (*gridPos == id) {
                    gridPos -= 1;
                    xoffset -= 1;
                }

                gridPos = ptrCol + 1 + width;
                while (*gridPos == id) {
                    gridPos += width + 1;
                    ++size;
                }

                size += (min(xoffset, yoffset)*-1);
                if (col + xoffset < area[0]) {
                    area[0] = col + xoffset;
                }
                if (row + yoffset < area[1]) {
                    area[1] = row + yoffset;
                }
                if (col + xoffset + size - 1 > area[2]) {
                    area[2] = col + xoffset + size - 1;
                }
                if (row + yoffset + size - 1 > area[3]) {
                    area[3] = row + yoffset + size - 1;
                }
                *squares_removed = col + xoffset;
                *(squares_removed + 1) = row + yoffset;
                *(squares_removed + 2) = size;
                clear_square(puzzle, width, squares_removed);
                ++nb_squares_removed;
                squares_removed += 3;
            }
            ++col;
        }
        ++row;
    }
    *squares_removed = -1;
    return nb_squares_removed;
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movl %esi, 0x7c(%rsp)
movq %rdx, 0x70(%rsp)
movq %rcx, 0x68(%rsp)
movl $0x0, 0x64(%rsp)
movq 0x70(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x60(%rsp)
movq 0x70(%rsp), %rax
movl 0x4(%rax), %eax
movl %eax, 0x5c(%rsp)
movq 0x70(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x58(%rsp)
movq 0x70(%rsp), %rax
movl 0xc(%rax), %eax
movl %eax, 0x54(%rsp)
movq 0x80(%rsp), %rax
movl 0x54(%rsp), %ecx
imull 0x7c(%rsp), %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x48(%rsp)
movl 0x5c(%rsp), %eax
movl %eax, 0x44(%rsp)
movq 0x80(%rsp), %rax
movl 0x5c(%rsp), %ecx
imull 0x7c(%rsp), %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
cmpq 0x48(%rsp), %rax
ja 0x11254
movq 0x38(%rsp), %rax
movslq 0x58(%rsp), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x30(%rsp)
movl 0x60(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0x38(%rsp), %rax
movslq 0x60(%rsp), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
cmpq 0x30(%rsp), %rax
ja 0x1122c
movq 0x20(%rsp), %rax
cmpl $0x1, (%rax)
jle 0x1120e
movq 0x20(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x1c(%rsp)
movl $0x1, 0x18(%rsp)
movl $0x0, 0x14(%rsp)
movl $0x0, 0x10(%rsp)
movq 0x20(%rsp), %rax
movslq 0x7c(%rsp), %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
movl (%rax), %eax
cmpl 0x1c(%rsp), %eax
jne 0x11073
movl 0x7c(%rsp), %ecx
movq 0x8(%rsp), %rax
movslq %ecx, %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x8(%rsp)
movl 0x10(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x1103c
movq 0x20(%rsp), %rax
addq $-0x4, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
movl (%rax), %eax
cmpl 0x1c(%rsp), %eax
jne 0x110a9
movq 0x8(%rsp), %rax
addq $-0x4, %rax
movq %rax, 0x8(%rsp)
movl 0x14(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x11081
movq 0x20(%rsp), %rax
addq $0x4, %rax
movslq 0x7c(%rsp), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
movl (%rax), %eax
cmpl 0x1c(%rsp), %eax
jne 0x110f8
movl 0x7c(%rsp), %ecx
addl $0x1, %ecx
movq 0x8(%rsp), %rax
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x8(%rsp)
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
jmp 0x110c3
leaq 0x14(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xb4e0
imull $-0x1, (%rax), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x2c(%rsp), %eax
addl 0x14(%rsp), %eax
movq 0x70(%rsp), %rcx
cmpl (%rcx), %eax
jge 0x11132
movl 0x2c(%rsp), %ecx
addl 0x14(%rsp), %ecx
movq 0x70(%rsp), %rax
movl %ecx, (%rax)
movl 0x44(%rsp), %eax
addl 0x10(%rsp), %eax
movq 0x70(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x11154
movl 0x44(%rsp), %ecx
addl 0x10(%rsp), %ecx
movq 0x70(%rsp), %rax
movl %ecx, 0x4(%rax)
movl 0x2c(%rsp), %eax
addl 0x14(%rsp), %eax
addl 0x18(%rsp), %eax
subl $0x1, %eax
movq 0x70(%rsp), %rcx
cmpl 0x8(%rcx), %eax
jle 0x11184
movl 0x2c(%rsp), %ecx
addl 0x14(%rsp), %ecx
addl 0x18(%rsp), %ecx
subl $0x1, %ecx
movq 0x70(%rsp), %rax
movl %ecx, 0x8(%rax)
movl 0x44(%rsp), %eax
addl 0x10(%rsp), %eax
addl 0x18(%rsp), %eax
subl $0x1, %eax
movq 0x70(%rsp), %rcx
cmpl 0xc(%rcx), %eax
jle 0x111b4
movl 0x44(%rsp), %ecx
addl 0x10(%rsp), %ecx
addl 0x18(%rsp), %ecx
subl $0x1, %ecx
movq 0x70(%rsp), %rax
movl %ecx, 0xc(%rax)
movl 0x2c(%rsp), %ecx
addl 0x14(%rsp), %ecx
movq 0x68(%rsp), %rax
movl %ecx, (%rax)
movl 0x44(%rsp), %ecx
addl 0x10(%rsp), %ecx
movq 0x68(%rsp), %rax
movl %ecx, 0x4(%rax)
movl 0x18(%rsp), %ecx
movq 0x68(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x80(%rsp), %rdi
movl 0x7c(%rsp), %esi
movq 0x68(%rsp), %rdx
callq 0x10e00
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
movq 0x68(%rsp), %rax
addq $0xc, %rax
movq %rax, 0x68(%rsp)
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
movq 0x20(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x20(%rsp)
jmp 0x10fe0
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
movl 0x7c(%rsp), %ecx
movq 0x38(%rsp), %rax
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x38(%rsp)
jmp 0x10f9c
movq 0x68(%rsp), %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movl 0x64(%rsp), %eax
addq $0x88, %rsp
retq
nopl (%rax,%rax)