// File: /workspace/github_cpp_makefile_star2_O1/ksabry[P]bfbrute/src/ProgramIterator.h
// Function: ProgramIterator<400ul, 32ul, 12ul, 32ul>::StringDistanceOutputRecursive[abi:cxx11](char const*, unsigned long, unsigned long, unsigned char*, unsigned long)
std::string StringDistanceOutputRecursive(const char* target, uint_fast32_t targetSize, uint_fast32_t shortCircuit, uint8_t* currentData, uint_fast32_t currentDataIdx)
	{
		if (targetSize == 0)
		{
			return std::string();
		}

		uint_fast32_t bestScore = 100000;
		std::string bestProgram = std::string(shortCircuit + 1, ' ');
		char c = target[0];

		// Compute best scores for reaching each specific data index
		uint_fast32_t dataDeltaScores[data_size];
		std::string dataDeltaPrograms[data_size];

		for (uint_fast32_t idx = 0; idx < data_size; idx++)
		{
			dataDeltaScores[idx] = abs(static_cast<int_fast32_t>(currentDataIdx - idx));
			dataDeltaPrograms[idx] = "";
			if (idx > currentDataIdx)
			{
				for (uint_fast32_t i = 0; i < idx - currentDataIdx; i++) dataDeltaPrograms[idx] += '>';
			}
			else
			{
				for (uint_fast32_t i = 0; i < currentDataIdx - idx; i++) dataDeltaPrograms[idx] += '<';
			}
		}
		for (int_fast32_t startDelta = -8; startDelta <= 8; startDelta++)
		{
			int_fast32_t startIdx = static_cast<int_fast32_t>(currentDataIdx) + startDelta;
			if (startIdx < 0 || startIdx >= data_size)
			{
				continue;
			}
			for (int_fast32_t innerDelta = -8; innerDelta <= 8; innerDelta++)
			{
				if (innerDelta == 0)
				{
					continue;
				}
				int_fast32_t innerIdx = startIdx;
				while (currentData[innerIdx])
				{
					innerIdx += innerDelta;
					if (innerIdx < 0 || innerIdx >= data_size)
					{
						goto loop_fail;
					}
				}
				for (int_fast32_t endDelta = -8; endDelta <= 8; endDelta++)
				{
					int_fast32_t endIdx = innerIdx + endDelta;
					if (endIdx < 0 || endIdx >= data_size)
					{
						continue;
					}
					uint_fast32_t dataDeltaScore = 2 + abs(startDelta) + abs(innerDelta) + abs(endDelta);
					if (dataDeltaScore < dataDeltaScores[endIdx])
					{
						dataDeltaScores[endIdx] = dataDeltaScore;
						dataDeltaPrograms[endIdx] = std::string();
						if (startDelta > 0)
						{
							for (uint_fast32_t i = 0; i < startDelta; i++) dataDeltaPrograms[endIdx] += '>';
						}
						else
						{
							for (uint_fast32_t i = 0; i < -startDelta; i++) dataDeltaPrograms[endIdx] += '<';
						}
						dataDeltaPrograms[endIdx] += '[';
						if (innerDelta > 0)
						{
							for (uint_fast32_t i = 0; i < innerDelta; i++) dataDeltaPrograms[endIdx] += '>';
						}
						else
						{
							for (uint_fast32_t i = 0; i < -innerDelta; i++) dataDeltaPrograms[endIdx] += '<';
						}
						dataDeltaPrograms[endIdx] += ']';
						if (endDelta > 0)
						{
							for (uint_fast32_t i = 0; i < endDelta; i++) dataDeltaPrograms[endIdx] += '>';
						}
						else
						{
							for (uint_fast32_t i = 0; i < -endDelta; i++) dataDeltaPrograms[endIdx] += '<';
						}
					}
				}
			loop_fail:;
			}
		}

		// Search through reaching each specific data index and directly modifying the data to match the next character
		for (uint_fast32_t newDataIdx = 0; newDataIdx < data_size; newDataIdx++)
		{
			uint_fast32_t charScore = 1 + dataDeltaScores[newDataIdx] + abs(static_cast<int8_t>(c - currentData[newDataIdx]));
			std::string charProgram = dataDeltaPrograms[newDataIdx];
			int8_t diff = static_cast<int8_t>(c - currentData[newDataIdx]);
			if (diff > 0)
			{
				for (uint_fast32_t i = 0; i < diff; i++) charProgram += '+';
			}
			else
			{
				for (uint_fast32_t i = 0; i < -diff; i++) charProgram += '-';
			}
			charProgram += '.';

			if (charScore > shortCircuit)
			{
				continue;
			}

			char oldData = currentData[newDataIdx];
			currentData[newDataIdx] = c;
			std::string restProgram = StringDistanceOutputRecursive(target + 1, targetSize - 1, shortCircuit - charScore, currentData, newDataIdx);
			uint_fast32_t restScore = restProgram.size();
			currentData[newDataIdx] = oldData;

			if (charScore + restScore < bestScore)
			{
				bestScore = charScore + restScore;
				bestProgram = charProgram + restProgram;
			}

#ifdef CASE_INSENSITIVE
			if ('a' <= c && c <= 'z')
			{
				char upperC = toupper(c);
				uint_fast32_t upperCharScore = 1 + dataDeltaScores[newDataIdx] + abs(static_cast<int8_t>(upperC - currentData[newDataIdx]));
				std::string upperCharProgram = dataDeltaPrograms[newDataIdx];
				int8_t diff = static_cast<int8_t>(upperC - currentData[newDataIdx]);
				if (diff > 0)
				{
					for (uint_fast32_t i = 0; i < diff; i++) upperCharProgram += '+';
				}
				else
				{
					for (uint_fast32_t i = 0; i < -diff; i++) upperCharProgram += '-';
				}
				upperCharProgram += '.';

				if (upperCharScore > shortCircuit)
				{
					continue;
				}

				char oldData = currentData[newDataIdx];
				currentData[newDataIdx] = upperC;
				std::string restProgram = StringDistanceOutputRecursive(target + 1, targetSize - 1, shortCircuit - upperCharScore, currentData, newDataIdx);
				uint_fast32_t restScore = restProgram.size();
				currentData[newDataIdx] = oldData;

				if (upperCharScore + restScore < bestScore)
				{
					bestScore = upperCharScore + restScore;
					bestProgram = upperCharProgram + restProgram;
				}
			}
#endif
		}
		return bestProgram;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3f88, %rsp           # imm = 0x3F88
movq %rsi, 0x88(%rsp)
movq %rcx, 0x50(%rsp)
testq %rcx, %rcx
je 0x86d0
movq %rdx, %rbx
movq %r9, 0x18(%rsp)
movq 0x3fc0(%rsp), %r12
movq %r8, 0x90(%rsp)
leaq 0x1(%r8), %rsi
leaq 0x10(%rdi), %rax
movq %rax, 0x80(%rsp)
movq %rax, (%rdi)
movq %rdi, 0x20(%rsp)
movl $0x20, %edx
callq 0x2280
movq %rbx, 0x48(%rsp)
movb (%rbx), %al
movb %al, 0x17(%rsp)
movl $0x10, %eax
leaq (%rsp,%rax), %rcx
addq $0xd80, %rcx            # imm = 0xD80
movq %rcx, -0x10(%rcx)
movq $0x0, -0x8(%rcx)
movb $0x0, (%rcx)
addq $0x20, %rax
cmpq $0x3210, %rax           # imm = 0x3210
jne 0x819f
movq %r12, %rbx
negq %rbx
xorl %r15d, %r15d
cmpq $0x1, %rbx
movq %rbx, %r14
adcq $0x0, %r14
cmpq $0x1, %r12
movq %r12, %rbp
adcq $0x0, %rbp
movq 0x3fc0(%rsp), %rax
subq %r15, %rax
movq %rax, %rcx
negq %rcx
cmovsq %rax, %rcx
movq %rcx, 0x100(%rsp,%r15,8)
movq %r15, %rax
shlq $0x5, %rax
leaq (%rsp,%rax), %r13
addq $0xd80, %r13            # imm = 0xD80
movq 0x8(%r13), %rdx
movq %r13, %rdi
xorl %esi, %esi
leaq 0x14ae(%rip), %rcx      # 0x96d1
xorl %r8d, %r8d
callq 0x2300
cmpq %r15, 0x3fc0(%rsp)
jae 0x825f
movq %r13, %rdi
movl $0x3e, %esi
callq 0x21b0
decq %r14
jne 0x8235
incq %r15
decq %r12
incq %rbx
cmpq $0x190, %r15            # imm = 0x190
jne 0x81ce
jmp 0x8273
je 0x8247
movq %r13, %rdi
movl $0x3c, %esi
callq 0x21b0
decq %rbp
jmp 0x825f
movq $-0x8, %rbp
movl $0x8, %ecx
movq 0x18(%rsp), %rax
cmpq $0x1, %rcx
movq %rcx, 0x98(%rsp)
adcq $0x0, %rcx
movq %rcx, 0xb0(%rsp)
movq 0x3fc0(%rsp), %rcx
addq %rbp, %rcx
movq %rcx, 0xa8(%rsp)
cmpq $0x18f, %rcx            # imm = 0x18F
ja 0x84e2
movq %rbp, %rcx
negq %rcx
cmovsq %rbp, %rcx
addq $0x2, %rcx
movq %rcx, 0xa0(%rsp)
movq $-0x8, %rcx
movl $0x8, %edx
movq %rbp, 0xc0(%rsp)
cmpq $0x1, %rdx
movq %rdx, 0xb8(%rsp)
adcq $0x0, %rdx
movq %rdx, 0xc8(%rsp)
testq %rcx, %rcx
je 0x84ca
movq 0xa8(%rsp), %r14
cmpb $0x0, (%rax,%r14)
je 0x8327
addq %rcx, %r14
cmpq $0x18f, %r14            # imm = 0x18F
jbe 0x830f
jmp 0x84ca
movq %rcx, %rax
negq %rax
cmovsq %rcx, %rax
addq 0xa0(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq $-0x8, %r15
movl $0x8, %ebx
movq %rcx, 0x58(%rsp)
cmpq $0x1, %rbx
movq %rbx, 0xd8(%rsp)
adcq $0x0, %rbx
leaq (%r15,%r14), %rax
cmpq $0x18f, %rax            # imm = 0x18F
ja 0x84a8
movq %r15, %rcx
negq %rcx
cmovsq %r15, %rcx
addq 0xd0(%rsp), %rcx
cmpq 0x100(%rsp,%rax,8), %rcx
jae 0x84a8
movq %rcx, 0x100(%rsp,%rax,8)
leaq 0x38(%rsp), %r12
movq %r12, 0x28(%rsp)
movq $0x0, 0x30(%rsp)
movb $0x0, 0x38(%rsp)
shlq $0x5, %rax
leaq (%rsp,%rax), %r13
addq $0xd80, %r13            # imm = 0xD80
movq %r13, %rdi
leaq 0x28(%rsp), %rsi
callq 0x2290
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x83e5
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x2230
movq %rbp, %r12
testq %rbp, %rbp
jle 0x8401
movq %r13, %rdi
movl $0x3e, %esi
callq 0x21b0
decq %r12
jne 0x83ed
jmp 0x841d
movq 0xb0(%rsp), %r12
je 0x841d
movq %r13, %rdi
movl $0x3c, %esi
callq 0x21b0
decq %r12
jne 0x840b
movq %r13, %rdi
movl $0x5b, %esi
callq 0x21b0
movq 0x58(%rsp), %rax
movq %rax, %r12
movq 0xc8(%rsp), %rbp
testq %rax, %rax
jle 0x8453
movq %r13, %rdi
movl $0x3e, %esi
callq 0x21b0
decq %r12
jne 0x843f
jmp 0x8465
movq %r13, %rdi
movl $0x3c, %esi
callq 0x21b0
decq %rbp
jne 0x8453
movq %r13, %rdi
movl $0x5d, %esi
callq 0x21b0
movq 0xc0(%rsp), %rbp
movq %r15, %r12
testq %r15, %r15
jle 0x84a6
movq %r13, %rdi
movl $0x3e, %esi
callq 0x21b0
decq %r12
jne 0x8482
jmp 0x84a8
movq %r13, %rdi
movl $0x3c, %esi
callq 0x21b0
decq %rbx
jne 0x8496
incq %r15
movq 0xd8(%rsp), %rbx
decq %rbx
cmpq $0x9, %r15
movq 0x18(%rsp), %rax
movq 0x58(%rsp), %rcx
jne 0x8352
incq %rcx
movq 0xb8(%rsp), %rdx
decq %rdx
cmpq $0x9, %rcx
jne 0x82e6
incq %rbp
movq 0x98(%rsp), %rcx
decq %rcx
cmpq $0x9, %rbp
jne 0x8284
incq 0x48(%rsp)
decq 0x50(%rsp)
movl $0x186a0, %r15d         # imm = 0x186A0
xorl %r12d, %r12d
leaq 0x28(%rsp), %rbx
movq 0x100(%rsp,%r12,8), %r14
movq 0x18(%rsp), %rbp
movb (%rbp,%r12), %r13b
movq %r12, %rax
shlq $0x5, %rax
leaq 0x38(%rsp), %rcx
movq %rcx, 0x28(%rsp)
movq 0xd80(%rsp,%rax), %rsi
movq 0xd88(%rsp,%rax), %rdx
addq %rsi, %rdx
movq %rbx, %rdi
callq 0x2f66
movb 0x17(%rsp), %al
subb (%rbp,%r12), %al
testb %al, %al
jle 0x8574
movzbl %al, %ebp
movq %rbx, %rdi
movl $0x2b, %esi
callq 0x21b0
decq %rbp
jne 0x8560
jmp 0x858d
movsbl %al, %ebp
negl %ebp
je 0x858d
movq %rbx, %rdi
movl $0x2d, %esi
callq 0x21b0
decq %rbp
jne 0x857b
movq %rbx, %rdi
movl $0x2e, %esi
callq 0x21b0
movb 0x17(%rsp), %dl
movl %edx, %eax
subb %r13b, %al
movl %eax, %ecx
sarb $0x7, %cl
xorb %cl, %al
subb %cl, %al
movzbl %al, %eax
addq %rax, %r14
incq %r14
movq 0x90(%rsp), %r8
subq %r14, %r8
jb 0x8670
movq 0x18(%rsp), %r13
movb (%r13,%r12), %bpl
movb %dl, (%r13,%r12)
movq %r12, (%rsp)
leaq 0x60(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x48(%rsp), %rdx
movq 0x50(%rsp), %rcx
movq %r13, %r9
callq 0x812e
addq 0x68(%rsp), %r14
movb %bpl, (%r13,%r12)
cmpq %r15, %r14
jae 0x8654
leaq 0xe0(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
leaq 0x60(%rsp), %rdx
callq 0x87ac
movq 0x20(%rsp), %rdi
movq %r15, %rsi
callq 0x2290
movq 0xe0(%rsp), %rdi
leaq 0xf0(%rsp), %rax
cmpq %rax, %rdi
je 0x8651
movq 0xf0(%rsp), %rsi
incq %rsi
callq 0x2230
movq %r14, %r15
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0x8670
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x2230
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x868c
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x2230
incq %r12
cmpq $0x190, %r12            # imm = 0x190
jne 0x8512
movq $-0x3200, %rbx          # imm = 0xCE00
leaq 0x3f70(%rsp), %r14
movq -0x10(%r14), %rdi
cmpq %rdi, %r14
je 0x86bf
movq (%r14), %rsi
incq %rsi
callq 0x2230
addq $-0x20, %r14
addq $0x20, %rbx
jne 0x86ab
movq 0x20(%rsp), %rdi
jmp 0x86e3
leaq 0x10(%rdi), %rax
movq %rax, (%rdi)
movq $0x0, 0x8(%rdi)
movb $0x0, 0x10(%rdi)
movq %rdi, %rax
addq $0x3f88, %rsp           # imm = 0x3F88
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0x872a
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x2230
jmp 0x872a
jmp 0x8727
jmp 0x8727
jmp 0x8754
jmp 0x8754
jmp 0x8727
jmp 0x8754
jmp 0x8754
movq %rax, %rbx
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x8757
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x2230
jmp 0x8757
jmp 0x8754
jmp 0x8754
jmp 0x8754
jmp 0x8754
jmp 0x8754
jmp 0x8754
movq %rax, %rbx
movq $-0x3200, %r14          # imm = 0xCE00
leaq 0x3f70(%rsp), %r15
movq -0x10(%r15), %rdi
cmpq %rdi, %r15
je 0x877a
movq (%r15), %rsi
incq %rsi
callq 0x2230
addq $-0x20, %r15
addq $0x20, %r14
jne 0x8766
movq 0x20(%rsp), %rax
movq (%rax), %rdi
movq 0x80(%rsp), %rax
cmpq %rax, %rdi
je 0x87a4
movq (%rax), %rsi
incq %rsi
callq 0x2230
movq %rbx, %rdi
callq 0x23a0