// File: /workspace/github_cpp_makefile_star2_O3/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 0x23eb
leaq 0x140(%rsp), %rdi
movl $0x14, %edx
movq %rbx, %rsi
callq 0x262b
movq 0x88(%rsp), %r12
testq %r12, %r12
je 0x2c59
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 0x2c47
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 0x2c2d
incq %rdx
cmpq %r12, %rdx
jne 0x2c21
jmp 0x2c63
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, 0x30(%rsp)
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x394a
leaq 0xe0(%rsp), %rdi
leaq 0xc0(%rsp), %rdx
movq %r12, %rsi
callq 0x2b1a
movl $0x0, 0xc(%rsp)
testq %r12, %r12
je 0x2cfc
movq 0x70(%rsp), %rsi
movq 0x90(%rsp), %rdi
movq 0x10(%rsp), %r8
xorl %r9d, %r9d
movl $0x1, %ecx
movq 0xe0(%rsp), %r10
xorl %r11d, %r11d
movzwl %r9w, %ebx
movq %rdi, %rax
imulq %rbx, %rax
leaq (%rsi,%rax,4), %r14
movq %rcx, %rax
xorl %edx, %edx
divq %r12
movl (%r14,%rdx,4), %eax
cmpl %eax, %r11d
cmovbel %eax, %r11d
movl %r11d, 0xc(%rsp)
movzwl -0x2(%r8,%rcx,2), %eax
movw %bx, (%r10,%rax,2)
incl %r9d
movzwl %cx, %eax
incq %rcx
cmpq %rax, %r12
ja 0x2cbc
leaq 0x10(%rsp), %rsi
movq 0x40(%rsp), %rdi
callq 0x3aa0
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdi
subq %rsi, %rdi
je 0x2d71
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 0x2d3f
jmp 0x2d74
xorl %r14d, %r14d
callq 0x2040
addq $0x2faf080, %rax        # imm = 0x2FAF080
movq 0x98(%rsp), %rcx
cmpq (%rcx), %rax
jge 0x32cc
movq $0x0, 0xa8(%rsp)
movq $0x0, 0xa0(%rsp)
movq %r12, 0x48(%rsp)
callq 0x2040
movq %rax, 0xf8(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x10(%rsp), %r10
movq 0x18(%rsp), %r9
movq 0x140(%rsp), %rax
movq %rax, 0x108(%rsp)
movq 0x160(%rsp), %r13
movq 0xe0(%rsp), %rdi
subq %r10, %r9
sarq %r9
leaq -0x1(%r9), %r15
movb $0x1, %r11b
movl $0x1, %esi
xorl %r8d, %r8d
movq %r14, 0x50(%rsp)
movq %r9, 0xb0(%rsp)
movq %r15, 0x100(%rsp)
movq 0x68(%rsp), %rcx
cmpq %rcx, %r8
jae 0x2f6d
movq %rsi, %rax
xorl %edx, %edx
divq %rcx
testq %r13, %r13
je 0x3086
movl %r11d, 0x3c(%rsp)
movq %rsi, 0x60(%rsp)
movq %r8, 0x58(%rsp)
movzwl (%r10,%r8,2), %esi
movq %rdx, 0x110(%rsp)
movzwl (%r10,%rdx,2), %r8d
movq %r13, %rax
imulq %rsi, %rax
movq 0x108(%rsp), %rcx
leaq (%rcx,%rax,2), %rcx
movq 0x70(%rsp), %rdx
movq 0x90(%rsp), %r9
movq %r9, %rax
movq %rsi, 0x130(%rsp)
imulq %rsi, %rax
leaq (%rdx,%rax,4), %rbp
movl 0xc(%rsp), %eax
movq %rax, 0xb8(%rsp)
movq %r9, 0x120(%rsp)
movq %r9, %rax
imulq %r8, %rax
movq %rdx, 0x128(%rsp)
leaq (%rdx,%rax,4), %rax
movq %rax, 0x118(%rsp)
xorl %r9d, %r9d
movq 0x68(%rsp), %r15
movzwl (%rcx,%r9,2), %eax
movq %rdi, %rsi
movzwl (%rdi,%rax,2), %edi
leaq 0x1(%rdi), %rax
movzwl (%r10,%rdi,2), %r14d
xorl %edx, %edx
divq %r15
cmpw %r14w, %r8w
je 0x2f52
movl %edx, %eax
movzwl (%r10,%rax,2), %edx
cmpw 0x130(%rsp), %dx
je 0x2f52
movl (%rbp,%r14,4), %r12d
movq 0x30(%rsp), %rax
leal (%r12,%rax), %ebx
movl (%rbp,%r8,4), %eax
movq 0xb8(%rsp), %r15
addl %eax, %r15d
cmpl %r15d, %ebx
ja 0x2f8a
movzwl %dx, %edx
shll $0x2, %edx
movq 0x118(%rsp), %r11
movl (%r11,%rdx), %ebx
leal (%rbx,%r12), %r15d
imulq 0x120(%rsp), %r14
movq 0x128(%rsp), %r11
leaq (%r11,%r14,4), %r14
addl (%rdx,%r14), %eax
cmpl %eax, %r15d
movq 0x68(%rsp), %r15
jb 0x2fab
incq %r9
cmpq %r9, %r13
movq %rsi, %rdi
jne 0x2ec5
movq 0x48(%rsp), %r12
movq 0x50(%rsp), %r14
jmp 0x2f97
movl $0x1, %esi
movl $0x0, %r8d
testb $0x1, %r11b
movb $0x1, %r11b
je 0x2e1b
jmp 0x3091
movq 0x48(%rsp), %r12
movq 0x50(%rsp), %r14
movq %rsi, %rdi
movq 0x60(%rsp), %rsi
movq 0x58(%rsp), %r8
movl 0x3c(%rsp), %r11d
jmp 0x3086
movq %rdi, %rax
movq 0x110(%rsp), %rbp
subq %rbp, %rax
movl $0x0, %ecx
movq 0xb0(%rsp), %r9
cmovbq %r9, %rcx
addq %rax, %rcx
incq %rcx
cmpq $0x2, %rcx
movl $0xffff, %r11d          # imm = 0xFFFF
movq 0x100(%rsp), %r15
jb 0x3054
shrq %rcx
movq %rbp, %rax
andq %r11, %rax
movl %eax, %edx
movq %rdi, %r8
andq %r11, %r8
movl %r8d, %r9d
movzwl (%r10,%rdx,2), %r11d
movq %r15, %r14
movq %rbp, %r15
movzwl (%r10,%r9,2), %ebp
movw %bp, (%r10,%rdx,2)
movw %r11w, (%r10,%r9,2)
movl $0xffff, %r11d          # imm = 0xFFFF
movzwl (%r10,%rdx,2), %edx
movw %r15w, (%rsi,%rdx,2)
movq %r14, %r15
movzwl (%r10,%r9,2), %edx
movq 0xb0(%rsp), %r9
movw %di, (%rsi,%rdx,2)
incq %rax
xorl %edx, %edx
divq %r9
addq %r14, %r8
movq %rdx, %rbp
movq %r8, %rax
xorl %edx, %edx
divq %r9
movq %rdx, %rdi
decq %rcx
jne 0x2fe7
cmpl %ebx, %r12d
cmoval %r12d, %ebx
movq 0xb8(%rsp), %rax
cmpl %ebx, %eax
cmoval %eax, %ebx
movl %ebx, 0xc(%rsp)
xorl %r11d, %r11d
movq 0x50(%rsp), %r14
movq %rsi, %rdi
movq 0x48(%rsp), %r12
movq 0x60(%rsp), %rsi
movq 0x58(%rsp), %r8
incq %r8
incq %rsi
jmp 0x2e1b
leaq 0x138(%rsp), %rax
movq %rax, (%rsp)
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rsi
leaq 0x140(%rsp), %rdx
leaq 0xe0(%rsp), %rcx
leaq 0xc(%rsp), %r8
movq 0x30(%rsp), %r9
callq 0x3b1f
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdi
subq %rsi, %rdi
je 0x312b
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 0x30f9
jmp 0x312d
xorl %ebx, %ebx
cmpq %r14, %rbx
jae 0x3144
movq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4754
movq %rbx, %r14
cmpq $0x8, %r12
jb 0x31b8
leaq 0xc0(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x482f
movq 0x10(%rsp), %rdi
movaps 0xc0(%rsp), %xmm0
movaps %xmm0, 0x10(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x20(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0xc0(%rsp)
movq $0x0, 0xd0(%rsp)
testq %rdi, %rdi
je 0x31ae
callq 0x2140
movq 0xc0(%rsp), %rdi
testq %rdi, %rdi
je 0x31ae
callq 0x2140
movl $0x0, 0xc(%rsp)
jmp 0x31db
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
leaq 0x52cf(%rip), %rdx      # 0x8498
callq 0x4939
movl $0x0, 0xc(%rsp)
testq %r12, %r12
je 0x3243
movq 0x10(%rsp), %rax
movq 0x70(%rsp), %rcx
movq 0x90(%rsp), %rdx
xorl %esi, %esi
movl $0x1, %edi
movq 0xe0(%rsp), %r8
movzwl -0x2(%rax,%rdi,2), %r9d
movq %rdx, %r10
imulq %r9, %r10
leaq (%rcx,%r10,4), %r10
cmpq %rdi, %r12
movl $0x0, %r11d
cmovneq %rdi, %r11
movzwl (%rax,%r11,2), %r11d
movl (%r10,%r11,4), %r10d
cmpl %r10d, %esi
cmovbel %r10d, %esi
movl %esi, 0xc(%rsp)
leal -0x1(%rdi), %r10d
movw %r10w, (%r8,%r9,2)
movzwl %di, %r9d
incq %rdi
cmpq %r9, %r12
ja 0x31fc
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 0x2dad
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
je 0x32de
callq 0x2140
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x32ed
callq 0x2140
movq 0x140(%rsp), %rdi
testq %rdi, %rdi
je 0x32ff
callq 0x2140
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x330e
callq 0x2140
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 0x3352
movq %rax, %rbx
jmp 0x3364
movq %rax, %rbx
jmp 0x3373
movq %rax, %rbx
jmp 0x3385
jmp 0x333d
jmp 0x333d
movq %rax, %rbx
movq 0x40(%rsp), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0x3352
callq 0x2140
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
je 0x3364
callq 0x2140
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3373
callq 0x2140
movq 0x140(%rsp), %rdi
testq %rdi, %rdi
je 0x3385
callq 0x2140
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x3394
callq 0x2140
movq %rbx, %rdi
callq 0x21b0