// File: /workspace/github_cpp_makefile_star2_O3/mitchblank[P]qiksolve/qiksolve.cpp
// Function: Dictionary::recursiveSolve(AbstractSolutionAcceptor*, std::vector<unsigned int, std::allocator<unsigned int>> const&, AnswerSequence*) const
void Dictionary::recursiveSolve(AbstractSolutionAcceptor * const acceptor, Words const& active_words, AnswerSequence * const runningAnswersp) const
{
	assert(!active_words.empty());
	if (active_words.size() == 1) {	// We found an end node
		acceptor->acceptSolution(*runningAnswersp, active_words.front());
	} else {
		DividedWordList dl(wordLength());
		double best_entropy = -1.0;
		Word best_word = 0;
		// Of all of the words in active_words, find the one that
		// will gives us the most even split (and thus the highest entropy)
		{
			auto it = keys_.cbegin();
			do {
				dl.build(*this, active_words, *it);
				double const entropy = dl.entropy();
				if (entropy > best_entropy) {
					best_entropy = entropy;
					best_word = *it;
				}
			} while (++it != keys_.cend());
		}
		assert(popcount32(best_word) == wordLength());
		// Now that we have found our best word, recompute the split
		dl.build(*this, active_words, best_word);
		assert(dl.entropy() == best_entropy);
		acceptor->acceptBranch(*runningAnswersp, best_word, best_entropy, dl);
		// Now recursively descend
		for (unsigned i = 0; i < wordLength() + 1; i++) {
			const WordsWithTotalChoices& wwtc = dl[i];
			if (wwtc.count() > 0) {
				runningAnswersp->push_back(i);
				recursiveSolve(acceptor, wwtc.choices(), runningAnswersp);
				runningAnswersp->pop_back();
			}
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rcx, %rbx
movq %rsi, -0x38(%rbp)
movq (%rdx), %rax
movq 0x8(%rdx), %rcx
cmpq %rcx, %rax
je 0x2bd0
subq %rax, %rcx
cmpq $0x4, %rcx
jne 0x2a53
movl (%rax), %edx
movq -0x38(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
movq %rbx, %rsi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmpq *%rax
movq %rdx, %r12
movq %rdi, %r15
movl 0x48(%rdi), %esi
leaq -0x58(%rbp), %r14
movq %r14, %rdi
callq 0x3a22
movq 0x30(%r15), %r13
movsd 0x359c(%rip), %xmm0     # 0x6010
movsd %xmm0, -0x40(%rbp)
movl $0x0, -0x30(%rbp)
movl (%r13), %ecx
movq %r14, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x27c2
movq %r14, %rdi
callq 0x28fa
ucomisd -0x40(%rbp), %xmm0
jbe 0x2aad
movl (%r13), %eax
movl %eax, -0x30(%rbp)
movsd %xmm0, -0x40(%rbp)
addq $0x4, %r13
cmpq 0x38(%r15), %r13
jne 0x2a80
movl -0x30(%rbp), %r14d
movl %r14d, %eax
shrl %eax
andl $0x55555555, %eax       # imm = 0x55555555
movl %r14d, %ecx
subl %eax, %ecx
movl $0x33333333, %eax       # imm = 0x33333333
movl %ecx, %edx
andl %eax, %edx
shrl $0x2, %ecx
andl %eax, %ecx
addl %edx, %ecx
movl %ecx, %eax
shrl $0x4, %eax
addl %ecx, %eax
andl $0xf0f0f0f, %eax        # imm = 0xF0F0F0F
imull $0x1010101, %eax, %eax  # imm = 0x1010101
shrl $0x18, %eax
cmpl 0x48(%r15), %eax
jne 0x2bef
leaq -0x58(%rbp), %rdi
movq %r15, %rsi
movq %r12, %rdx
movl %r14d, %ecx
callq 0x27c2
leaq -0x58(%rbp), %rdi
callq 0x28fa
movsd -0x40(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jne 0x2c0e
jp 0x2c0e
movq -0x38(%rbp), %rdi
movq (%rdi), %rax
leaq -0x58(%rbp), %rcx
movq %rbx, %rsi
movl %r14d, %edx
movapd %xmm1, %xmm0
callq *0x10(%rax)
movl $0x0, -0x2c(%rbp)
movl 0x48(%r15), %ecx
cmpl $-0x1, %ecx
je 0x2bb8
xorl %eax, %eax
leaq -0x2c(%rbp), %r12
movl %eax, %r13d
movq -0x58(%rbp), %r14
shlq $0x5, %r13
cmpq $0x0, 0x18(%r14,%r13)
je 0x2bac
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x2b80
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rbx)
jmp 0x2b8b
movq %rbx, %rdi
movq %r12, %rdx
callq 0x459a
addq %r13, %r14
movq %r15, %rdi
movq -0x38(%rbp), %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x2a02
addq $-0x4, 0x8(%rbx)
movl -0x2c(%rbp), %eax
movl 0x48(%r15), %ecx
incl %eax
movl %eax, -0x2c(%rbp)
leal 0x1(%rcx), %edx
cmpl %edx, %eax
jb 0x2b57
leaq -0x58(%rbp), %rdi
callq 0x3a5a
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x355c(%rip), %rdi      # 0x6133
leaq 0x347b(%rip), %rsi      # 0x6059
leaq 0x3564(%rip), %rcx      # 0x6149
movl $0x18b, %edx            # imm = 0x18B
callq 0x20c0
leaq 0x35c0(%rip), %rdi      # 0x61b6
leaq 0x345c(%rip), %rsi      # 0x6059
leaq 0x3545(%rip), %rcx      # 0x6149
movl $0x19f, %edx            # imm = 0x19F
callq 0x20c0
leaq 0x35c7(%rip), %rdi      # 0x61dc
leaq 0x343d(%rip), %rsi      # 0x6059
leaq 0x3526(%rip), %rcx      # 0x6149
movl $0x1a2, %edx            # imm = 0x1A2
callq 0x20c0
jmp 0x2c31
jmp 0x2c31
movq %rax, %rbx
leaq -0x58(%rbp), %rdi
callq 0x3a5a
movq %rbx, %rdi
callq 0x2240
nop