// File: /workspace/github_cpp_makefile_star2_O3/Alcaro[P]bridges/solver.cpp
// Function: gamemap::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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8368, %rsp          # imm = 0xC8368
leaq 0x4e60(%rsp), %rax
movq %rdi, -0x4e30(%rax)
movq %rax, -0x8(%rax)
movslq 0x4(%rdi), %r14
testq %r14, %r14
jle 0x26389
movl (%rdi), %eax
leal 0x7(%rax), %ecx
andl $-0x8, %ecx
movq %rax, (%rsp)
leaq -0x1(%rax), %rdx
movq %rdx, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
leaq 0x46(%rsp), %rsi
xorl %r8d, %r8d
movdqa 0xc875(%rip), %xmm2     # 0x32640
movdqa 0x9bdd(%rip), %xmm3     # 0x2f9b0
movdqa 0x9595(%rip), %xmm4     # 0x2f370
movdqa 0x9bdd(%rip), %xmm5     # 0x2f9c0
pxor %xmm5, %xmm0
pcmpeqd %xmm6, %xmm6
movdqa 0xc85d(%rip), %xmm7     # 0x32650
xorl %r9d, %r9d
cmpl $0x0, (%rsp)
jle 0x26094
xorl %r10d, %r10d
movdqa %xmm4, %xmm8
movdqa %xmm3, %xmm9
movdqa %xmm2, %xmm10
movdqa 0xc815(%rip), %xmm11    # 0x32630
movdqa %xmm8, %xmm12
pxor %xmm5, %xmm12
movdqa %xmm12, %xmm14
pcmpgtd %xmm0, %xmm14
pshufd $0xa0, %xmm14, %xmm13   # xmm13 = xmm14[0,0,2,2]
pshuflw $0xe8, %xmm13, %xmm15   # xmm15 = xmm13[0,2,2,3,4,5,6,7]
pcmpeqd %xmm0, %xmm12
pshufd $0xf5, %xmm12, %xmm12   # xmm12 = xmm12[1,1,3,3]
pshuflw $0xe8, %xmm12, %xmm1    # xmm1 = xmm12[0,2,2,3,4,5,6,7]
pand %xmm15, %xmm1
pshufd $0xf5, %xmm14, %xmm14   # xmm14 = xmm14[1,1,3,3]
pshuflw $0xe8, %xmm14, %xmm15   # xmm15 = xmm14[0,2,2,3,4,5,6,7]
por %xmm1, %xmm15
pxor %xmm6, %xmm15
packssdw %xmm15, %xmm15
movd %xmm15, %edx
testb $0x1, %dl
je 0x25e80
leal (%r8,%r10), %edx
movw %dx, -0xe(%rsi,%r10,2)
pand %xmm13, %xmm12
por %xmm14, %xmm12
packssdw %xmm12, %xmm12
pxor %xmm6, %xmm12
packssdw %xmm12, %xmm12
movd %xmm12, %edx
shrl $0x10, %edx
testb $0x1, %dl
je 0x25eb2
leal (%r8,%r10), %edx
incl %edx
movw %dx, -0xc(%rsi,%r10,2)
movdqa %xmm9, %xmm1
pxor %xmm5, %xmm1
movdqa %xmm1, %xmm14
pcmpgtd %xmm0, %xmm14
pshufd $0xa0, %xmm14, %xmm12   # xmm12 = xmm14[0,0,2,2]
pcmpeqd %xmm0, %xmm1
pshufd $0xf5, %xmm1, %xmm13    # xmm13 = xmm1[1,1,3,3]
movdqa %xmm13, %xmm1
pand %xmm12, %xmm1
pshufd $0xf5, %xmm14, %xmm14   # xmm14 = xmm14[1,1,3,3]
por %xmm14, %xmm1
packssdw %xmm1, %xmm1
pxor %xmm6, %xmm1
packssdw %xmm1, %xmm1
pextrw $0x2, %xmm1, %edx
testb $0x1, %dl
je 0x25f0d
leal (%r8,%r10), %edx
addl $0x2, %edx
movw %dx, -0xa(%rsi,%r10,2)
pshufhw $0x84, %xmm12, %xmm1    # xmm1 = xmm12[0,1,2,3,4,5,4,6]
pshufhw $0x84, %xmm13, %xmm12   # xmm12 = xmm13[0,1,2,3,4,5,4,6]
pand %xmm1, %xmm12
pshufhw $0x84, %xmm14, %xmm1    # xmm1 = xmm14[0,1,2,3,4,5,4,6]
por %xmm12, %xmm1
pxor %xmm6, %xmm1
packssdw %xmm1, %xmm1
pextrw $0x3, %xmm1, %edx
testb $0x1, %dl
je 0x25f48
leal (%r8,%r10), %edx
addl $0x3, %edx
movw %dx, -0x8(%rsi,%r10,2)
movdqa %xmm10, %xmm1
pxor %xmm5, %xmm1
movdqa %xmm1, %xmm14
pcmpgtd %xmm0, %xmm14
pshufd $0xa0, %xmm14, %xmm13   # xmm13 = xmm14[0,0,2,2]
pshuflw $0xe8, %xmm13, %xmm15   # xmm15 = xmm13[0,2,2,3,4,5,6,7]
pcmpeqd %xmm0, %xmm1
pshufd $0xf5, %xmm1, %xmm12    # xmm12 = xmm1[1,1,3,3]
pshuflw $0xe8, %xmm12, %xmm1    # xmm1 = xmm12[0,2,2,3,4,5,6,7]
pand %xmm15, %xmm1
pshufd $0xf5, %xmm14, %xmm14   # xmm14 = xmm14[1,1,3,3]
pshuflw $0xe8, %xmm14, %xmm15   # xmm15 = xmm14[0,2,2,3,4,5,6,7]
por %xmm1, %xmm15
pxor %xmm6, %xmm15
packssdw %xmm15, %xmm1
pextrw $0x4, %xmm1, %edx
testb $0x1, %dl
je 0x25fae
leal (%r8,%r10), %edx
addl $0x4, %edx
movw %dx, -0x6(%rsi,%r10,2)
pand %xmm13, %xmm12
por %xmm14, %xmm12
packssdw %xmm12, %xmm12
pxor %xmm6, %xmm12
packssdw %xmm12, %xmm1
pextrw $0x5, %xmm1, %edx
testb $0x1, %dl
je 0x25fde
leal (%r8,%r10), %edx
addl $0x5, %edx
movw %dx, -0x4(%rsi,%r10,2)
movdqa %xmm11, %xmm1
pxor %xmm5, %xmm1
movdqa %xmm1, %xmm14
pcmpgtd %xmm0, %xmm14
pshufd $0xa0, %xmm14, %xmm12   # xmm12 = xmm14[0,0,2,2]
pcmpeqd %xmm0, %xmm1
pshufd $0xf5, %xmm1, %xmm13    # xmm13 = xmm1[1,1,3,3]
movdqa %xmm13, %xmm1
pand %xmm12, %xmm1
pshufd $0xf5, %xmm14, %xmm14   # xmm14 = xmm14[1,1,3,3]
por %xmm14, %xmm1
packssdw %xmm1, %xmm1
pxor %xmm6, %xmm1
packssdw %xmm1, %xmm1
pextrw $0x6, %xmm1, %edx
testb $0x1, %dl
je 0x26039
leal (%r8,%r10), %edx
addl $0x6, %edx
movw %dx, -0x2(%rsi,%r10,2)
pshufhw $0x84, %xmm12, %xmm1    # xmm1 = xmm12[0,1,2,3,4,5,4,6]
pshufhw $0x84, %xmm13, %xmm12   # xmm12 = xmm13[0,1,2,3,4,5,4,6]
pand %xmm1, %xmm12
pshufhw $0x84, %xmm14, %xmm1    # xmm1 = xmm14[0,1,2,3,4,5,4,6]
por %xmm12, %xmm1
pxor %xmm6, %xmm1
packssdw %xmm1, %xmm1
pextrw $0x7, %xmm1, %edx
testb $0x1, %dl
je 0x26073
leal (%r8,%r10), %edx
addl $0x7, %edx
movw %dx, (%rsi,%r10,2)
addq $0x8, %r10
paddq %xmm7, %xmm8
paddq %xmm7, %xmm9
paddq %xmm7, %xmm10
paddq %xmm7, %xmm11
cmpq %r10, %rcx
jne 0x25e1b
incq %r9
addq $0x64, %r8
addq $0xc8, %rsi
cmpq %r14, %r9
jne 0x25df6
leaq 0xc(%rdi), %rax
movq %rax, 0x18(%rsp)
movq %rdi, 0x10(%rsp)
leaq 0x14(%rdi), %r8
xorl %r9d, %r9d
movl $0xffff, %r10d          # imm = 0xFFFF
xorl %ebx, %ebx
xorl %r11d, %r11d
movq (%rsp), %rdi
movq %r14, 0x8(%rsp)
testl %edi, %edi
jle 0x261ad
imulq $0x64, %rbx, %r14
imulq $0x4b0, %rbx, %r15      # imm = 0x4B0
addq 0x18(%rsp), %r15
movq %r8, %r12
xorl %r13d, %r13d
leaq (,%r13,2), %rdx
addq %r13, %rdx
leaq (%r14,%r13), %rbp
movswq 0x2(%r15,%rdx,4), %rcx
movl %ecx, %esi
cmpq %rsi, %rbp
jne 0x2611f
leaq (%r15,%rdx,4), %rcx
xorl %edx, %edx
cmpb $0x0, (%rcx)
setg %dl
addl %edx, %r11d
jmp 0x26133
movzwl 0x38(%rsp,%rcx,2), %edx
movzwl 0x38(%rsp,%rbp,2), %esi
movw %si, 0x38(%rsp,%rcx,2)
movw %dx, 0x38(%rsp,%rbp,2)
movw $0xf, %dx
xorl %ecx, %ecx
movl $0x110, %esi            # imm = 0x110
shll %cl, %esi
cmpb $-0x1, -0x4(%r12,%rcx)
cmovel %r9d, %esi
orl %esi, %edx
movl $0xfffffffe, %esi       # imm = 0xFFFFFFFE
roll %cl, %esi
movb (%r12,%rcx), %al
cmpb $0x1, %al
cmovnel %r10d, %esi
andl %edx, %esi
movl $0x11, %edx
shll %cl, %edx
cmpb $0x2, %al
notl %edx
cmovnel %r10d, %edx
cmpb $0x3, %al
jne 0x26188
movl $0x111, %eax            # imm = 0x111
shll %cl, %eax
notl %eax
andl %eax, %esi
movl $0x1000, %edx           # imm = 0x1000
shll %cl, %edx
orl %esi, %edx
jmp 0x2618c
andl %edx, %esi
movl %esi, %edx
incq %rcx
cmpq $0x4, %rcx
jne 0x26139
movw %dx, 0x4e60(%rsp,%rbp,2)
incq %r13
addq $0xc, %r12
cmpq %rdi, %r13
jne 0x260f2
incq %rbx
addq $0x4b0, %r8             # imm = 0x4B0
movq 0x8(%rsp), %r14
cmpq %r14, %rbx
jne 0x260d4
movq 0x10(%rsp), %rax
cmpl $0x0, 0x8(%rax)
je 0x264df
cmpl $0x3, %r11d
jl 0x264e3
xorl %r14d, %r14d
xorl %r15d, %r15d
movq $0x0, 0x8(%rsp)
xorl %r13d, %r13d
movq 0x10(%rsp), %rdi
cmpl $0x0, (%rsp)
jle 0x2635b
movl $0xc, %ebp
imulq $0x4b0, %r13, %rbx      # imm = 0x4B0
xorl %r12d, %r12d
leaq 0xc(%rdi), %r10
leaq (%rdi,%r14), %rdx
movq 0x4e58(%rsp), %rax
addq %r15, %rax
movzwl (%rax,%r12,2), %ecx
movb (%rbp,%rdx), %r9b
cmpb $0x2, %r9b
jne 0x26257
movl %ecx, %eax
andl $0x100, %eax            # imm = 0x100
je 0x26257
movsbl 0x4(%rbp,%rdx), %eax
addl %r12d, %eax
cltq
addq %rbx, %r10
leaq (%rax,%rax,2), %rax
cmpb $0x2, (%r10,%rax,4)
je 0x26288
movl %ecx, %r8d
jmp 0x26292
cmpb $0x1, %r9b
setne %sil
jne 0x262d0
movl %ecx, %eax
movl %ecx, %r8d
andl $0x10, %eax
je 0x26295
movsbl 0x4(%rbp,%rdx), %eax
addl %r12d, %eax
cltq
addq %rbx, %r10
leaq (%rax,%rax,2), %rax
cmpb $0x1, (%r10,%rax,4)
je 0x262d5
movl %ecx, %r8d
jmp 0x262dc
movl %ecx, %r8d
andl $0xfffffeff, %r8d       # imm = 0xFFFFFEFF
movb $0x1, %sil
cmpb $0x2, %r9b
jne 0x262de
movl %ecx, %eax
andl $0x800, %eax            # imm = 0x800
je 0x262de
movsbl 0x7(%rbp,%rdx), %eax
addl %r13d, %eax
cltq
imulq $0x4b0, %rax, %rax      # imm = 0x4B0
addq %rdi, %rax
movl %r8d, %r9d
andl $0xfffff7ff, %r9d       # imm = 0xFFFFF7FF
cmpb $0x2, (%rbp,%rax)
cmovnel %r8d, %r9d
movl %r9d, %r8d
jmp 0x262de
movl %ecx, %r8d
jmp 0x26295
movl %ecx, %r8d
andl $-0x11, %r8d
xorl %esi, %esi
testb %sil, %sil
jne 0x26315
movl %ecx, %eax
andl $0x80, %eax
je 0x26315
movsbl 0x7(%rbp,%rdx), %eax
addl %r13d, %eax
cltq
imulq $0x4b0, %rax, %rax      # imm = 0x4B0
addq %rdi, %rax
movl %r8d, %edx
andl $0xffffff7f, %edx       # imm = 0xFFFFFF7F
cmpb $0x1, (%rbp,%rax)
cmovnel %r8d, %edx
movl %edx, %r8d
cmpw %r8w, %cx
je 0x26347
movq 0x8(%rsp), %rax
addl %r12d, %eax
movzwl %ax, %esi
movzwl %r8w, %edx
leaq 0x30(%rsp), %rdi
callq 0x275f0
testb %al, %al
je 0x2655e
movq 0x30(%rsp), %rdi
movl (%rdi), %eax
movq %rax, (%rsp)
incq %r12
movslq (%rsp), %rax
addq $0xc, %rbp
cmpq %rax, %r12
jl 0x2620e
incq %r13
movslq 0x4(%rdi), %rcx
addq $0x64, 0x8(%rsp)
addq $0xc8, %r15
addq $0x4b0, %r14            # imm = 0x4B0
cmpq %rcx, %r13
jl 0x261f5
testl %ecx, %ecx
jg 0x264e8
jmp 0x26393
cmpl $0x0, 0x8(%rdi)
je 0x264df
leaq 0x30(%rsp), %rdi
xorl %ebx, %ebx
xorl %esi, %esi
callq 0x27c02
testl %eax, %eax
jle 0x26560
movq 0x30(%rsp), %rdi
cmpl $0x0, 0x4(%rdi)
jle 0x26492
xorl %ebx, %ebx
cmpl $0x0, (%rdi)
jle 0x26482
imulq $0xc8, %rbx, %rax
movq %rax, (%rsp)
imulq $0x4b0, %rbx, %r12      # imm = 0x4B0
xorl %r14d, %r14d
leaq (%r14,%r14), %rax
addq 0x4e58(%rsp), %rax
movq (%rsp), %rcx
movzwl (%rcx,%rax), %eax
movl %eax, %ecx
notl %ecx
andl $0x1, %ecx
xorl %r15d, %r15d
testb $0x11, %al
sete %r15b
movl %eax, %edx
andl $0x111, %edx            # imm = 0x111
cmpl $0x1, %edx
adcw %cx, %r15w
xorl %ecx, %ecx
testb $0x8, %al
sete %cl
xorl %ebp, %ebp
testb $-0x78, %al
sete %bpl
andl $0x888, %eax            # imm = 0x888
cmpl $0x1, %eax
adcw %cx, %bp
leaq (%rdi,%r12), %rax
leaq (%r14,%r14,2), %r13
movzbl 0x14(%rax,%r13,4), %eax
cmpw %ax, %r15w
je 0x26464
movl %r14d, %esi
movl %ebx, %edx
xorl %ecx, %ecx
callq 0x22f08
movq 0x30(%rsp), %rdi
leaq (%rdi,%r12), %rax
jmp 0x2642d
movl %r14d, %esi
movl %ebx, %edx
movl $0x3, %ecx
callq 0x22f08
movq 0x30(%rsp), %rdi
leaq (%rdi,%r12), %rax
movzbl 0x17(%rax,%r13,4), %eax
cmpw %ax, %bp
jne 0x26450
incq %r14
movslq (%rdi), %rax
cmpq %rax, %r14
jl 0x263d8
incq %rbx
movslq 0x4(%rdi), %rax
cmpq %rax, %rbx
jl 0x263ba
callq 0x2314a
movb $0x1, %bl
testb %al, %al
jne 0x26560
leaq 0xc9e4(%rip), %rdi      # 0x32e8c
callq 0x3590
movq 0x30(%rsp), %rsi
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0x2335a
cmpb $0x0, 0xf(%rbx)
movq %rbx, %rdi
jns 0x264cd
movq 0x20(%rsp), %rdi
callq 0x3590
movq %rbx, %rdi
callq 0x2a87c
callq 0x3180
movb $0x1, %bl
jmp 0x26560
movq 0x10(%rsp), %rdi
movl $0xe, %r14d
xorl %r15d, %r15d
leaq 0x30(%rsp), %rbx
xorl %r12d, %r12d
cmpl $0x0, (%rsp)
jle 0x26542
movq %r14, %r13
xorl %ebp, %ebp
movswq (%rdi,%r13), %rax
leaq (%r15,%rbp), %rcx
movl %eax, %eax
cmpq %rax, %rcx
jne 0x26532
leal (%r15,%rbp), %eax
movzwl %ax, %esi
movq %rbx, %rdi
callq 0x2782e
testb %al, %al
je 0x2655e
movq 0x30(%rsp), %rdi
movl (%rdi), %eax
movq %rax, (%rsp)
incq %rbp
movslq (%rsp), %rax
addq $0xc, %r13
cmpq %rax, %rbp
jl 0x26504
incq %r12
movslq 0x4(%rdi), %rax
addq $0x64, %r15
addq $0x4b0, %r14            # imm = 0x4B0
cmpq %rax, %r12
jl 0x264f9
jmp 0x26393
xorl %ebx, %ebx
movl %ebx, %eax
addq $0xc8368, %rsp          # imm = 0xC8368
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq