// File: razimantv[P]DancingLinks/nqueens/../DancingLinks/DancingLinks.cpp
// Function: DancingLinks::Create(int, int, int, char*)
void DancingLinks::Create(int R, int C1, int C2, char *mat) {
  // Create linked structure
  assert((R >= 0) && (C1 >= 0) && (C2 >= 0));
  int C = C1 + C2;

  // Start by destroying existing structure, if any
  Destroy();

  // Allocate memory for the full structure
  // Being lavish here, essentially treating it like an adjacency matrix
  //  C DancingLinksColumns for columns and R*C DancingLinksCells for cells_
  //  TODO: Convert to an adjacency list maybe

  // First, the C columns
  DancingLinksColumn *columns_ = new DancingLinksColumn[C];

  // Set left and right links in both directions for the head
  dummycolumn_->set_right_ptr(&columns_[0]);
  dummycolumn_->set_left_ptr(&columns_[C - 1]);
  columns_[0].set_left_ptr(dummycolumn_);
  columns_[C - 1].set_right_ptr(dummycolumn_);

  // Set left and right pointers for remaining column elements
  for (int i = 0; i < C - 1; i++) {
    columns_[i].set_right_ptr(&columns_[i + 1]);
    columns_[i + 1].set_left_ptr(&columns_[i]);
  }

  // Set size and essentiality values for each column
  for (int i = 0; i < C; i++) {
    columns_[i].set_size(R);
    columns_[i].set_essential(i < C1);
  }

  // Now the cells
  DancingLinksCell *cells_ = new DancingLinksCell[R * C];

  // Assign row and column IDs and neighbours for all cells
  for (int i = 0, k = 0; i < R; i++) {
    for (int j = 0; j < C; j++, k++) {
      cells_[k].set_row_id(i);
      cells_[k].set_column_ptr(&columns_[j]);

      if (k % C == 0)
        cells_[k].set_left_ptr(&cells_[k + C - 1]);
      else
        cells_[k].set_left_ptr(&cells_[k - 1]);

      if (k % C == C - 1)
        cells_[k].set_right_ptr(&cells_[k - C + 1]);
      else
        cells_[k].set_right_ptr(&cells_[k + 1]);

      if (k < C) {
        cells_[k].set_up_ptr(columns_[j].dummycell());
        columns_[j].dummycell()->set_down_ptr(&cells_[k]);
      } else
        cells_[k].set_up_ptr(&cells_[k - C]);

      if (k >= (R - 1) * C) {
        cells_[k].set_down_ptr(columns_[j].dummycell());
        columns_[j].dummycell()->set_up_ptr(&cells_[k]);
      } else
        cells_[k].set_down_ptr(&cells_[k + C]);
    }
  }

  // If a matrix element is 0, delete it by changing neighbours' pointers
  for (int i = 0, k = 0; i < R; i++) {
    for (int j = 0; j < C; j++, k++) {
      if (mat[k] == 0) cells_[k].Erase();
    }
  }
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movq %rdi, 0x100(%rsp)
movl %esi, 0xfc(%rsp)
movl %edx, 0xf8(%rsp)
movl %ecx, 0xf4(%rsp)
movq %r8, 0xe8(%rsp)
movq 0x100(%rsp), %rax
movq %rax, 0x90(%rsp)
xorl %eax, %eax
cmpl $0x0, 0xfc(%rsp)
movb %al, 0x9f(%rsp)
jl 0x1fa4
xorl %eax, %eax
cmpl $0x0, 0xf8(%rsp)
movb %al, 0x9f(%rsp)
jl 0x1fa4
cmpl $0x0, 0xf4(%rsp)
setge %al
movb %al, 0x9f(%rsp)
movb 0x9f(%rsp), %al
testb $0x1, %al
jne 0x1fb1
jmp 0x1fb3
jmp 0x1fd2
leaq 0x308d(%rip), %rdi      # 0x5047
leaq 0x30a9(%rip), %rsi      # 0x506a
movl $0x28, %edx
leaq 0x30be(%rip), %rcx      # 0x508b
callq 0x10a0
movq 0x90(%rsp), %rdi
movl 0xf8(%rsp), %eax
addl 0xf4(%rsp), %eax
movl %eax, 0xe4(%rsp)
callq 0x1e20
movslq 0xe4(%rsp), %rax
movq %rax, 0x78(%rsp)
movl $0x20, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
addq $0x8, %rdi
setb %al
orb %al, %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x70(%rsp)
callq 0x1030
movq %rax, %rcx
movq 0x78(%rsp), %rax
movq %rcx, 0x80(%rsp)
movq %rax, (%rcx)
addq $0x8, %rcx
movq %rcx, 0x88(%rsp)
cmpq $0x0, %rax
je 0x209f
movq 0x88(%rsp), %rax
movq 0x78(%rsp), %rdx
shlq $0x5, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x60(%rsp)
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x46f0
jmp 0x2087
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %rax
addq $0x20, %rax
cmpq %rcx, %rax
movq %rax, 0x68(%rsp)
jne 0x2076
movq 0x90(%rsp), %rax
movq 0x88(%rsp), %rcx
movq %rcx, 0xd8(%rsp)
movq (%rax), %rdi
movq 0xd8(%rsp), %rsi
callq 0x2b00
movq 0x90(%rsp), %rax
movq (%rax), %rdi
movq 0xd8(%rsp), %rsi
movl 0xe4(%rsp), %eax
subl $0x1, %eax
cltq
shlq $0x5, %rax
addq %rax, %rsi
callq 0x2b20
movq 0x90(%rsp), %rax
movq 0xd8(%rsp), %rdi
movq (%rax), %rsi
callq 0x2b20
movq 0x90(%rsp), %rax
movq 0xd8(%rsp), %rdi
movl 0xe4(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x5, %rcx
addq %rcx, %rdi
movq (%rax), %rsi
callq 0x2b00
movl $0x0, 0xc8(%rsp)
movl 0xc8(%rsp), %eax
movl 0xe4(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x2248
movq 0xd8(%rsp), %rdi
movslq 0xc8(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rdi
movq 0xd8(%rsp), %rsi
movl 0xc8(%rsp), %eax
addl $0x1, %eax
cltq
shlq $0x5, %rax
addq %rax, %rsi
callq 0x2b00
movq 0xd8(%rsp), %rdi
movl 0xc8(%rsp), %eax
addl $0x1, %eax
cltq
shlq $0x5, %rax
addq %rax, %rdi
movq 0xd8(%rsp), %rsi
movslq 0xc8(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rsi
callq 0x2b20
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0x2141
movq 0x88(%rsp), %rcx
movq %rax, %rsi
movq 0x58(%rsp), %rax
movq %rsi, 0xd0(%rsp)
movl %edx, 0xcc(%rsp)
cmpq %rax, %rcx
movq %rax, 0x50(%rsp)
je 0x2231
movq 0x50(%rsp), %rdi
addq $-0x20, %rdi
movq %rdi, 0x48(%rsp)
callq 0x4780
movq 0x88(%rsp), %rcx
movq 0x48(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x50(%rsp)
jne 0x2207
movq 0x70(%rsp), %rsi
movq 0x80(%rsp), %rdi
callq 0x1150
jmp 0x2805
movl $0x0, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jge 0x22cc
movq 0xd8(%rsp), %rdi
movslq 0xc4(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rdi
movl 0xfc(%rsp), %esi
callq 0x2b40
movq 0xd8(%rsp), %rdi
movslq 0xc4(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rdi
movl 0xc4(%rsp), %eax
cmpl 0xf8(%rsp), %eax
setl %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x2ae0
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0x2253
movl 0xfc(%rsp), %eax
imull 0xe4(%rsp), %eax
cltq
movq %rax, 0x38(%rsp)
movl $0x30, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x30(%rsp)
callq 0x1030
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x40(%rsp)
cmpq $0x0, %rax
je 0x2362
movq 0x40(%rsp), %rax
movq 0x38(%rsp), %rcx
imulq $0x30, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x20(%rsp)
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x45a0
jmp 0x234a
movq 0x20(%rsp), %rcx
movq 0x18(%rsp), %rax
addq $0x30, %rax
cmpq %rcx, %rax
movq %rax, 0x28(%rsp)
jne 0x2339
movq 0x40(%rsp), %rax
movq %rax, 0xb8(%rsp)
movl $0x0, 0xb4(%rsp)
movl $0x0, 0xb0(%rsp)
movl 0xb4(%rsp), %eax
cmpl 0xfc(%rsp), %eax
jge 0x2745
movl $0x0, 0xac(%rsp)
movl 0xac(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jge 0x272d
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movl 0xb4(%rsp), %esi
callq 0x2b60
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0xd8(%rsp), %rsi
movslq 0xac(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rsi
callq 0x2b80
movl 0xb0(%rsp), %eax
cltd
idivl 0xe4(%rsp)
cmpl $0x0, %edx
jne 0x248a
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0xb8(%rsp), %rsi
movl 0xb0(%rsp), %eax
addl 0xe4(%rsp), %eax
subl $0x1, %eax
cltq
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2ba0
jmp 0x24c1
movq 0x30(%rsp), %rsi
movq 0x40(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
callq 0x1150
jmp 0x2805
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0xb8(%rsp), %rsi
movl 0xb0(%rsp), %eax
subl $0x1, %eax
cltq
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2ba0
movl 0xb0(%rsp), %eax
cltd
idivl 0xe4(%rsp)
movl 0xe4(%rsp), %eax
subl $0x1, %eax
cmpl %eax, %edx
jne 0x251e
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0xb8(%rsp), %rsi
movl 0xb0(%rsp), %eax
subl 0xe4(%rsp), %eax
addl $0x1, %eax
cltq
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2bc0
jmp 0x2555
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0xb8(%rsp), %rsi
movl 0xb0(%rsp), %eax
addl $0x1, %eax
cltq
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2bc0
movl 0xb0(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jge 0x25eb
movq 0xb8(%rsp), %rax
movslq 0xb0(%rsp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x10(%rsp)
movq 0xd8(%rsp), %rdi
movslq 0xac(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rdi
callq 0x2c00
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x2be0
movq 0xd8(%rsp), %rdi
movslq 0xac(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rdi
callq 0x2c00
movq %rax, %rdi
movq 0xb8(%rsp), %rsi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2c10
jmp 0x2626
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0xb8(%rsp), %rsi
movl 0xb0(%rsp), %eax
subl 0xe4(%rsp), %eax
cltq
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2be0
movl 0xb0(%rsp), %eax
movl 0xfc(%rsp), %ecx
subl $0x1, %ecx
imull 0xe4(%rsp), %ecx
cmpl %ecx, %eax
jl 0x26c9
movq 0xb8(%rsp), %rax
movslq 0xb0(%rsp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x8(%rsp)
movq 0xd8(%rsp), %rdi
movslq 0xac(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rdi
callq 0x2c00
movq 0x8(%rsp), %rdi
movq %rax, %rsi
callq 0x2c10
movq 0xd8(%rsp), %rdi
movslq 0xac(%rsp), %rax
shlq $0x5, %rax
addq %rax, %rdi
callq 0x2c00
movq %rax, %rdi
movq 0xb8(%rsp), %rsi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2be0
jmp 0x2704
movq 0xb8(%rsp), %rdi
movslq 0xb0(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq 0xb8(%rsp), %rsi
movl 0xb0(%rsp), %eax
addl 0xe4(%rsp), %eax
cltq
imulq $0x30, %rax, %rax
addq %rax, %rsi
callq 0x2c10
jmp 0x2706
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
movl 0xb0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb0(%rsp)
jmp 0x23a4
jmp 0x272f
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x2385
movl $0x0, 0xa8(%rsp)
movl $0x0, 0xa4(%rsp)
movl 0xa8(%rsp), %eax
cmpl 0xfc(%rsp), %eax
jge 0x27fd
movl $0x0, 0xa0(%rsp)
movl 0xa0(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jge 0x27e5
movq 0xe8(%rsp), %rax
movslq 0xa4(%rsp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x27bf
movq 0xb8(%rsp), %rdi
movslq 0xa4(%rsp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
callq 0x4670
jmp 0x27c1
movl 0xa0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa0(%rsp)
movl 0xa4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa4(%rsp)
jmp 0x277a
jmp 0x27e7
movl 0xa8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa8(%rsp)
jmp 0x275b
addq $0x108, %rsp            # imm = 0x108
retq
movq 0xd0(%rsp), %rdi
callq 0x1140
nopw %cs:(%rax,%rax)