// File: chuckwolber[P]Cube/test/test_algorithm.cpp
// Function: test_inversions()
void test_inversions() {
    std::cout << "Testing inversions... ";

    Algorithm alg_1({{Layer::L, true}, {Layer::F, true}});
   
    assert(!alg_1.hasInversion());
    alg_1 += 9;
    assert(alg_1.hasInversion());
    verify_turns(alg_1.getAlgorithm(), {{Layer::L, true}, {Layer::L, false}});

    Algorithm alg_2({{Layer::L, true}, {Layer::L, true}, {Layer::F, true}});
    assert(!alg_2.hasInversion());
    alg_2 += 12;
    assert(alg_2.hasInversion());
    verify_turns(alg_2.getAlgorithm(), 
                    {{Layer::L, true}, {Layer::L, false}, {Layer::F, true}});

    Algorithm alg_3({{Layer::F, true}, {Layer::F, false}}); 
    assert(alg_3.hasInversion());

    Algorithm alg_4({{Layer::F, false}, {Layer::F, true}}); 
    assert(alg_4.hasInversion());

    Algorithm alg_5({{Layer::B, true}, {Layer::B, false}}); 
    assert(alg_5.hasInversion());

    Algorithm alg_6({{Layer::B, false}, {Layer::B, true}}); 
    assert(alg_6.hasInversion());

    std::cout << "Passed" << std::endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3c0, %rsp            # imm = 0x3C0
movq 0xa736(%rip), %rdi      # 0x15fd8
leaq 0x4c2e(%rip), %rsi      # 0x104d7
callq 0x2190
movl $0x4, -0x60(%rbp)
movb $0x1, -0x5c(%rbp)
movl $0x5, -0x58(%rbp)
movb $0x1, -0x54(%rbp)
leaq -0x60(%rbp), %rax
movq %rax, -0x50(%rbp)
movq $0x2, -0x48(%rbp)
leaq -0x61(%rbp), %rdi
movq %rdi, -0x350(%rbp)
callq 0x51f0
movq -0x350(%rbp), %rcx
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
leaq -0x40(%rbp), %rdi
callq 0xf130
jmp 0xb8fe
leaq -0x28(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x2630
jmp 0xb90d
leaq -0x40(%rbp), %rdi
callq 0x4920
leaq -0x61(%rbp), %rdi
callq 0x54d0
leaq -0x28(%rbp), %rdi
callq 0x3530
movb %al, -0x351(%rbp)
jmp 0xb930
movb -0x351(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xb93e
jmp 0xb940
jmp 0xb9a1
leaq 0x4ba7(%rip), %rdi      # 0x104ee
leaq 0x498b(%rip), %rsi      # 0x102d9
movl $0x103, %edx            # imm = 0x103
leaq 0x4baa(%rip), %rcx      # 0x10504
callq 0x2100
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xb982
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x4920
leaq -0x61(%rbp), %rdi
callq 0x54d0
jmp 0xc2ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc2c1
leaq -0x28(%rbp), %rdi
movl $0x9, %esi
callq 0x2bd0
jmp 0xb9b1
leaq -0x28(%rbp), %rdi
callq 0x3530
movb %al, -0x352(%rbp)
jmp 0xb9c2
movb -0x352(%rbp), %al
testb $0x1, %al
jne 0xb9ce
jmp 0xb9d0
jmp 0xb9ef
leaq 0x4b18(%rip), %rdi      # 0x104ef
leaq 0x48fb(%rip), %rsi      # 0x102d9
movl $0x105, %edx            # imm = 0x105
leaq 0x4b1a(%rip), %rcx      # 0x10504
callq 0x2100
leaq -0x90(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x33e0
jmp 0xba01
movl $0x4, -0xc8(%rbp)
movb $0x1, -0xc4(%rbp)
movl $0x4, -0xc0(%rbp)
movb $0x0, -0xbc(%rbp)
leaq -0xc8(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq $0x2, -0xb0(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x51f0
movq -0x360(%rbp), %rcx
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rdx
leaq -0xa8(%rbp), %rdi
callq 0xf130
jmp 0xba72
leaq -0x90(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0xecb0
jmp 0xba87
leaq -0xa8(%rbp), %rdi
callq 0x4920
leaq -0xc9(%rbp), %rdi
callq 0x54d0
leaq -0x90(%rbp), %rdi
callq 0x4920
movabsq $0x100000005, %rax      # imm = 0x100000005
movq %rax, -0x130(%rbp)
movups 0x5235(%rip), %xmm0     # 0x10cf8
movaps %xmm0, -0x140(%rbp)
leaq -0x140(%rbp), %rax
movq %rax, -0x120(%rbp)
movq $0x3, -0x118(%rbp)
leaq -0x141(%rbp), %rdi
movq %rdi, -0x368(%rbp)
callq 0x51f0
movq -0x368(%rbp), %rcx
movq -0x120(%rbp), %rsi
movq -0x118(%rbp), %rdx
leaq -0x110(%rbp), %rdi
callq 0xf130
jmp 0xbb19
leaq -0xf8(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x2630
jmp 0xbb2e
leaq -0x110(%rbp), %rdi
callq 0x4920
leaq -0x141(%rbp), %rdi
callq 0x54d0
leaq -0xf8(%rbp), %rdi
callq 0x3530
movb %al, -0x369(%rbp)
jmp 0xbb5a
movb -0x369(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xbb68
jmp 0xbb6d
jmp 0xbc17
leaq 0x49a7(%rip), %rdi      # 0x1051b
leaq 0x475e(%rip), %rsi      # 0x102d9
movl $0x109, %edx            # imm = 0x109
leaq 0x497d(%rip), %rcx      # 0x10504
callq 0x2100
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xbbb2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x4920
leaq -0xc9(%rbp), %rdi
callq 0x54d0
leaq -0x90(%rbp), %rdi
callq 0x4920
jmp 0xc2c1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xbbf5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x4920
leaq -0x141(%rbp), %rdi
callq 0x54d0
jmp 0xc2c1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc2b5
leaq -0xf8(%rbp), %rdi
movl $0xc, %esi
callq 0x2bd0
jmp 0xbc2a
leaq -0xf8(%rbp), %rdi
callq 0x3530
movb %al, -0x36a(%rbp)
jmp 0xbc3e
movb -0x36a(%rbp), %al
testb $0x1, %al
jne 0xbc4a
jmp 0xbc4c
jmp 0xbc6b
leaq 0x48c9(%rip), %rdi      # 0x1051c
leaq 0x467f(%rip), %rsi      # 0x102d9
movl $0x10b, %edx            # imm = 0x10B
leaq 0x489e(%rip), %rcx      # 0x10504
callq 0x2100
leaq -0x160(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x33e0
jmp 0xbc80
movups 0x5089(%rip), %xmm0     # 0x10d10
movaps %xmm0, -0x1a0(%rbp)
movabsq $0x100000005, %rax      # imm = 0x100000005
movq %rax, -0x190(%rbp)
leaq -0x1a0(%rbp), %rax
movq %rax, -0x188(%rbp)
movq $0x3, -0x180(%rbp)
leaq -0x1a1(%rbp), %rdi
movq %rdi, -0x378(%rbp)
callq 0x51f0
movq -0x378(%rbp), %rcx
movq -0x188(%rbp), %rsi
movq -0x180(%rbp), %rdx
leaq -0x178(%rbp), %rdi
callq 0xf130
jmp 0xbcee
leaq -0x160(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0xecb0
jmp 0xbd03
leaq -0x178(%rbp), %rdi
callq 0x4920
leaq -0x1a1(%rbp), %rdi
callq 0x54d0
leaq -0x160(%rbp), %rdi
callq 0x4920
movl $0x5, -0x208(%rbp)
movb $0x1, -0x204(%rbp)
movl $0x5, -0x200(%rbp)
movb $0x0, -0x1fc(%rbp)
leaq -0x208(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq $0x2, -0x1f0(%rbp)
leaq -0x209(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x51f0
movq -0x380(%rbp), %rcx
movq -0x1f8(%rbp), %rsi
movq -0x1f0(%rbp), %rdx
leaq -0x1e8(%rbp), %rdi
callq 0xf130
jmp 0xbd98
leaq -0x1d0(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x2630
jmp 0xbdad
leaq -0x1e8(%rbp), %rdi
callq 0x4920
leaq -0x209(%rbp), %rdi
callq 0x54d0
leaq -0x1d0(%rbp), %rdi
callq 0x3530
movb %al, -0x381(%rbp)
jmp 0xbdd9
movb -0x381(%rbp), %al
testb $0x1, %al
jne 0xbde5
jmp 0xbdea
jmp 0xbe94
leaq 0x4740(%rip), %rdi      # 0x10531
leaq 0x44e1(%rip), %rsi      # 0x102d9
movl $0x110, %edx            # imm = 0x110
leaq 0x4700(%rip), %rcx      # 0x10504
callq 0x2100
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xbe2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x4920
leaq -0x1a1(%rbp), %rdi
callq 0x54d0
leaq -0x160(%rbp), %rdi
callq 0x4920
jmp 0xc2b5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xbe72
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x4920
leaq -0x209(%rbp), %rdi
callq 0x54d0
jmp 0xc2b5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc2a9
movl $0x5, -0x270(%rbp)
movb $0x0, -0x26c(%rbp)
movl $0x5, -0x268(%rbp)
movb $0x1, -0x264(%rbp)
leaq -0x270(%rbp), %rax
movq %rax, -0x260(%rbp)
movq $0x2, -0x258(%rbp)
leaq -0x271(%rbp), %rdi
movq %rdi, -0x390(%rbp)
callq 0x51f0
movq -0x390(%rbp), %rcx
movq -0x260(%rbp), %rsi
movq -0x258(%rbp), %rdx
leaq -0x250(%rbp), %rdi
callq 0xf130
jmp 0xbf05
leaq -0x238(%rbp), %rdi
leaq -0x250(%rbp), %rsi
callq 0x2630
jmp 0xbf1a
leaq -0x250(%rbp), %rdi
callq 0x4920
leaq -0x271(%rbp), %rdi
callq 0x54d0
leaq -0x238(%rbp), %rdi
callq 0x3530
movb %al, -0x391(%rbp)
jmp 0xbf46
movb -0x391(%rbp), %al
testb $0x1, %al
jne 0xbf52
jmp 0xbf54
jmp 0xbfbb
leaq 0x45eb(%rip), %rdi      # 0x10546
leaq 0x4377(%rip), %rsi      # 0x102d9
movl $0x113, %edx            # imm = 0x113
leaq 0x4596(%rip), %rcx      # 0x10504
callq 0x2100
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xbf99
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x250(%rbp), %rdi
callq 0x4920
leaq -0x271(%rbp), %rdi
callq 0x54d0
jmp 0xc2a9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc29d
movl $0x7, -0x2d8(%rbp)
movb $0x1, -0x2d4(%rbp)
movl $0x7, -0x2d0(%rbp)
movb $0x0, -0x2cc(%rbp)
leaq -0x2d8(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movq $0x2, -0x2c0(%rbp)
leaq -0x2d9(%rbp), %rdi
movq %rdi, -0x3a0(%rbp)
callq 0x51f0
movq -0x3a0(%rbp), %rcx
movq -0x2c8(%rbp), %rsi
movq -0x2c0(%rbp), %rdx
leaq -0x2b8(%rbp), %rdi
callq 0xf130
jmp 0xc02c
leaq -0x2a0(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
callq 0x2630
jmp 0xc041
leaq -0x2b8(%rbp), %rdi
callq 0x4920
leaq -0x2d9(%rbp), %rdi
callq 0x54d0
leaq -0x2a0(%rbp), %rdi
callq 0x3530
movb %al, -0x3a1(%rbp)
jmp 0xc06d
movb -0x3a1(%rbp), %al
testb $0x1, %al
jne 0xc079
jmp 0xc07b
jmp 0xc0e2
leaq 0x44d9(%rip), %rdi      # 0x1055b
leaq 0x4250(%rip), %rsi      # 0x102d9
movl $0x116, %edx            # imm = 0x116
leaq 0x446f(%rip), %rcx      # 0x10504
callq 0x2100
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc0c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x4920
leaq -0x2d9(%rbp), %rdi
callq 0x54d0
jmp 0xc29d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc291
movl $0x7, -0x340(%rbp)
movb $0x0, -0x33c(%rbp)
movl $0x7, -0x338(%rbp)
movb $0x1, -0x334(%rbp)
leaq -0x340(%rbp), %rax
movq %rax, -0x330(%rbp)
movq $0x2, -0x328(%rbp)
leaq -0x341(%rbp), %rdi
movq %rdi, -0x3b0(%rbp)
callq 0x51f0
movq -0x3b0(%rbp), %rcx
movq -0x330(%rbp), %rsi
movq -0x328(%rbp), %rdx
leaq -0x320(%rbp), %rdi
callq 0xf130
jmp 0xc153
leaq -0x308(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x2630
jmp 0xc168
leaq -0x320(%rbp), %rdi
callq 0x4920
leaq -0x341(%rbp), %rdi
callq 0x54d0
leaq -0x308(%rbp), %rdi
callq 0x3530
movb %al, -0x3b1(%rbp)
jmp 0xc194
movb -0x3b1(%rbp), %al
testb $0x1, %al
jne 0xc1a0
jmp 0xc1a2
jmp 0xc212
leaq 0x43c7(%rip), %rdi      # 0x10570
leaq 0x4129(%rip), %rsi      # 0x102d9
movl $0x119, %edx            # imm = 0x119
leaq 0x4348(%rip), %rcx      # 0x10504
callq 0x2100
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc1e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x4920
leaq -0x341(%rbp), %rdi
callq 0x54d0
jmp 0xc291
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x308(%rbp), %rdi
callq 0x4bd0
jmp 0xc291
movq 0x9dbf(%rip), %rdi      # 0x15fd8
leaq 0x4196(%rip), %rsi      # 0x103b6
callq 0x2190
movq %rax, -0x3c0(%rbp)
jmp 0xc22e
movq -0x3c0(%rbp), %rdi
movq 0x9d8c(%rip), %rsi      # 0x15fc8
callq 0x21c0
jmp 0xc243
leaq -0x308(%rbp), %rdi
callq 0x4bd0
leaq -0x2a0(%rbp), %rdi
callq 0x4bd0
leaq -0x238(%rbp), %rdi
callq 0x4bd0
leaq -0x1d0(%rbp), %rdi
callq 0x4bd0
leaq -0xf8(%rbp), %rdi
callq 0x4bd0
leaq -0x28(%rbp), %rdi
callq 0x4bd0
addq $0x3c0, %rsp            # imm = 0x3C0
popq %rbp
retq
leaq -0x2a0(%rbp), %rdi
callq 0x4bd0
leaq -0x238(%rbp), %rdi
callq 0x4bd0
leaq -0x1d0(%rbp), %rdi
callq 0x4bd0
leaq -0xf8(%rbp), %rdi
callq 0x4bd0
leaq -0x28(%rbp), %rdi
callq 0x4bd0
movq -0x70(%rbp), %rdi
callq 0x22a0
nopw %cs:(%rax,%rax)