// File: /workspace/github_cpp_makefile_star2_O1/estan[P]tsp/tsp.cpp
// Function: std::vector<unsigned short, std::allocator<unsigned short>> approximate<std::chrono::_V2::system_clock>(std::istream&, std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::_V2::system_clock::duration> const&)
vector<uint16_t> approximate(istream &in, const chrono::time_point<T>& deadline) {
    /*
     * Initialization.
     */

    // Deadline for 3-opt inside main loop is 50 ms before hard deadline.
    chrono::milliseconds fifty_ms(50);
    auto threeOptDeadline = deadline - fifty_ms;

    // Calculate distance / K-nearest neighbors matrix.
    const Matrix<uint32_t> d = createDistanceMatrix(in);
    const Matrix<uint16_t> neighbor = createNeighborsMatrix(d, MAX_K);
    const uint32_t min = minDistance(d); // Shortest distance.
    const size_t N = d.rows();           // Number of cities.

    // Generate initial greedy tour.
    vector<uint16_t> tour = greedy(d);

    // Create max / position for initial 2-opt + 3-opt.
    vector<uint16_t> position(N);
    uint32_t max = 0;
    for (uint16_t i = 0; i < N; ++i) {
        max = std::max(max, d[i][(i + 1) % N]); // Maximum distance in tour.
        position[tour[i]] = i;                  // tour[i] is i:th city in tour.
    }

    /*
     * Main loop.
     *
     * We repeatedly
     *
     *   1) Optimize the tour with 2-opt + 3-opt.
     *   2) "Kick" the tour with a random 4-exchange.
     *
     * until only max(50, 2 * average iteration time) milliseconds remains
     * before deadline, and then pick the shortest tour we found.
     */

    // Some main loop statistics.
    size_t i = 0;                        // Number of iterations of main loop.
    chrono::milliseconds totalTime(0);   // Total time spent in main loop.
    chrono::milliseconds averageTime(0); // Average main loop iteration time.

    vector<uint16_t> shortestTour = tour;          // Best tour found.
    uint64_t shortestTourLength = length(tour, d); // Length of best tour found.

    for (i = 0; (now() + std::max(fifty_ms, 2 * averageTime)) < deadline; ++i) {
        auto start = now();

        // Optimize tour with 2-opt + 3-opt.
        twoOpt(tour, d, neighbor, position, max, min);
        threeOpt(tour, d, neighbor, position, max, min, threeOptDeadline);

        uint64_t tourLength = length(tour, d);
        if (tourLength < shortestTourLength) {
            // Shorter tour found.
            shortestTour = tour;
            shortestTourLength = tourLength;
        }

        if (N >= 8) {
            // Perform random 4-opt "double bridge" move.
            tour = doubleBridge(tour);
        } else {
            // Tiny tour, so just shuffle it instead.
            shuffle(tour.begin(), tour.end(), rng);
        }

        // Update max / position needed by fast 2/3-opt.
        max = 0;
        for (uint16_t j = 0; j < N; ++j) {
            max = std::max(max, d[tour[j]][tour[(j + 1) % N]]);
            position[tour[j]] = j;
        }

        // Collect statistics.
        totalTime += chrono::duration_cast<chrono::milliseconds>(now() - start);
        averageTime = totalTime / (i + 1);
    }

    LOG("Main Loop Statistics");
    LOG("  iterations: " << i);
    LOG("  totalTime: " << totalTime);
    LOG("  averageTime: " << averageTime);

    return shortestTour;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x40(%rsp)
movq $-0x2faf080, %rax       # imm = 0xFD050F80
movq %rdx, 0x98(%rsp)
addq (%rdx), %rax
movq %rax, 0x138(%rsp)
leaq 0x70(%rsp), %rbx
movq %rbx, %rdi
callq 0x23fb
leaq 0x140(%rsp), %rdi
movl $0x14, %edx
movq %rbx, %rsi
callq 0x25e2
movq 0x88(%rsp), %r12
testq %r12, %r12
je 0x2c24
movq 0x70(%rsp), %rax
movq 0x90(%rsp), %rcx
shlq $0x2, %rcx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %rdx, 0x30(%rsp)
xorl %edx, %edx
movslq %edx, %rsi
imulq %rcx, %rsi
addq %rax, %rsi
xorl %edi, %edi
cmpq %rdi, %rdx
je 0x2c12
movl (%rsi,%rdi,4), %r8d
movq 0x30(%rsp), %r9
cmpl %r9d, %r8d
cmovbl %r8d, %r9d
movq %r9, 0x30(%rsp)
incq %rdi
cmpq %rdi, %r12
jne 0x2bf8
incq %rdx
cmpq %r12, %rdx
jne 0x2bec
jmp 0x2c2e
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, 0x30(%rsp)
leaq 0x18(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x3544
leaq 0xe0(%rsp), %rdi
leaq 0xc0(%rsp), %rdx
movq %r12, %rsi
callq 0x2ae8
movl $0x0, 0x14(%rsp)
testq %r12, %r12
je 0x2cc5
movl 0x14(%rsp), %esi
movq 0x70(%rsp), %rdi
movq 0x90(%rsp), %r8
movq 0x18(%rsp), %r9
movl $0x1, %ecx
movq 0xe0(%rsp), %r10
xorl %r11d, %r11d
movzwl %r11w, %ebx
movq %r8, %rax
imulq %rbx, %rax
leaq (%rdi,%rax,4), %r14
movq %rcx, %rax
xorl %edx, %edx
divq %r12
movl (%r14,%rdx,4), %eax
cmpl %eax, %esi
cmovbel %eax, %esi
movl %esi, 0x14(%rsp)
movzwl -0x2(%r9,%rcx,2), %eax
movw %bx, (%r10,%rax,2)
incl %r11d
movzwl %cx, %eax
incq %rcx
cmpq %rax, %r12
ja 0x2c88
leaq 0x18(%rsp), %rsi
movq 0x40(%rsp), %rdi
callq 0x3692
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdi
subq %rsi, %rdi
je 0x2d3a
sarq %rdi
movq 0x70(%rsp), %r8
movq 0x90(%rsp), %r9
xorl %r14d, %r14d
cmpq $0x1, %rdi
movl $0x0, %r10d
sbbq %rdi, %r10
movl $0x1, %ecx
movzwl -0x2(%rsi,%rcx,2), %eax
imulq %r9, %rax
leaq (%r8,%rax,4), %r11
movq %rcx, %rax
xorl %edx, %edx
divq %rdi
movzwl (%rsi,%rdx,2), %eax
movl (%r11,%rax,4), %eax
addq %rax, %r14
leaq (%r10,%rcx), %rax
incq %rax
incq %rcx
cmpq $0x1, %rax
jne 0x2d08
jmp 0x2d3d
xorl %r14d, %r14d
callq 0x2040
addq $0x2faf080, %rax        # imm = 0x2FAF080
movq 0x98(%rsp), %rcx
cmpq (%rcx), %rax
jge 0x3289
movq $0x0, 0xa8(%rsp)
movq $0x0, 0xa0(%rsp)
movq %r12, 0x50(%rsp)
callq 0x2040
movq %rax, 0xf8(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x48(%rsp)
testq %rax, %rax
je 0x3054
movq 0x18(%rsp), %r9
movq 0x160(%rsp), %r15
movq %r14, 0x58(%rsp)
movq 0x140(%rsp), %rax
movq %rax, 0x108(%rsp)
movq 0xe0(%rsp), %rsi
movq 0x20(%rsp), %r10
subq %r9, %r10
sarq %r10
leaq -0x1(%r10), %rbp
movl $0x1, %edi
movb $0x1, %al
movl %eax, 0x3c(%rsp)
xorl %r8d, %r8d
movq 0x48(%rsp), %rax
movq %r10, 0xb0(%rsp)
movq %rbp, 0x100(%rsp)
cmpq %rax, %rdi
movl $0x0, %eax
cmovneq %rdi, %rax
testq %r15, %r15
je 0x3030
movq %rdi, 0x68(%rsp)
movq %r8, 0x60(%rsp)
movzwl (%r9,%r8,2), %edi
movq %rax, 0x110(%rsp)
movzwl (%r9,%rax,2), %ebp
movq %r15, %rax
imulq %rdi, %rax
movq 0x108(%rsp), %rdx
leaq (%rdx,%rax,2), %r11
movq 0x70(%rsp), %rcx
movq 0x90(%rsp), %rdx
movq %rdx, %rax
movq %rdi, 0x130(%rsp)
imulq %rdi, %rax
leaq (%rcx,%rax,4), %r10
movl 0x14(%rsp), %eax
movq %rax, 0xb8(%rsp)
movq %rdx, 0x120(%rsp)
movq %rdx, %rax
imulq %rbp, %rax
movq %rcx, 0x128(%rsp)
leaq (%rcx,%rax,4), %rax
movq %rax, 0x118(%rsp)
xorl %r8d, %r8d
movq 0x48(%rsp), %r13
movzwl (%r11,%r8,2), %eax
movq %rsi, %rdi
movzwl (%rsi,%rax,2), %esi
leaq 0x1(%rsi), %rax
movzwl (%r9,%rsi,2), %ebx
xorl %edx, %edx
divq %r13
cmpw %bx, %bp
je 0x2f19
movl %edx, %eax
movzwl (%r9,%rax,2), %edx
cmpw 0x130(%rsp), %dx
je 0x2f19
movl (%r10,%rbx,4), %r12d
movq 0x30(%rsp), %rax
leal (%r12,%rax), %r14d
movl (%r10,%rbp,4), %eax
movq 0xb8(%rsp), %r13
addl %eax, %r13d
cmpl %r13d, %r14d
ja 0x2f37
movzwl %dx, %edx
shll $0x2, %edx
movq 0x118(%rsp), %rcx
movl (%rcx,%rdx), %r14d
leal (%r14,%r12), %r13d
imulq 0x120(%rsp), %rbx
movq 0x128(%rsp), %rcx
leaq (%rcx,%rbx,4), %rbx
addl (%rdx,%rbx), %eax
cmpl %eax, %r13d
movq 0x48(%rsp), %r13
jb 0x2f49
incq %r8
cmpq %r8, %r15
movq %rdi, %rsi
jne 0x2e90
movq 0x50(%rsp), %r12
movq 0x58(%rsp), %r14
jmp 0x3026
movq 0x50(%rsp), %r12
movq 0x58(%rsp), %r14
movq %rdi, %rsi
jmp 0x3026
movq %rsi, %rax
movq 0x110(%rsp), %rcx
subq %rcx, %rax
movl $0x0, %edx
movq 0xb0(%rsp), %r10
cmovbq %r10, %rdx
leaq (%rax,%rdx), %r8
incq %r8
cmpq $0x2, %r8
movl $0xffff, %ebx           # imm = 0xFFFF
movq %rdi, %r13
movq 0x100(%rsp), %rbp
jb 0x2ff6
shrq %r8
cmpq $0x1, %r8
adcq $0x0, %r8
movq %rcx, %rax
andq %rbx, %rax
movl %eax, %edx
movq %rsi, %rdi
andq %rbx, %rdi
movl %edi, %r10d
movzwl (%r9,%rdx,2), %r11d
movzwl (%r9,%r10,2), %ebx
movw %bx, (%r9,%rdx,2)
movl $0xffff, %ebx           # imm = 0xFFFF
movw %r11w, (%r9,%r10,2)
movzwl (%r9,%rdx,2), %edx
movw %cx, (%r13,%rdx,2)
movzwl (%r9,%r10,2), %ecx
movq 0xb0(%rsp), %r10
movw %si, (%r13,%rcx,2)
incq %rax
xorl %edx, %edx
divq %r10
addq %rbp, %rdi
movq %rdx, %rcx
movq %rdi, %rax
xorl %edx, %edx
divq %r10
movq %rdx, %rsi
decq %r8
jne 0x2f90
cmpl %r14d, %r12d
cmoval %r12d, %r14d
movq 0xb8(%rsp), %rax
cmpl %r14d, %eax
cmoval %eax, %r14d
movl %r14d, 0x14(%rsp)
movl $0x0, 0x3c(%rsp)
movq 0x50(%rsp), %r12
movq 0x58(%rsp), %r14
movq %r13, %rsi
movq 0x68(%rsp), %rdi
movq 0x60(%rsp), %r8
incq %r8
incq %rdi
movq 0x48(%rsp), %rax
cmpq %rax, %r8
jne 0x2df5
testq %rax, %rax
je 0x3054
testb $0x1, 0x3c(%rsp)
je 0x2dab
leaq 0x138(%rsp), %rax
movq %rax, (%rsp)
leaq 0x18(%rsp), %rdi
leaq 0x70(%rsp), %rsi
leaq 0x140(%rsp), %rdx
leaq 0xe0(%rsp), %rcx
leaq 0x14(%rsp), %r8
movq 0x30(%rsp), %r9
callq 0x3711
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdi
subq %rsi, %rdi
je 0x30ee
sarq %rdi
movq 0x70(%rsp), %r8
movq 0x90(%rsp), %r9
cmpq $0x1, %rdi
movl $0x0, %r10d
sbbq %rdi, %r10
movl $0x1, %ecx
xorl %ebx, %ebx
movzwl -0x2(%rsi,%rcx,2), %eax
imulq %r9, %rax
leaq (%r8,%rax,4), %r11
movq %rcx, %rax
xorl %edx, %edx
divq %rdi
movzwl (%rsi,%rdx,2), %eax
movl (%r11,%rax,4), %eax
addq %rax, %rbx
leaq (%r10,%rcx), %rax
incq %rax
incq %rcx
cmpq $0x1, %rax
jne 0x30bc
jmp 0x30f0
xorl %ebx, %ebx
cmpq %r14, %rbx
jae 0x3107
movq 0x40(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x4444
movq %rbx, %r14
cmpq $0x8, %r12
jb 0x3173
leaq 0xc0(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x4511
movq 0x18(%rsp), %rdi
movq 0xc0(%rsp), %rax
movq %rax, 0x18(%rsp)
movups 0xc8(%rsp), %xmm0
movups %xmm0, 0x20(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0xc0(%rsp)
movq $0x0, 0xd0(%rsp)
testq %rdi, %rdi
je 0x315f
callq 0x2150
movq 0xc0(%rsp), %rdi
testq %rdi, %rdi
je 0x3189
callq 0x2150
jmp 0x3189
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rsi
leaq 0x531c(%rip), %rdx      # 0x84a0
callq 0x461b
movl $0x0, 0x14(%rsp)
testq %r12, %r12
je 0x3200
movl 0x14(%rsp), %eax
movq 0x18(%rsp), %rcx
movq 0x70(%rsp), %rdx
movq 0x90(%rsp), %rsi
movl $0x1, %edi
movq 0xe0(%rsp), %r8
movzwl -0x2(%rcx,%rdi,2), %r9d
movq %rsi, %r10
imulq %r9, %r10
leaq (%rdx,%r10,4), %r10
cmpq %rdi, %r12
movl $0x0, %r11d
cmovneq %rdi, %r11
movzwl (%rcx,%r11,2), %r11d
movl (%r10,%r11,4), %r10d
cmpl %r10d, %eax
cmovbel %r10d, %eax
movl %eax, 0x14(%rsp)
leal -0x1(%rdi), %r10d
movw %r10w, (%r8,%r9,2)
movzwl %di, %r9d
incq %rdi
cmpq %r9, %r12
ja 0x31b9
callq 0x2040
subq 0xf8(%rsp), %rax
movabsq $0x431bde82d7b634db, %rcx # imm = 0x431BDE82D7B634DB
imulq %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x12, %rdx
addq %rax, %rdx
movq 0xa0(%rsp), %rcx
addq %rdx, %rcx
movq 0xa8(%rsp), %rsi
incq %rsi
movq %rcx, %rax
movq %rcx, 0xa0(%rsp)
xorl %edx, %edx
movq %rsi, 0xa8(%rsp)
divq %rsi
movq %rax, %rbx
callq 0x2040
addq %rbx, %rbx
cmpq $0x33, %rbx
movl $0x32, %ecx
cmovlq %rcx, %rbx
imulq $0xf4240, %rbx, %rcx    # imm = 0xF4240
addq %rax, %rcx
movq 0x98(%rsp), %rax
cmpq (%rax), %rcx
jl 0x2d76
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
je 0x329b
callq 0x2150
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x32aa
callq 0x2150
movq 0x140(%rsp), %rdi
testq %rdi, %rdi
je 0x32bc
callq 0x2150
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x32cb
callq 0x2150
movq 0x40(%rsp), %rax
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x330f
movq %rax, %rbx
jmp 0x3321
movq %rax, %rbx
jmp 0x3330
movq %rax, %rbx
jmp 0x3342
jmp 0x32fa
jmp 0x32fa
movq %rax, %rbx
movq 0x40(%rsp), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0x330f
callq 0x2150
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
je 0x3321
callq 0x2150
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x3330
callq 0x2150
movq 0x140(%rsp), %rdi
testq %rdi, %rdi
je 0x3342
callq 0x2150
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x3351
callq 0x2150
movq %rbx, %rdi
callq 0x21c0
nop