// File: /workspace/github_cpp_makefile_star2_O1/lioncedric[P]cimpressGridCoverage/src/squares.cc
// Function: solver(int*, int, int, int const*)
int solver(int * puzzle, const int width, int orientation, const int *const area) {
    int id;
    int nb_squares_used = 0;
    //code here was duplicated in order to gain performance
    if (orientation == 0) {
        int * ptrLineMin = puzzle + area[0] + area[1] * width;
        const int * ptrLineMax = puzzle + area[0] + area[3] * width;
        int row = area[1];

        for (int* ptrLine = ptrLineMin; ptrLine <= ptrLineMax; ptrLine += width, ++row) {
            int col = area[0];
            const int computed_line = row * width;
            const int * ptrColMax = ptrLine + area[2] - area[0];
            for (int* ptrCol = ptrLine; ptrCol <= ptrColMax; ++ptrCol, ++col) {

                if (*ptrCol == 1) {
                    id = computed_line + col;
                    ++nb_squares_used;
                    *ptrCol = id;
                    int size = 1;
                    while (true) {
                        bool stop = false;
                        int * ptrCol2 = ptrCol + size * width;
                        if (*(ptrCol2 + size) != 1)break;
                        for (int i = 0; i < size; ++i) {
                            if (*(ptrCol2 + i) != 1 || *(ptrCol + i * width + size) != 1) {
                                stop = true;
                                break;
                            }
                        }
                        if (stop) {
                            break;
                        }

                        for (int i = 0; i < size; ++i) {
                            *(ptrCol2 + i) = id;
                            *(ptrCol + i * width + size) = id;
                        }
                        *(ptrCol2 + size) = id;
                        ++size;
                    }
                }

            }

        }

    } else if (orientation == 1) {
        int * ptrLineMin = puzzle + area[2] + area[3] * width;
        const int * ptrLineMax = puzzle + area[2] + area[1] * width;
        int row = area[3];

        for (int* ptrLine = ptrLineMin; ptrLine >= ptrLineMax; ptrLine -= width, --row) {
            int col = area[2];
            const int computed_line = row * width;
            const int * ptrColMax = ptrLine + area[0] - area[2];
            for (int* ptrCol = ptrLine; ptrCol >= ptrColMax; --ptrCol, --col) {

                if (*ptrCol == 1) {
                    id = computed_line + col;
                    ++nb_squares_used;
                    *ptrCol = id;
                    int size = 1;
                    while (true) {
                        bool stop = false;
                        int * ptrCol2 = ptrCol - size * width;
                        if (*(ptrCol2 - size) != 1)break;
                        for (int i = 0; i < size; ++i) {
                            if (*(ptrCol2 - i) != 1 || *(ptrCol - i * width - size) != 1) {
                                stop = true;
                                break;
                            }
                        }
                        if (stop) {
                            break;
                        }

                        for (int i = 0; i < size; ++i) {
                            *(ptrCol2 - i) = id;
                            *(ptrCol - i * width - size) = id;
                        }
                        *(ptrCol2 - size) = id;
                        ++size;
                    }
                }

            }

        }
    } else if (orientation == 2) {
        int * ptrLineMin = puzzle + area[0] + area[3] * width;
        const int * ptrLineMax = puzzle + area[0] + area[1] * width;
        int row = area[3];

        for (int* ptrLine = ptrLineMin; ptrLine >= ptrLineMax; ptrLine -= width, --row) {
            int col = area[0];
            const int computed_line = row * width;
            const int * ptrColMax = ptrLine + area[2] - area[0];
            for (int* ptrCol = ptrLine; ptrCol <= ptrColMax; ++ptrCol, ++col) {

                if (*ptrCol == 1) {
                    id = computed_line + col;
                    ++nb_squares_used;
                    *ptrCol = id;
                    int size = 1;
                    while (true) {
                        bool stop = false;
                        int * ptrCol2 = ptrCol - size * width;
                        if (*(ptrCol2 + size) != 1)break;
                        for (int i = 0; i < size; ++i) {
                            if (*(ptrCol2 + i) != 1 || *(ptrCol - i * width + size) != 1) {
                                stop = true;
                                break;
                            }
                        }
                        if (stop) {
                            break;
                        }

                        for (int i = 0; i < size; ++i) {
                            *(ptrCol2 + i) = id;
                            *(ptrCol - i * width + size) = id;
                        }
                        *(ptrCol2 + size) = id;
                        ++size;
                    }
                }

            }

        }

    } else {
        int * ptrLineMin = puzzle + area[2] + area[1] * width;
        const int * ptrLineMax = puzzle + area[2] + area[3] * width;
        int row = area[1];

        for (int* ptrLine = ptrLineMin; ptrLine <= ptrLineMax; ptrLine += width, ++row) {
            int col = area[2];
            const int computed_line = row * width;
            const int * ptrColMax = ptrLine + area[0] - area[2];
            for (int* ptrCol = ptrLine; ptrCol >= ptrColMax; --ptrCol, --col) {

                if (*ptrCol == 1) {
                    id = computed_line + col;
                    ++nb_squares_used;
                    *ptrCol = id;
                    int size = 1;
                    while (true) {
                        bool stop = false;
                        int * ptrCol2 = ptrCol + size * width;
                        if (*(ptrCol2 - size) != 1)break;
                        for (int i = 0; i < size; ++i) {
                            if (*(ptrCol2 - i) != 1 || *(ptrCol + i * width - size) != 1) {
                                stop = true;
                                break;
                            }
                        }
                        if (stop) {
                            break;
                        }

                        for (int i = 0; i < size; ++i) {
                            *(ptrCol2 - i) = id;
                            *(ptrCol + i * width - size) = id;
                        }
                        *(ptrCol2 - size) = id;
                        ++size;
                    }
                }

            }

        }

    }


    return nb_squares_used;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
cmpl $0x2, %edx
movq %rcx, -0x10(%rsp)
je 0x4415
cmpl $0x1, %edx
je 0x42b1
testl %edx, %edx
jne 0x454f
movl 0x4(%rcx), %ebp
movl %ebp, %eax
imull %esi, %eax
movslq 0xc(%rcx), %r8
movslq %esi, %r11
imulq %r11, %r8
cmpl %r8d, %eax
jg 0x4569
movslq (%rcx), %rdx
leaq (%rdi,%rdx,4), %rdx
leaq (%rdx,%r8,4), %rdi
movq %rdi, -0x20(%rsp)
cltq
leaq (%rdx,%rax,4), %r9
leaq (,%r11,4), %r10
xorl %eax, %eax
movq %r11, -0x18(%rsp)
movslq (%rcx), %r11
movslq 0x8(%rcx), %rcx
leaq (%r9,%rcx,4), %rbx
leaq (,%r11,4), %rcx
subq %rcx, %rbx
cmpq %rbx, %r9
movl %ebp, -0x24(%rsp)
ja 0x428d
movl %ebp, %r14d
imull %esi, %r14d
movq %r9, %r15
cmpl $0x1, (%r15)
jne 0x427d
leal (%r11,%r14), %ebp
movl %ebp, (%r15)
movl $0x1, %r12d
movl %r12d, %ecx
imull %esi, %ecx
movslq %ecx, %rcx
leaq (%r15,%rcx,4), %r13
movslq %r12d, %rdi
cmpl $0x1, (%r13,%rdi,4)
jne 0x4275
testl %r12d, %r12d
jle 0x4248
movl %r12d, %ecx
leaq (%r15,%rdi,4), %r8
xorl %edx, %edx
cmpl $0x1, (%r13,%rdx,4)
jne 0x4275
cmpl $0x1, (%r8)
jne 0x4275
incq %rdx
addq %r10, %r8
cmpq %rdx, %rcx
jne 0x422f
testl %r12d, %r12d
jle 0x4269
movl %r12d, %ecx
leaq (%r15,%rdi,4), %rdx
xorl %r8d, %r8d
movl %ebp, (%r13,%r8,4)
movl %ebp, (%rdx)
incq %r8
addq %r10, %rdx
cmpq %r8, %rcx
jne 0x4257
movl %ebp, (%r13,%rdi,4)
incl %r12d
movb $0x1, %cl
jmp 0x4277
xorl %ecx, %ecx
testb %cl, %cl
jne 0x4209
incl %eax
addq $0x4, %r15
incl %r11d
cmpq %rbx, %r15
jbe 0x41f2
movq -0x18(%rsp), %r11
leaq (%r9,%r11,4), %r9
movl -0x24(%rsp), %ebp
incl %ebp
cmpq -0x20(%rsp), %r9
movq -0x10(%rsp), %rcx
jbe 0x41c5
jmp 0x456b
movl 0xc(%rcx), %r10d
movl %r10d, %eax
imull %esi, %eax
movslq 0x4(%rcx), %r9
movslq %esi, %r8
imulq %r8, %r9
cmpl %r9d, %eax
jl 0x4569
movslq 0x8(%rcx), %rdx
leaq (%rdi,%rdx,4), %rdx
leaq (%rdx,%r9,4), %rdi
movq %rdi, -0x20(%rsp)
cltq
leaq (%rdx,%rax,4), %r9
movq %r8, %rax
negq %rax
movq %rax, -0x8(%rsp)
shlq $0x2, %r8
negq %r8
xorl %eax, %eax
movslq 0x8(%rcx), %r11
movslq (%rcx), %rcx
leaq (%r9,%rcx,4), %rbx
leaq (,%r11,4), %rcx
subq %rcx, %rbx
cmpq %rbx, %r9
movl %r10d, -0x24(%rsp)
movq %r9, -0x18(%rsp)
jb 0x43ea
movl %r10d, %r14d
imull %esi, %r14d
cmpl $0x1, (%r9)
jne 0x43da
leal (%r11,%r14), %ebp
movl %ebp, (%r9)
movl $0x1, %r12d
movl %r12d, %ecx
imull %esi, %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
movq %r9, %r13
subq %rcx, %r13
movslq %r12d, %rdi
leaq (,%rdi,4), %r10
movq %r10, %rcx
negq %rcx
cmpl $0x1, (%r13,%rcx)
jne 0x43ce
testl %r12d, %r12d
jle 0x4399
movl %r12d, %edx
movq %r9, %r15
subq %r10, %r15
negq %rdx
xorl %ecx, %ecx
cmpl $0x1, (%r13,%rcx,4)
jne 0x43ce
cmpl $0x1, (%r15)
jne 0x43ce
addq %r8, %r15
decq %rcx
cmpq %rcx, %rdx
jne 0x4380
testl %r12d, %r12d
jle 0x43bf
movl %r12d, %edx
movq %r9, %r15
subq %r10, %r15
negq %rdx
xorl %ecx, %ecx
movl %ebp, (%r13,%rcx,4)
movl %ebp, (%r15)
addq %r8, %r15
decq %rcx
cmpq %rcx, %rdx
jne 0x43ac
negq %rdi
movl %ebp, (%r13,%rdi,4)
incl %r12d
movb $0x1, %dl
jmp 0x43d0
xorl %edx, %edx
testb %dl, %dl
jne 0x4341
incl %eax
addq $-0x4, %r9
decl %r11d
cmpq %rbx, %r9
jae 0x432a
movq -0x18(%rsp), %r9
movq -0x8(%rsp), %rcx
leaq (%r9,%rcx,4), %r9
movl -0x24(%rsp), %r10d
decl %r10d
cmpq -0x20(%rsp), %r9
movq -0x10(%rsp), %rcx
jae 0x42fa
jmp 0x456b
movl 0xc(%rcx), %r10d
movl %r10d, %eax
imull %esi, %eax
movslq 0x4(%rcx), %r9
movslq %esi, %r8
imulq %r8, %r9
cmpl %r9d, %eax
jl 0x4569
movslq (%rcx), %rdx
leaq (%rdi,%rdx,4), %rdx
leaq (%rdx,%r9,4), %rdi
movq %rdi, -0x18(%rsp)
cltq
leaq (%rdx,%rax,4), %r9
movq %r8, %rax
negq %rax
movq %rax, -0x20(%rsp)
shlq $0x2, %r8
negq %r8
xorl %eax, %eax
movslq (%rcx), %r11
movslq 0x8(%rcx), %rcx
leaq (%r9,%rcx,4), %rbx
leaq (,%r11,4), %rcx
subq %rcx, %rbx
cmpq %rbx, %r9
movl %r10d, -0x24(%rsp)
ja 0x452c
movl %r10d, %r14d
imull %esi, %r14d
movq %r9, %r15
cmpl $0x1, (%r15)
jne 0x451c
leal (%r11,%r14), %ebp
movl %ebp, (%r15)
movl $0x1, %r12d
movl %r12d, %ecx
imull %esi, %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
movq %r15, %r13
subq %rcx, %r13
movslq %r12d, %rdi
cmpl $0x1, (%r13,%rdi,4)
jne 0x4514
testl %r12d, %r12d
jle 0x44e7
movl %r12d, %ecx
leaq (%r15,%rdi,4), %r10
xorl %edx, %edx
cmpl $0x1, (%r13,%rdx,4)
jne 0x4514
cmpl $0x1, (%r10)
jne 0x4514
incq %rdx
addq %r8, %r10
cmpq %rdx, %rcx
jne 0x44ce
testl %r12d, %r12d
jle 0x4508
movl %r12d, %ecx
leaq (%r15,%rdi,4), %rdx
xorl %r10d, %r10d
movl %ebp, (%r13,%r10,4)
movl %ebp, (%rdx)
incq %r10
addq %r8, %rdx
cmpq %r10, %rcx
jne 0x44f6
movl %ebp, (%r13,%rdi,4)
incl %r12d
movb $0x1, %cl
jmp 0x4516
xorl %ecx, %ecx
testb %cl, %cl
jne 0x44a2
incl %eax
addq $0x4, %r15
incl %r11d
cmpq %rbx, %r15
jbe 0x448b
movq -0x20(%rsp), %rcx
leaq (%r9,%rcx,4), %r9
movl -0x24(%rsp), %r10d
decl %r10d
cmpq -0x18(%rsp), %r9
movq -0x10(%rsp), %rcx
jae 0x445d
jmp 0x456b
movl 0x4(%rcx), %r9d
movl %r9d, %eax
imull %esi, %eax
movslq 0xc(%rcx), %r8
movslq %esi, %r11
imulq %r11, %r8
cmpl %r8d, %eax
jle 0x4576
xorl %eax, %eax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movslq 0x8(%rcx), %rdx
leaq (%rdi,%rdx,4), %rdx
leaq (%rdx,%r8,4), %rdi
movq %rdi, -0x8(%rsp)
cltq
leaq (%rdx,%rax,4), %rdx
leaq (,%r11,4), %r10
xorl %eax, %eax
movq %r11, -0x20(%rsp)
movslq 0x8(%rcx), %r11
movslq (%rcx), %rcx
leaq (%rdx,%rcx,4), %rbx
leaq (,%r11,4), %rcx
subq %rcx, %rbx
cmpq %rbx, %rdx
movl %r9d, -0x24(%rsp)
movq %rdx, -0x18(%rsp)
jb 0x4686
movl %r9d, %r14d
imull %esi, %r14d
movq %rdx, %r9
cmpl $0x1, (%r9)
jne 0x4676
leal (%r11,%r14), %ebp
movl %ebp, (%r9)
movl $0x1, %r12d
movl %r12d, %ecx
imull %esi, %ecx
movslq %ecx, %rcx
leaq (%r9,%rcx,4), %r13
movslq %r12d, %rdi
leaq (,%rdi,4), %r8
movq %r13, %rcx
subq %r8, %rcx
cmpl $0x1, (%rcx)
jne 0x466a
testl %r12d, %r12d
jle 0x4635
movl %r12d, %ecx
movq %r9, %r15
subq %r8, %r15
negq %rcx
xorl %edx, %edx
cmpl $0x1, (%r13,%rdx,4)
jne 0x466a
cmpl $0x1, (%r15)
jne 0x466a
addq %r10, %r15
decq %rdx
cmpq %rdx, %rcx
jne 0x461c
testl %r12d, %r12d
jle 0x465b
movl %r12d, %ecx
movq %r9, %r15
subq %r8, %r15
negq %rcx
xorl %edx, %edx
movl %ebp, (%r13,%rdx,4)
movl %ebp, (%r15)
addq %r10, %r15
decq %rdx
cmpq %rdx, %rcx
jne 0x4648
negq %rdi
movl %ebp, (%r13,%rdi,4)
incl %r12d
movb $0x1, %cl
jmp 0x466c
xorl %ecx, %ecx
testb %cl, %cl
jne 0x45e6
incl %eax
addq $-0x4, %r9
decl %r11d
cmpq %rbx, %r9
jae 0x45cf
movq -0x20(%rsp), %r11
movq -0x18(%rsp), %rdx
leaq (%rdx,%r11,4), %rdx
movl -0x24(%rsp), %r9d
incl %r9d
cmpq -0x8(%rsp), %rdx
movq -0x10(%rsp), %rcx
jbe 0x459c
jmp 0x456b
nop