// File: /workspace/github_cpp_makefile_star2_O2/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
movq %rcx, -0x38(%rsp)
movl %esi, -0x54(%rsp)
movslq %esi, %rax
movq %rax, -0x50(%rsp)
cmpl $0x2, %edx
je 0x38d0
cmpl $0x1, %edx
je 0x3725
testl %edx, %edx
jne 0x3a5a
movq -0x38(%rsp), %rsi
movslq (%rsi), %rax
leaq (%rdi,%rax,4), %rcx
movl 0x4(%rsi), %r9d
movl %r9d, %edx
imull -0x54(%rsp), %edx
movslq %edx, %rdx
leaq (%rcx,%rdx,4), %r10
movslq 0xc(%rsi), %rsi
movq -0x50(%rsp), %r8
imulq %r8, %rsi
leaq (%rcx,%rsi,4), %rcx
movq %rcx, -0x30(%rsp)
leaq (,%r8,4), %r11
shlq $0x2, %rdx
leaq (%rdx,%rax,4), %rax
leaq (%rax,%rdi), %rcx
leaq (%rcx,%r8,4), %rbx
addq %rax, %rdi
addq $0x4, %rdi
xorl %eax, %eax
cmpq -0x30(%rsp), %r10
ja 0x3bf3
movq %rax, %rdx
movq -0x38(%rsp), %rax
movslq (%rax), %r15
movl %r9d, -0x40(%rsp)
movl %r9d, %r12d
imull -0x54(%rsp), %r12d
movslq 0x8(%rax), %rcx
movq %rdx, %rax
leaq (%r10,%rcx,4), %rsi
movq %r15, %rcx
shlq $0x2, %rcx
subq %rcx, %rsi
movq %rdi, -0x28(%rsp)
movq %r10, %r9
movq %rbx, -0x20(%rsp)
movq %r10, -0x48(%rsp)
cmpq %rsi, %r9
ja 0x36f4
cmpl $0x1, (%r9)
jne 0x36e0
leal (%r15,%r12), %ecx
incl %eax
movl %ecx, (%r9)
movq %rdi, %r13
movq %rbx, %rbp
movabsq $0x1, %r14
movq %r14, %rdx
imulq -0x50(%rsp), %rdx
leaq (%r9,%rdx,4), %r10
cmpl $0x1, (%r10,%r14,4)
jne 0x36e0
movq %r13, %r8
xorl %edx, %edx
cmpq %rdx, %r14
je 0x36b6
cmpl $0x1, (%rbp,%rdx,4)
jne 0x36e0
incq %rdx
cmpl $0x1, (%r8)
leaq (%r8,%r11), %r8
je 0x369b
jmp 0x36e0
movq %r13, %rdx
xorl %r8d, %r8d
cmpq %r8, %r14
je 0x36d0
movl %ecx, (%rbp,%r8,4)
movl %ecx, (%rdx)
incq %r8
addq %r11, %rdx
jmp 0x36bc
movl %ecx, (%r10,%r14,4)
incq %r14
addq %r11, %rbp
addq $0x4, %r13
jmp 0x3682
addq $0x4, %r9
incl %r15d
addq $0x4, %rbx
addq $0x4, %rdi
jmp 0x365a
movq %rax, %rcx
movq -0x50(%rsp), %rax
movq -0x48(%rsp), %r10
leaq (%r10,%rax,4), %r10
movq %rcx, %rax
movl -0x40(%rsp), %r9d
incl %r9d
movq -0x20(%rsp), %rbx
addq %r11, %rbx
movq -0x28(%rsp), %rdi
addq %r11, %rdi
jmp 0x360f
movq -0x38(%rsp), %rsi
movslq 0x8(%rsi), %rax
leaq (%rdi,%rax,4), %rcx
movl 0xc(%rsi), %r9d
movl %r9d, %edx
imull -0x54(%rsp), %edx
movslq %edx, %rdx
leaq (%rcx,%rdx,4), %r10
movslq 0x4(%rsi), %rsi
movq -0x50(%rsp), %r8
imulq %r8, %rsi
leaq (%rcx,%rsi,4), %rcx
movq %rcx, -0x18(%rsp)
movq %r8, %rcx
negq %rcx
movq %rcx, -0x8(%rsp)
shlq $0x2, %rdx
leaq (%rdx,%rax,4), %r11
movq %r10, %rdx
leaq (,%r8,4), %rbx
leaq (%rdi,%r11), %r13
addq $-0x4, %r13
subq %rbx, %r11
addq %rdi, %r11
negq %rbx
xorl %eax, %eax
cmpq -0x18(%rsp), %rdx
jb 0x3bf3
movq %rax, -0x40(%rsp)
movq -0x38(%rsp), %rax
movslq 0x8(%rax), %r12
movl %r9d, -0x20(%rsp)
movl %r9d, %ecx
imull -0x54(%rsp), %ecx
movq %rcx, -0x48(%rsp)
movslq (%rax), %rcx
leaq (%rdx,%rcx,4), %rax
movq %r12, %rcx
shlq $0x2, %rcx
subq %rcx, %rax
movq %r13, -0x30(%rsp)
movq %r11, -0x10(%rsp)
movq %rdx, -0x28(%rsp)
cmpq %rax, %rdx
jb 0x38a0
cmpl $0x1, (%rdx)
jne 0x388c
movq -0x48(%rsp), %rcx
leal (%r12,%rcx), %esi
movq -0x40(%rsp), %rcx
incl %ecx
movq %rcx, -0x40(%rsp)
movl %esi, (%rdx)
movq %r13, %r10
movq %r11, %r15
movabsq $0x1, %rbp
movq %rbp, %rcx
imulq -0x50(%rsp), %rcx
shlq $0x2, %rcx
movq %rdx, %r9
subq %rcx, %r9
leaq (,%rbp,4), %rcx
negq %rcx
cmpl $0x1, (%r9,%rcx)
jne 0x388c
movq %rbp, %rcx
negq %rcx
movq %r10, %r14
xorl %r8d, %r8d
movq %rbp, %rdi
addq %r8, %rdi
je 0x385f
cmpl $0x1, (%r15,%r8,4)
jne 0x388c
decq %r8
cmpl $0x1, (%r14)
leaq (%r14,%rbx), %r14
je 0x3841
jmp 0x388c
movq %r10, %r8
xorl %r14d, %r14d
movq %rbp, %rdi
addq %r14, %rdi
je 0x387c
movl %esi, (%r15,%r14,4)
movl %esi, (%r8)
decq %r14
addq %rbx, %r8
jmp 0x3865
movl %esi, (%r9,%rcx,4)
incq %rbp
addq %rbx, %r15
addq $-0x4, %r10
jmp 0x3810
addq $-0x4, %rdx
decl %r12d
addq $-0x4, %r11
addq $-0x4, %r13
jmp 0x37d7
movq -0x28(%rsp), %rdx
movq -0x8(%rsp), %rax
leaq (%rdx,%rax,4), %rdx
movl -0x20(%rsp), %r9d
decl %r9d
movq -0x10(%rsp), %r11
addq %rbx, %r11
movq -0x30(%rsp), %r13
addq %rbx, %r13
movq -0x40(%rsp), %rax
jmp 0x378c
movq -0x38(%rsp), %rsi
movslq (%rsi), %rax
leaq (%rdi,%rax,4), %rcx
movl 0xc(%rsi), %r9d
movl %r9d, %edx
imull -0x54(%rsp), %edx
movslq %edx, %rdx
leaq (%rcx,%rdx,4), %r11
movslq 0x4(%rsi), %rsi
movq -0x50(%rsp), %r8
imulq %r8, %rsi
leaq (%rcx,%rsi,4), %rcx
movq %rcx, -0x10(%rsp)
movq %r8, %rcx
negq %rcx
movq %rcx, -0x18(%rsp)
shlq $0x2, %rdx
leaq (%rdx,%rax,4), %r10
leaq (,%r8,4), %rbx
leaq (%rdi,%r10), %r14
addq $0x4, %r14
subq %rbx, %r10
addq %rdi, %r10
negq %rbx
xorl %eax, %eax
cmpq -0x10(%rsp), %r11
jb 0x3bf3
movq %rax, %rcx
movq -0x38(%rsp), %rax
movslq (%rax), %r12
movl %r9d, -0x48(%rsp)
movl %r9d, %edx
imull -0x54(%rsp), %edx
movq %rdx, -0x40(%rsp)
movslq 0x8(%rax), %rax
leaq (%r11,%rax,4), %rbp
movq %r12, %rax
shlq $0x2, %rax
subq %rax, %rbp
movq %rcx, %rax
movq %r14, -0x28(%rsp)
movq %r10, -0x30(%rsp)
movq %r11, -0x20(%rsp)
cmpq %rbp, %r11
ja 0x3a2f
cmpl $0x1, (%r11)
jne 0x3a1b
movq -0x40(%rsp), %rcx
addl %r12d, %ecx
incl %eax
movq %rax, %r13
movl %ecx, (%r11)
movq %r14, %rsi
movq %r10, %r15
movabsq $0x1, %rdi
movq %rdi, %rax
imulq -0x50(%rsp), %rax
shlq $0x2, %rax
movq %r11, %r9
subq %rax, %r9
cmpl $0x1, (%r9,%rdi,4)
jne 0x3a18
movq %rsi, %r8
xorl %edx, %edx
movq %r13, %rax
cmpq %rdx, %rdi
je 0x39ef
cmpl $0x1, (%r15,%rdx,4)
jne 0x3a1b
incq %rdx
cmpl $0x1, (%r8)
leaq (%r8,%rbx), %r8
je 0x39d4
jmp 0x3a1b
movq %rsi, %rdx
xorl %r8d, %r8d
cmpq %r8, %rdi
je 0x3a08
movl %ecx, (%r15,%r8,4)
movl %ecx, (%rdx)
incq %r8
addq %rbx, %rdx
jmp 0x39f5
movl %ecx, (%r9,%rdi,4)
incq %rdi
addq %rbx, %r15
addq $0x4, %rsi
jmp 0x39b2
movq %r13, %rax
addq $0x4, %r11
incl %r12d
addq $0x4, %r10
addq $0x4, %r14
jmp 0x397f
movq -0x20(%rsp), %r11
movq -0x18(%rsp), %rcx
leaq (%r11,%rcx,4), %r11
movl -0x48(%rsp), %r9d
decl %r9d
movq -0x30(%rsp), %r10
addq %rbx, %r10
movq -0x28(%rsp), %r14
addq %rbx, %r14
jmp 0x3933
movq -0x38(%rsp), %rsi
movslq 0x8(%rsi), %rax
leaq (%rdi,%rax,4), %rcx
movl 0x4(%rsi), %r9d
movq -0x50(%rsp), %r8
movl %r8d, %edx
imull %r9d, %edx
movslq %edx, %rdx
leaq (%rcx,%rdx,4), %r10
movslq 0xc(%rsi), %rsi
imulq %r8, %rsi
leaq (%rcx,%rsi,4), %rcx
movq %rcx, -0x18(%rsp)
leaq (,%r8,4), %r11
shlq $0x2, %rdx
leaq (%rdx,%rax,4), %rax
leaq (%rax,%rdi), %rcx
leaq (%rcx,%r8,4), %rbx
addq %rax, %rdi
addq $-0x4, %rdi
xorl %eax, %eax
cmpq -0x18(%rsp), %r10
ja 0x3bf3
movq %rax, %r13
movq -0x38(%rsp), %rax
movslq 0x8(%rax), %r15
movl %r9d, -0x20(%rsp)
movl %r9d, %ecx
imull -0x54(%rsp), %ecx
movq %rcx, -0x40(%rsp)
movslq (%rax), %rax
leaq (%r10,%rax,4), %rcx
movq %r15, %rax
shlq $0x2, %rax
subq %rax, %rcx
movq %rdi, -0x10(%rsp)
movq %r10, %r9
movq %rbx, -0x30(%rsp)
movq %r10, -0x28(%rsp)
movq %rcx, -0x48(%rsp)
cmpq %rcx, %r9
jb 0x3bc5
cmpl $0x1, (%r9)
jne 0x3bb1
movq -0x40(%rsp), %rax
leal (%r15,%rax), %ecx
incl %r13d
movl %ecx, (%r9)
movq %rdi, %rsi
movq %rbx, %rbp
movabsq $0x1, %r14
movq %r14, %rax
imulq -0x50(%rsp), %rax
leaq (%r9,%rax,4), %r10
leaq (,%r14,4), %rax
movq %r10, %rdx
subq %rax, %rdx
cmpl $0x1, (%rdx)
jne 0x3bac
movq %r14, %rdx
negq %rdx
movq %rsi, %r8
xorl %r12d, %r12d
movq %r14, %rax
addq %r12, %rax
je 0x3b7e
cmpl $0x1, (%rbp,%r12,4)
jne 0x3bac
decq %r12
cmpl $0x1, (%r8)
leaq (%r8,%r11), %r8
je 0x3b5f
jmp 0x3bac
movq %rsi, %r8
xorl %r12d, %r12d
movq %r14, %rax
addq %r12, %rax
je 0x3b9c
movl %ecx, (%rbp,%r12,4)
movl %ecx, (%r8)
decq %r12
addq %r11, %r8
jmp 0x3b84
movl %ecx, (%r10,%rdx,4)
incq %r14
addq %r11, %rbp
addq $-0x4, %rsi
jmp 0x3b33
movq -0x48(%rsp), %rcx
addq $-0x4, %r9
decl %r15d
addq $-0x4, %rbx
addq $-0x4, %rdi
jmp 0x3b01
movq -0x50(%rsp), %rax
movq -0x28(%rsp), %r10
leaq (%r10,%rax,4), %r10
movq %r13, %rax
movl -0x20(%rsp), %r9d
incl %r9d
movq -0x30(%rsp), %rbx
addq %r11, %rbx
movq -0x10(%rsp), %rdi
addq %r11, %rdi
jmp 0x3ab0
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq