// File: /workspace/github_cpp_makefile_star2_O3/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
movl %esi, -0x3c(%rsp)
cmpl $0x2, %edx
movq %rcx, -0x10(%rsp)
je 0x445f
cmpl $0x1, %edx
je 0x42cb
testl %edx, %edx
jne 0x45dd
movl 0x4(%rcx), %r10d
movl %r10d, %eax
movl -0x3c(%rsp), %edx
imull %edx, %eax
movslq 0xc(%rcx), %r9
movslq %edx, %r8
imulq %r8, %r9
cmpl %r9d, %eax
jg 0x45fb
movslq (%rcx), %rdx
leaq (%rdi,%rdx,4), %rsi
leaq (%rsi,%r9,4), %r9
movq %r9, -0x30(%rsp)
cltq
leaq (%rsi,%rax,4), %r13
shlq $0x2, %rax
leaq (%rax,%rdx,4), %rax
leaq (%rdi,%rax), %r12
addq $0x4, %r12
leaq (,%r8,4), %r11
xorl %eax, %eax
movslq (%rcx), %rbx
movslq 0x8(%rcx), %rcx
leaq (,%rcx,4), %r14
addq %r13, %r14
leaq (,%rbx,4), %rcx
subq %rcx, %r14
cmpq %r14, %r13
movl %r10d, -0x38(%rsp)
movq %r13, -0x20(%rsp)
movq %r12, -0x28(%rsp)
ja 0x429c
movl %r10d, %r15d
imull -0x3c(%rsp), %r15d
cmpl $0x1, (%r13)
jne 0x4289
leal (%rbx,%r15), %esi
incl %eax
movl %esi, (%r13)
cmpl $0x1, 0x4(%r13,%r8,4)
jne 0x4289
leaq (,%r8,4), %rbp
addq %r13, %rbp
leaq 0x4(,%r8,4), %r9
addq %r13, %r9
movl $0x1, %edx
movq %r12, %rdi
movq %rdi, %rcx
xorl %r10d, %r10d
cmpl $0x1, (%rbp,%r10,4)
jne 0x4289
cmpl $0x1, (%rcx)
jne 0x4289
incq %r10
addq %r11, %rcx
cmpq %r10, %rdx
jne 0x4228
movq %rdi, %rcx
xorl %r10d, %r10d
movl %esi, (%rbp,%r10,4)
movl %esi, (%rcx)
incq %r10
addq %r11, %rcx
cmpq %r10, %rdx
jne 0x4246
movl %esi, (%r9)
leaq 0x1(%rdx), %rcx
movq %rcx, %r9
imulq %r8, %r9
leaq (,%r9,4), %rbp
addq %r13, %rbp
leaq 0x4(,%rdx,4), %r9
addq %rbp, %r9
addq $0x4, %rdi
cmpl $0x1, (%r9)
movq %rcx, %rdx
je 0x4222
addq $0x4, %r13
incl %ebx
addq $0x4, %r12
cmpq %r14, %r13
jbe 0x41e3
movq -0x20(%rsp), %r13
leaq (%r13,%r8,4), %r13
movl -0x38(%rsp), %r10d
incl %r10d
movq -0x28(%rsp), %r12
addq %r11, %r12
cmpq -0x30(%rsp), %r13
movq -0x10(%rsp), %rcx
jbe 0x41a5
jmp 0x45fd
movl 0xc(%rcx), %r9d
movl %r9d, %eax
movl -0x3c(%rsp), %edx
imull %edx, %eax
movslq 0x4(%rcx), %r8
movslq %edx, %r10
imulq %r10, %r8
cmpl %r8d, %eax
jl 0x45fb
movslq 0x8(%rcx), %rdx
leaq (%rdi,%rdx,4), %rsi
leaq (%rsi,%r8,4), %r8
movq %r8, -0x8(%rsp)
cltq
leaq (%rsi,%rax,4), %rbp
movq %r10, %r11
negq %r11
shlq $0x2, %rax
leaq (%rax,%rdx,4), %rax
leaq (%rdi,%rax), %r13
addq $-0x4, %r13
movq %r10, -0x18(%rsp)
leaq (,%r10,4), %rbx
negq %rbx
xorl %eax, %eax
movslq 0x8(%rcx), %r14
movslq (%rcx), %rcx
leaq (,%rcx,4), %r15
addq %rbp, %r15
leaq (,%r14,4), %rcx
subq %rcx, %r15
cmpq %r15, %rbp
movl %r9d, -0x20(%rsp)
movq %rbp, -0x28(%rsp)
movq %r13, -0x30(%rsp)
jb 0x4430
movl %r9d, %ecx
imull -0x3c(%rsp), %ecx
movq %rcx, -0x38(%rsp)
cmpl $0x1, (%rbp)
jne 0x441c
leal (%r14,%rcx), %r9d
incl %eax
movl %r9d, (%rbp)
cmpl $0x1, -0x4(%rbp,%r11,4)
jne 0x441c
leaq (,%r11,4), %rcx
addq %rbp, %rcx
leaq -0x4(,%r11,4), %rdi
addq %rbp, %rdi
movl $0x1, %esi
movq $-0x1, %r8
movq %r13, %r12
xorl %r10d, %r10d
movq %r12, %rdx
cmpl $0x1, (%rcx,%r10,4)
jne 0x4417
cmpl $0x1, (%rdx)
jne 0x4417
addq %rbx, %rdx
decq %r10
cmpq %r10, %r8
jne 0x43b9
xorl %edx, %edx
movq %r12, %r10
movl %r9d, (%rcx,%rdx,4)
movl %r9d, (%r10)
addq %rbx, %r10
decq %rdx
cmpq %rdx, %r8
jne 0x43d5
movl %r9d, (%rdi)
movq %rsi, %rdx
notq %rdx
incq %rsi
movq %rdx, %rcx
imulq -0x18(%rsp), %rcx
leaq (,%rcx,4), %rcx
addq %rbp, %rcx
leaq (%rcx,%rdx,4), %rdi
addq $-0x4, %r12
decq %r8
cmpl $0x1, (%rdi)
je 0x43b3
movq -0x38(%rsp), %rcx
addq $-0x4, %rbp
decl %r14d
addq $-0x4, %r13
cmpq %r15, %rbp
jae 0x436e
movq -0x28(%rsp), %rbp
leaq (%rbp,%r11,4), %rbp
movl -0x20(%rsp), %r9d
decl %r9d
movq -0x30(%rsp), %r13
addq %rbx, %r13
cmpq -0x8(%rsp), %rbp
movq -0x10(%rsp), %rcx
jae 0x432c
jmp 0x45fd
movl 0xc(%rcx), %r9d
movl %r9d, %eax
movl -0x3c(%rsp), %edx
imull %edx, %eax
movslq 0x4(%rcx), %r8
movslq %edx, %r10
imulq %r10, %r8
cmpl %r8d, %eax
jl 0x45fb
movslq (%rcx), %rdx
leaq (%rdi,%rdx,4), %rsi
leaq (%rsi,%r8,4), %r8
movq %r8, -0x18(%rsp)
cltq
leaq (%rsi,%rax,4), %rbp
movq %r10, %r11
negq %r11
shlq $0x2, %rax
leaq (%rax,%rdx,4), %rax
leaq (%rdi,%rax), %r13
addq $0x4, %r13
movq %r10, -0x30(%rsp)
leaq (,%r10,4), %rbx
negq %rbx
xorl %eax, %eax
movslq (%rcx), %r14
movslq 0x8(%rcx), %rcx
leaq (,%rcx,4), %r15
addq %rbp, %r15
leaq (,%r14,4), %rcx
subq %rcx, %r15
cmpq %r15, %rbp
movl %r9d, -0x38(%rsp)
movq %rbp, -0x20(%rsp)
movq %r13, -0x28(%rsp)
ja 0x45b1
movl %r9d, %r12d
imull -0x3c(%rsp), %r12d
cmpl $0x1, (%rbp)
jne 0x459d
leal (%r14,%r12), %esi
incl %eax
movl %esi, (%rbp)
cmpl $0x1, 0x4(%rbp,%r11,4)
jne 0x459d
leaq (,%r11,4), %r8
addq %rbp, %r8
leaq 0x4(,%r11,4), %rdx
addq %rbp, %rdx
movl $0x1, %ecx
movq %r13, %rdi
movq %rdi, %r9
xorl %r10d, %r10d
cmpl $0x1, (%r8,%r10,4)
jne 0x459d
cmpl $0x1, (%r9)
jne 0x459d
incq %r10
addq %rbx, %r9
cmpq %r10, %rcx
jne 0x4540
movq %rdi, %r9
xorl %r10d, %r10d
movl %esi, (%r8,%r10,4)
movl %esi, (%r9)
incq %r10
addq %rbx, %r9
cmpq %r10, %rcx
jne 0x455e
movl %esi, (%rdx)
movq %rcx, %rdx
notq %rdx
imulq -0x30(%rsp), %rdx
leaq (,%rdx,4), %r8
addq %rbp, %r8
leaq (%r8,%rcx,4), %rdx
addq $0x4, %rdx
incq %rcx
addq $0x4, %rdi
cmpl $0x1, (%rdx)
je 0x453a
addq $0x4, %rbp
incl %r14d
addq $0x4, %r13
cmpq %r15, %rbp
jbe 0x44fd
movq -0x20(%rsp), %rbp
leaq (%rbp,%r11,4), %rbp
movl -0x38(%rsp), %r9d
decl %r9d
movq -0x28(%rsp), %r13
addq %rbx, %r13
cmpq -0x18(%rsp), %rbp
movq -0x10(%rsp), %rcx
jae 0x44bf
jmp 0x45fd
movl 0x4(%rcx), %r10d
movl %r10d, %eax
movl -0x3c(%rsp), %edx
imull %edx, %eax
movslq 0xc(%rcx), %r9
movslq %edx, %r8
imulq %r8, %r9
cmpl %r9d, %eax
jle 0x4608
xorl %eax, %eax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movslq 0x8(%rcx), %rdx
leaq (%rdi,%rdx,4), %rsi
leaq (%rsi,%r9,4), %r9
movq %r9, -0x18(%rsp)
cltq
leaq (%rsi,%rax,4), %r13
shlq $0x2, %rax
leaq (%rax,%rdx,4), %rax
leaq (%rdi,%rax), %r12
addq $-0x4, %r12
leaq (,%r8,4), %r11
xorl %eax, %eax
movslq 0x8(%rcx), %rbx
movslq (%rcx), %rcx
leaq (,%rcx,4), %r14
addq %r13, %r14
leaq (,%rbx,4), %rcx
subq %rcx, %r14
cmpq %r14, %r13
movl %r10d, -0x20(%rsp)
movq %r13, -0x28(%rsp)
movq %r12, -0x30(%rsp)
jb 0x473a
movl %r10d, %ecx
imull -0x3c(%rsp), %ecx
movq %rcx, -0x38(%rsp)
cmpl $0x1, (%r13)
jne 0x4727
leal (%rbx,%rcx), %esi
incl %eax
movl %esi, (%r13)
cmpl $0x1, -0x4(%r13,%r8,4)
jne 0x4727
leaq (,%r8,4), %r9
addq %r13, %r9
leaq -0x4(,%r8,4), %rdx
addq %r13, %rdx
movl $0x1, %edi
movq $-0x1, %rbp
movq %r12, %r15
xorl %r10d, %r10d
movq %r15, %rcx
cmpl $0x1, (%r9,%r10,4)
jne 0x4722
cmpl $0x1, (%rcx)
jne 0x4722
addq %r11, %rcx
decq %r10
cmpq %r10, %rbp
jne 0x46c6
xorl %ecx, %ecx
movq %r15, %r10
movl %esi, (%r9,%rcx,4)
movl %esi, (%r10)
addq %r11, %r10
decq %rcx
cmpq %rcx, %rbp
jne 0x46e2
movl %esi, (%rdx)
leaq 0x1(%rdi), %rcx
movq %rcx, %rdx
imulq %r8, %rdx
leaq (,%rdx,4), %r9
addq %r13, %r9
notq %rdi
leaq (%r9,%rdi,4), %rdx
addq $-0x4, %r15
decq %rbp
cmpl $0x1, (%rdx)
movq %rcx, %rdi
je 0x46c0
movq -0x38(%rsp), %rcx
addq $-0x4, %r13
decl %ebx
addq $-0x4, %r12
cmpq %r14, %r13
jae 0x467b
movq -0x28(%rsp), %r13
leaq (%r13,%r8,4), %r13
movl -0x20(%rsp), %r10d
incl %r10d
movq -0x30(%rsp), %r12
addq %r11, %r12
cmpq -0x18(%rsp), %r13
movq -0x10(%rsp), %rcx
jbe 0x4639
jmp 0x45fd
nop