// File: /workspace/github_cpp_makefile_star2_O1/chhylp123[P]hifiasm/rcut.cpp
// Function: mc_solve_cc(mc_opt_t const*, mc_g_t const*, mc_svaux_t*, unsigned int, unsigned int)
uint32_t mc_solve_cc(const mc_opt_t *opt, const mc_g_t *mg, mc_svaux_t *b, uint32_t cc_off, uint32_t cc_size)
{
	uint32_t j, k, n_iter = 0, flush = opt->max_iter * 50;
	t_w_t sc_opt = -(1<<30), sc;///problem-w
	b->cc_off = cc_off, b->cc_size = cc_size;
	if (b->cc_size < 2) return 0;
	sc_opt = mc_init_spin(mg->e, b);
	// print_sc(opt, mg, b, sc_opt, n_iter);
	if (b->cc_size == 2) return 0;
	for (j = 0; j < b->cc_size; ++j) {///backup s and z in s_opt and z_opt
		b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]]; ///hap status of each unitig
		b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]]; ///z[0]: positive weight; z[1]: positive weight
	}
	// print_sc(opt, mg->e, b, sc_opt, n_iter);
	sc = mc_optimize_local(opt, mg->e, b, &n_iter);
	if (sc > sc_opt) {
		for (j = 0; j < b->cc_size; ++j) {
			b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
			b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
		}
		sc_opt = sc;
	} else {
		for (j = 0; j < b->cc_size; ++j) {
			b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
			b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
		}
	}

    // print_mc_node(mg->e, b, 36880);
	// print_sc(opt, mg, b, sc_opt, n_iter);
	// mc_reset_z_debug(mg->e, b);
	// print_sc(opt, mg->e, b, sc_opt, n_iter);
	// fprintf(stderr, "\ncc_size: %u, cc_off: %u\n", b->cc_size, b->cc_off);
	for (k = 0; k < (uint32_t)opt->n_perturb; ++k) {
		if (k&1) mc_perturb(opt, mg->e, b);
		else mc_perturb_node(opt, mg->e, b, 3);
		sc = mc_optimize_local(opt, mg->e, b, &n_iter);
		// fprintf(stderr, "(%u) sc_opt: %f, sc: %f\n", k, sc_opt, sc);
		if (sc > sc_opt) {
			for (j = 0; j < b->cc_size; ++j) {
				b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc;
			// print_sc(opt, mg, b, sc_opt, n_iter);
		} else {
			for (j = 0; j < b->cc_size; ++j) {
				b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
				b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
			}
		}

		if((n_iter%flush) == 0)
		{
			mc_reset_z(mg->e, b);
			sc = mc_score(mg->e, b);

			for (j = 0; j < b->cc_size; ++j) {
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc;
		}
	}

	for (j = 0; j < b->cc_size; ++j)
	{
		b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
		b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
	}
		
	return n_iter;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl $0x0, 0xc(%rsp)
imull $0x32, (%rdi), %r13d
movl %ecx, 0x8(%rdx)
movl %r8d, 0xc(%rdx)
xorl %ebp, %ebp
cmpl $0x2, %r8d
jb 0x164adf
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r15
movq 0x28(%rsi), %rdi
movq %rdx, %rsi
callq 0x1637b8
movsd %xmm0, 0x10(%rsp)
cmpl $0x2, 0xc(%rbx)
je 0x164adf
cmpl $0x0, 0xc(%rbx)
je 0x1648ad
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm0
movupd %xmm0, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x164870
movq 0x28(%r14), %rsi
leaq 0xc(%rsp), %rcx
movq %r15, %rdi
movq %rbx, %rdx
callq 0x164af0
ucomisd 0x10(%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x164915
testl %eax, %eax
je 0x16490d
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movups (%rdx,%rcx), %xmm1
movups %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x1648d2
movsd %xmm0, 0x10(%rsp)
jmp 0x164958
testl %eax, %eax
je 0x164958
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16491b
cmpl $0x0, 0x4(%r15)
je 0x164a96
xorl %ebp, %ebp
leaq 0xc(%rsp), %r12
movq 0x28(%r14), %rsi
movq %r15, %rdi
movq %rbx, %rdx
testb $0x1, %bpl
jne 0x164981
callq 0x164ca6
jmp 0x164986
callq 0x164bb0
movq 0x28(%r14), %rsi
movq %r15, %rdi
movq %rbx, %rdx
movq %r12, %rcx
callq 0x164af0
ucomisd 0x10(%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x1649ec
testl %eax, %eax
je 0x1649e4
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movups (%rdx,%rcx), %xmm1
movups %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x1649a9
movsd %xmm0, 0x10(%rsp)
jmp 0x164a2f
testl %eax, %eax
je 0x164a2f
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x1649f2
movl 0xc(%rsp), %eax
xorl %edx, %edx
divl %r13d
testl %edx, %edx
jne 0x164a8a
movq 0x28(%r14), %rdi
movq %rbx, %rsi
callq 0x16360e
movq 0x28(%r14), %rdi
movq %rbx, %rsi
callq 0x163573
movsd %xmm0, 0x10(%rsp)
cmpl $0x0, 0xc(%rbx)
je 0x164a8a
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm0
movupd %xmm0, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x164a62
incl %ebp
cmpl 0x4(%r15), %ebp
jb 0x16496a
cmpl $0x0, 0xc(%rbx)
je 0x164adb
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x164a9e
movl 0xc(%rsp), %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq