// File: integeruser[P]GA3C-cpp/src/ga3c.cc
// Function: extract_accumulated_experience(std::deque<std::tuple<std::vector<float, std::allocator<float>>, long, float, std::vector<float, std::allocator<float>>, bool>, std::allocator<std::tuple<std::vector<float, std::allocator<float>>, long, float, std::vector<float, std::allocator<float>>, bool>>>&, float)
training_experience_t extract_accumulated_experience(memory_t& memory, float next_state_value)
{
    assert(not memory.empty());
    const auto n = std::min<uint32_t>(N_STEP_RETURN, memory.size());

    // pick experience at time step t
    uint32_t t = 0;
    const auto curr_state = std::get<0>(memory[t]);
    const auto action = std::get<1>(memory[t]);

    // and calculate its n-step return (until time step t+n)
    float n_step_return = 0.0f;
    for (; t < n; ++t) {
        const auto reward = std::get<2>(memory[t]);
        n_step_return += std::pow(GAMMA, t)*reward;
    }
    const auto done = std::get<4>(memory[n-1]);
    if (not done) { n_step_return += std::pow(GAMMA, n)*next_state_value; }

    memory.pop_front();
    return training_experience_t{curr_state, action, n_step_return};
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x68(%rbp)
movq %rdi, %rax
movq %rax, -0x60(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movss %xmm0, -0x14(%rbp)
movq -0x10(%rbp), %rdi
callq 0x48a0
xorb $-0x1, %al
testb $0x1, %al
jne 0x3724
jmp 0x3726
jmp 0x3745
leaq 0x10923(%rip), %rdi     # 0x14050
leaq 0x1092f(%rip), %rsi     # 0x14063
movl $0x3d, %edx
leaq 0x1092f(%rip), %rcx     # 0x1406f
callq 0x30f0
movq -0x10(%rbp), %rdi
callq 0x4910
movl %eax, -0x1c(%rbp)
leaq 0x10b14(%rip), %rdi     # 0x1426c
leaq -0x1c(%rbp), %rsi
callq 0x48d0
movl (%rax), %eax
movl %eax, -0x18(%rbp)
movl $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x4960
movq %rax, %rdi
callq 0x4940
movq %rax, %rsi
leaq -0x38(%rbp), %rdi
callq 0x4990
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x4960
movq %rax, %rdi
callq 0x4a80
movq (%rax), %rax
movq %rax, -0x40(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x44(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x18(%rbp), %eax
jae 0x3843
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x4960
movq %rax, %rdi
callq 0x4aa0
movss (%rax), %xmm0
movss %xmm0, -0x48(%rbp)
movl -0x20(%rbp), %edi
movss 0x1081e(%rip), %xmm0    # 0x14008
callq 0x4ac0
movsd %xmm0, -0x70(%rbp)
jmp 0x37f6
movsd -0x70(%rbp), %xmm0
movss -0x48(%rbp), %xmm1
cvtss2sd %xmm1, %xmm2
movss -0x44(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x44(%rbp)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x37b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x4bc0
jmp 0x38e0
movq -0x10(%rbp), %rdi
movl -0x18(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x4960
movq %rax, %rdi
callq 0x4af0
movb (%rax), %al
andb $0x1, %al
movb %al, -0x55(%rbp)
testb $0x1, -0x55(%rbp)
jne 0x38aa
movl -0x18(%rbp), %edi
movss 0x10792(%rip), %xmm0    # 0x14008
callq 0x4ac0
movsd %xmm0, -0x78(%rbp)
jmp 0x3882
movsd -0x78(%rbp), %xmm0
movss -0x14(%rbp), %xmm1
cvtss2sd %xmm1, %xmm2
movss -0x44(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x44(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4b10
movq -0x68(%rbp), %rdi
leaq -0x38(%rbp), %rsi
leaq -0x40(%rbp), %rdx
leaq -0x44(%rbp), %rcx
callq 0x4b80
jmp 0x38ca
leaq -0x38(%rbp), %rdi
callq 0x4bc0
movq -0x60(%rbp), %rax
addq $0x80, %rsp
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x3350
nopl (%rax)