// File: Alcaro[P]bridges/solver.cpp
// Function: (anonymous namespace)::solver<((anonymous namespace)::op_t)0>::solve()
bool solve()
	{
//puts("SOLVEBEGIN");
		possibilities = possibilities_buf;
		
		int num_roots = 0;
		
		//make sure that existing bridges are labeled as such on all tiles they're on
		//'map' is known correct, but anything other than that should use set_state
		
		for (int y=0;y<map.height;y++)
		for (int x=0;x<map.width;x++)
		{
			nextjoined[y*100+x] = y*100+x;
		}
		
		for (int y=0;y<map.height;y++)
		for (int x=0;x<map.width;x++)
		{
			gamemap::island& here = map.map[y][x];
			int index = y*100+x;
			
			if (here.rootnode != index)
			{
				int tmp = nextjoined[here.rootnode];
				nextjoined[here.rootnode] = nextjoined[index];
				nextjoined[index] = tmp;
			}
			
			if (here.rootnode == index && here.population > 0) num_roots++;
			
			uint16_t flags = 0x000F;
			for (int dir=0;dir<4;dir++)
			{
				if (here.bridgelen[dir] != -1) flags |= 0x0110<<dir;
				if (op!=op_another && op!=op_difficulty && here.bridges[dir] == 1) flags &= ~(0x0001<<dir);
				if (op!=op_another && op!=op_difficulty && here.bridges[dir] == 2) flags &= ~(0x0011<<dir);
				if (here.bridges[dir] == 3) { flags &= ~(0x0111<<dir); flags |= 0x1000<<dir; }
			}
			possibilities[index] = flags;
		}
		
		if (map.numislands == 0) return (op!=op_another);
		if (op==op_hint || op==op_difficulty) accumulator=0;
		
		//block 1s and 2s from using both of their bindings towards each other
		if (num_roots > 2) // except if that's the only two islands
		{
			for (int y=0;y<map.height;y++)
			for (int x=0;x<map.width;x++)
			{
				gamemap::island& here = map.map[y][x];
				uint16_t flags = possibilities[y*100+x];
				uint16_t newflags = flags;
				
				//keep the pointless flags&0x1234 checks, here.bridgelen[0] is undefined if the relevant flag isn't set
				//this isn't a pure performance optimization - the isolation rule processor ignores pop-1 islands,
				//  so without this, it could claim the map '1111' is solvable
				if (here.population == 2 && (flags&0x0100) && map.map[y][x+here.bridgelen[0]].population == 2)
					newflags &= ~0x0100;
				if (here.population == 1 && (flags&0x0010) && map.map[y][x+here.bridgelen[0]].population == 1)
					newflags &= ~0x0010;
				
				if (here.population == 2 && (flags&0x0800) && map.map[y+here.bridgelen[3]][x].population == 2)
					newflags &= ~0x0800;
				if (here.population == 1 && (flags&0x0080) && map.map[y+here.bridgelen[3]][x].population == 1)
					newflags &= ~0x0080;
				
				if (flags != newflags)
				{
//printf("%.3i(%.3i) %.4X->%.4X\n",y*100+x,here.population,flags,newflags);
					if (!set_state(y*100+x, newflags)) return false;
				}
			}
		}
		
		for (int y=0;y<map.height;y++)
		for (int x=0;x<map.width;x++)
		{
			if (map.map[y][x].rootnode != y*100+x) continue; // only poke the roots, no point doing duplicate checks
			if (!fill_simple(y*100+x)) return false;
		}
		
		if (op==op_hint && accumulator) return false;
		
		if (op == op_hint || op == op_difficulty)
		{
			int maxdepth = 1;
		again: ;
			int ret = solve_rec(0, maxdepth);
			if (ret == 0) return false;
			if (ret == -1) { maxdepth++; goto again; }
			maxdepth--; // needs at least depth 1, or it won't notice that it's finished. this should not contribute to difficulty
			add_difficulty(100*maxdepth*maxdepth);
#ifndef STDOUT_ERROR
if(maxdepth>=2)puts("#######"),puts(map.serialize()),puts("#######");
#endif
		}
		else
		{
			if (solve_rec(0, 0) <= 0) return false;
		}
		
		if (op==op_hint || op==op_difficulty) return false; // return value for these operations is irrelevant
		
		assign();
		return true;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x88(%rbp)
movq %rax, %rcx
addq $0x4e30, %rcx           # imm = 0x4E30
movq %rcx, 0x4e28(%rax)
movl $0x0, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movq -0x88(%rbp), %rcx
movl -0x20(%rbp), %eax
movq (%rcx), %rcx
cmpl 0x4(%rcx), %eax
jge 0x53ccb
movl $0x0, -0x24(%rbp)
movq -0x88(%rbp), %rcx
movl -0x24(%rbp), %eax
movq (%rcx), %rcx
cmpl (%rcx), %eax
jge 0x53cbe
movq -0x88(%rbp), %rax
imull $0x64, -0x20(%rbp), %ecx
addl -0x24(%rbp), %ecx
movw %cx, %dx
imull $0x64, -0x20(%rbp), %ecx
addl -0x24(%rbp), %ecx
movslq %ecx, %rcx
movw %dx, 0x8(%rax,%rcx,2)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x53c82
jmp 0x53cc0
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x53c69
movl $0x0, -0x28(%rbp)
movq -0x88(%rbp), %rcx
movl -0x28(%rbp), %eax
movq (%rcx), %rcx
cmpl 0x4(%rcx), %eax
jge 0x53ec4
movl $0x0, -0x2c(%rbp)
movq -0x88(%rbp), %rcx
movl -0x2c(%rbp), %eax
movq (%rcx), %rcx
cmpl (%rcx), %eax
jge 0x53eb4
movq -0x88(%rbp), %rax
movq (%rax), %rax
addq $0xc, %rax
movslq -0x28(%rbp), %rcx
imulq $0x4b0, %rcx, %rcx      # imm = 0x4B0
addq %rcx, %rax
movslq -0x2c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
imull $0x64, -0x28(%rbp), %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x3c(%rbp)
movq -0x38(%rbp), %rax
movswl 0x2(%rax), %eax
cmpl -0x3c(%rbp), %eax
je 0x53d84
movq -0x88(%rbp), %rax
movq -0x38(%rbp), %rcx
movswq 0x2(%rcx), %rcx
movzwl 0x8(%rax,%rcx,2), %ecx
movl %ecx, -0x40(%rbp)
movslq -0x3c(%rbp), %rcx
movw 0x8(%rax,%rcx,2), %dx
movq -0x38(%rbp), %rcx
movswq 0x2(%rcx), %rcx
movw %dx, 0x8(%rax,%rcx,2)
movl -0x40(%rbp), %ecx
movw %cx, %dx
movslq -0x3c(%rbp), %rcx
movw %dx, 0x8(%rax,%rcx,2)
movq -0x38(%rbp), %rax
movswl 0x2(%rax), %eax
cmpl -0x3c(%rbp), %eax
jne 0x53da6
movq -0x38(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jle 0x53da6
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
movw $0xf, -0x42(%rbp)
movl $0x0, -0x48(%rbp)
cmpl $0x4, -0x48(%rbp)
jge 0x53e8c
movq -0x38(%rbp), %rax
movslq -0x48(%rbp), %rcx
movsbl 0x4(%rax,%rcx), %eax
cmpl $-0x1, %eax
je 0x53de5
movl -0x48(%rbp), %ecx
movl $0x110, %eax            # imm = 0x110
shll %cl, %eax
movl %eax, %ecx
movzwl -0x42(%rbp), %eax
orl %ecx, %eax
movw %ax, -0x42(%rbp)
movq -0x38(%rbp), %rax
movslq -0x48(%rbp), %rcx
movzbl 0x8(%rax,%rcx), %eax
cmpl $0x1, %eax
jne 0x53e10
movl -0x48(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
xorl $-0x1, %ecx
movzwl -0x42(%rbp), %eax
andl %ecx, %eax
movw %ax, -0x42(%rbp)
movq -0x38(%rbp), %rax
movslq -0x48(%rbp), %rcx
movzbl 0x8(%rax,%rcx), %eax
cmpl $0x2, %eax
jne 0x53e3b
movl -0x48(%rbp), %ecx
movl $0x11, %eax
shll %cl, %eax
movl %eax, %ecx
xorl $-0x1, %ecx
movzwl -0x42(%rbp), %eax
andl %ecx, %eax
movw %ax, -0x42(%rbp)
movq -0x38(%rbp), %rax
movslq -0x48(%rbp), %rcx
movzbl 0x8(%rax,%rcx), %eax
cmpl $0x3, %eax
jne 0x53e7c
movl -0x48(%rbp), %ecx
movl $0x111, %eax            # imm = 0x111
shll %cl, %eax
movl %eax, %ecx
xorl $-0x1, %ecx
movzwl -0x42(%rbp), %eax
andl %ecx, %eax
movw %ax, -0x42(%rbp)
movl -0x48(%rbp), %ecx
movl $0x1000, %eax           # imm = 0x1000
shll %cl, %eax
movl %eax, %ecx
movzwl -0x42(%rbp), %eax
orl %ecx, %eax
movw %ax, -0x42(%rbp)
jmp 0x53e7e
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x53db3
movq -0x88(%rbp), %rax
movw -0x42(%rbp), %dx
movq 0x4e28(%rax), %rax
movslq -0x3c(%rbp), %rcx
movw %dx, (%rax,%rcx,2)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x53cef
jmp 0x53eb6
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x53cd2
movq -0x88(%rbp), %rax
movq (%rax), %rax
cmpl $0x0, 0x8(%rax)
jne 0x53edd
movb $0x1, -0xd(%rbp)
jmp 0x542d6
cmpl $0x2, -0x1c(%rbp)
jle 0x54147
movl $0x0, -0x4c(%rbp)
movq -0x88(%rbp), %rcx
movl -0x4c(%rbp), %eax
movq (%rcx), %rcx
cmpl 0x4(%rcx), %eax
jge 0x54145
movl $0x0, -0x50(%rbp)
movq -0x88(%rbp), %rcx
movl -0x50(%rbp), %eax
movq (%rcx), %rcx
cmpl (%rcx), %eax
jge 0x54135
movq -0x88(%rbp), %rax
movq (%rax), %rcx
addq $0xc, %rcx
movslq -0x4c(%rbp), %rdx
imulq $0x4b0, %rdx, %rdx      # imm = 0x4B0
addq %rdx, %rcx
movslq -0x50(%rbp), %rdx
imulq $0xc, %rdx, %rdx
addq %rdx, %rcx
movq %rcx, -0x58(%rbp)
movq 0x4e28(%rax), %rax
imull $0x64, -0x4c(%rbp), %ecx
addl -0x50(%rbp), %ecx
movslq %ecx, %rcx
movw (%rax,%rcx,2), %ax
movw %ax, -0x5a(%rbp)
movw -0x5a(%rbp), %ax
movw %ax, -0x5c(%rbp)
movq -0x58(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2, %eax
jne 0x53fce
movzwl -0x5a(%rbp), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x53fce
movq -0x88(%rbp), %rax
movq (%rax), %rax
addq $0xc, %rax
movslq -0x4c(%rbp), %rcx
imulq $0x4b0, %rcx, %rcx      # imm = 0x4B0
addq %rcx, %rax
movl -0x50(%rbp), %ecx
movq -0x58(%rbp), %rdx
movsbl 0x4(%rdx), %edx
addl %edx, %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movsbl (%rax), %eax
cmpl $0x2, %eax
jne 0x53fce
movzwl -0x5c(%rbp), %eax
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movw %ax, -0x5c(%rbp)
movq -0x58(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x1, %eax
jne 0x5402c
movzwl -0x5a(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x5402c
movq -0x88(%rbp), %rax
movq (%rax), %rax
addq $0xc, %rax
movslq -0x4c(%rbp), %rcx
imulq $0x4b0, %rcx, %rcx      # imm = 0x4B0
addq %rcx, %rax
movl -0x50(%rbp), %ecx
movq -0x58(%rbp), %rdx
movsbl 0x4(%rdx), %edx
addl %edx, %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movsbl (%rax), %eax
cmpl $0x1, %eax
jne 0x5402c
movzwl -0x5c(%rbp), %eax
andl $-0x11, %eax
movw %ax, -0x5c(%rbp)
movq -0x58(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2, %eax
jne 0x5408e
movzwl -0x5a(%rbp), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0x5408e
movq -0x88(%rbp), %rax
movq (%rax), %rax
addq $0xc, %rax
movl -0x4c(%rbp), %ecx
movq -0x58(%rbp), %rdx
movsbl 0x7(%rdx), %edx
addl %edx, %ecx
movslq %ecx, %rcx
imulq $0x4b0, %rcx, %rcx      # imm = 0x4B0
addq %rcx, %rax
movslq -0x50(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movsbl (%rax), %eax
cmpl $0x2, %eax
jne 0x5408e
movzwl -0x5c(%rbp), %eax
andl $0xfffff7ff, %eax       # imm = 0xFFFFF7FF
movw %ax, -0x5c(%rbp)
movq -0x58(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x1, %eax
jne 0x540f0
movzwl -0x5a(%rbp), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x540f0
movq -0x88(%rbp), %rax
movq (%rax), %rax
addq $0xc, %rax
movl -0x4c(%rbp), %ecx
movq -0x58(%rbp), %rdx
movsbl 0x7(%rdx), %edx
addl %edx, %ecx
movslq %ecx, %rcx
imulq $0x4b0, %rcx, %rcx      # imm = 0x4B0
addq %rcx, %rax
movslq -0x50(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movsbl (%rax), %eax
cmpl $0x1, %eax
jne 0x540f0
movzwl -0x5c(%rbp), %eax
andl $0xffffff7f, %eax       # imm = 0xFFFFFF7F
movw %ax, -0x5c(%rbp)
movzwl -0x5a(%rbp), %eax
movzwl -0x5c(%rbp), %ecx
cmpl %ecx, %eax
je 0x54125
movq -0x88(%rbp), %rdi
imull $0x64, -0x4c(%rbp), %eax
addl -0x50(%rbp), %eax
movzwl %ax, %esi
movzwl -0x5c(%rbp), %edx
callq 0x552b0
testb $0x1, %al
jne 0x54123
movb $0x0, -0xd(%rbp)
jmp 0x542d6
jmp 0x54125
jmp 0x54127
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x53f0b
jmp 0x54137
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x53eee
jmp 0x54147
movl $0x0, -0x60(%rbp)
movq -0x88(%rbp), %rcx
movl -0x60(%rbp), %eax
movq (%rcx), %rcx
cmpl 0x4(%rcx), %eax
jge 0x541f4
movl $0x0, -0x64(%rbp)
movq -0x88(%rbp), %rcx
movl -0x64(%rbp), %eax
movq (%rcx), %rcx
cmpl (%rcx), %eax
jge 0x541e4
movq -0x88(%rbp), %rax
movq (%rax), %rax
addq $0xc, %rax
movslq -0x60(%rbp), %rcx
imulq $0x4b0, %rcx, %rcx      # imm = 0x4B0
addq %rcx, %rax
movslq -0x64(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movswl 0x2(%rax), %eax
imull $0x64, -0x60(%rbp), %ecx
addl -0x64(%rbp), %ecx
cmpl %ecx, %eax
je 0x541b4
jmp 0x541d9
movq -0x88(%rbp), %rdi
imull $0x64, -0x60(%rbp), %eax
addl -0x64(%rbp), %eax
movzwl %ax, %esi
callq 0x55570
testb $0x1, %al
jne 0x541d7
movb $0x0, -0xd(%rbp)
jmp 0x542d6
jmp 0x541d9
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x5416b
jmp 0x541e6
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x5414e
xorl %eax, %eax
testb $0x1, %al
jne 0x541ff
jmp 0x542a9
movl $0x1, -0x68(%rbp)
movq -0x88(%rbp), %rdi
movl -0x68(%rbp), %eax
xorl %esi, %esi
movzwl %ax, %edx
callq 0x55a90
movl %eax, -0x6c(%rbp)
cmpl $0x0, -0x6c(%rbp)
jne 0x5422c
movb $0x0, -0xd(%rbp)
jmp 0x542d6
cmpl $-0x1, -0x6c(%rbp)
jne 0x5423d
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x54206
movq -0x88(%rbp), %rcx
movl -0x68(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x68(%rbp)
imull $0x64, -0x68(%rbp), %eax
imull -0x68(%rbp), %eax
movq %rcx, -0x8(%rbp)
movl %eax, -0xc(%rbp)
cmpl $0x2, -0x68(%rbp)
jl 0x542a7
leaq 0x12bb5(%rip), %rdi     # 0x66e1e
callq 0x4580
movq -0x88(%rbp), %rax
movq (%rax), %rsi
leaq -0x80(%rbp), %rdi
callq 0x4f7f0
leaq -0x80(%rbp), %rdi
callq 0x5660
movq %rax, %rdi
callq 0x4580
leaq 0x12b85(%rip), %rdi     # 0x66e1e
callq 0x4580
leaq -0x80(%rbp), %rdi
callq 0x5870
jmp 0x542c6
movq -0x88(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x55a90
cmpl $0x0, %eax
jg 0x542c4
movb $0x0, -0xd(%rbp)
jmp 0x542d6
jmp 0x542c6
movq -0x88(%rbp), %rdi
callq 0x55ee0
movb $0x1, -0xd(%rbp)
movb -0xd(%rbp), %al
andb $0x1, %al
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)