// File: /workspace/github_cpp_makefile_star2_O2/razimantv[P]DancingLinks/sudoku/../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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r8, 0x28(%rsp)
movl %edx, %eax
orl %esi, %eax
orl %ecx, %eax
js 0x195e
movl %ecx, %ebx
movq %rdi, %r15
movq %rsi, %r12
movl %edx, 0x8(%rsp)
addl %edx, %ebx
callq 0x1632
movq %rbx, %r14
shlq $0x5, %rbx
leaq 0x8(%rbx), %rdi
movq %rdi, (%rsp)
callq 0x1030
movq %r14, (%rax)
movq %rax, 0x10(%rsp)
leaq 0x8(%rax), %r13
movq %r14, 0x18(%rsp)
testl %r14d, %r14d
je 0x1728
negq %rbx
xorl %r14d, %r14d
movq %r13, %rbp
movq %rbp, %rdi
callq 0x1fb4
addq $-0x20, %r14
addq $0x20, %rbp
cmpq %r14, %rbx
jne 0x1713
movq (%r15), %rax
movq %r13, 0x8(%rax)
movq 0x18(%rsp), %rbx
movslq %ebx, %rcx
leal -0x1(%rbx), %r15d
shlq $0x5, %rcx
addq %r13, %rcx
addq $-0x20, %rcx
movq %rcx, (%rax)
movq 0x10(%rsp), %rdx
movq %rax, 0x8(%rdx)
movq %rax, 0x8(%rcx)
xorl %eax, %eax
testl %r15d, %r15d
cmovgl %r15d, %eax
leaq 0x28(%rdx), %rcx
subq $0x1, %rax
jb 0x177a
leaq -0x20(%rcx), %rdx
movq %rcx, -0x18(%rcx)
movq %rdx, (%rcx)
addq $0x20, %rcx
jmp 0x1763
movslq 0x8(%rsp), %rax
xorl %ecx, %ecx
testl %ebx, %ebx
movl $0x0, %edx
cmovgl %ebx, %edx
movq %rdx, 0x8(%rsp)
movq 0x10(%rsp), %rdx
addq $0x24, %rdx
cmpq %rcx, 0x8(%rsp)
je 0x17b3
movl %r12d, -0x4(%rdx)
cmpq %rax, %rcx
setl (%rdx)
incq %rcx
addq $0x20, %rdx
jmp 0x1799
imull %r12d, %ebx
imulq $0x30, %rbx, %rbp
movq %rbp, %rdi
callq 0x1030
movq %rax, (%rsp)
testl %ebx, %ebx
je 0x17e3
xorl %ebx, %ebx
movq (%rsp), %rax
leaq (%rax,%rbx), %rdi
callq 0x1f54
addq $0x30, %rbx
cmpq %rbx, %rbp
jne 0x17cd
movq (%rsp), %rdx
leaq -0x30(%rdx), %rsi
leal -0x1(%r12), %eax
movq 0x18(%rsp), %rcx
imull %ecx, %eax
movslq %ecx, %rdi
movslq %eax, %r8
xorl %r9d, %r9d
testl %r12d, %r12d
cmovlel %r9d, %r12d
movq %r12, 0x20(%rsp)
imulq $0x30, 0x8(%rsp), %r10
addq $0x18, 0x10(%rsp)
imulq $-0x30, %rdi, %rax
addq %rdx, %rax
movq %rax, 0x30(%rsp)
xorl %r12d, %r12d
cmpl 0x20(%rsp), %r9d
je 0x18f7
movslq %r12d, %r12
imulq $0x30, %r12, %rbp
movq 0x30(%rsp), %rax
leaq (%rax,%rbp), %r11
leaq (%rdi,%r12), %rax
imulq $0x30, %rax, %r14
movq (%rsp), %rax
addq %rax, %r14
addq %rax, %rbp
movq 0x10(%rsp), %r13
xorl %ebx, %ebx
cmpq %rbx, %r10
je 0x18ef
movl %r9d, 0x28(%rbp,%rbx)
leaq -0x10(%r13), %rax
movq %rax, 0x20(%rbp,%rbx)
movl %r12d, %eax
cltd
idivl 0x18(%rsp)
testl %edx, %edx
je 0x1884
movq %r12, %rcx
jmp 0x1888
leaq (%rdi,%r12), %rcx
leaq (%rbx,%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rsi, %rcx
movq %rcx, (%rbp,%rbx)
cmpl %r15d, %edx
je 0x18a2
movq %rax, %rdx
jmp 0x18a6
leaq (%r11,%rbx), %rdx
addq $0x30, %rdx
movq %rdx, 0x8(%rbp,%rbx)
cmpq %rdi, %r12
jge 0x18be
movq (%r13), %rdx
movq %rax, 0x18(%rdx)
jmp 0x18c2
leaq (%r11,%rbx), %rdx
movq %rdx, 0x10(%rbp,%rbx)
cmpq %r8, %r12
jge 0x18d2
leaq (%r14,%rbx), %rdx
jmp 0x18da
movq (%r13), %rdx
movq %rax, 0x10(%rdx)
movq %rdx, 0x18(%rbp,%rbx)
incq %r12
addq $0x30, %rbx
addq $0x20, %r13
jmp 0x185c
incl %r9d
jmp 0x1828
xorl %r14d, %r14d
movq 0x8(%rsp), %rax
movl %eax, %ebx
xorl %ebp, %ebp
movq 0x28(%rsp), %rax
cmpl 0x20(%rsp), %ebp
je 0x194f
movslq %ebx, %r12
movslq %r14d, %r13
imulq $0x30, %r13, %r15
addq (%rsp), %r15
movq 0x8(%rsp), %rcx
leal (%rcx,%r13), %r14d
cmpq %r13, %r12
je 0x1947
cmpb $0x0, (%rax,%r13)
jne 0x193e
movq %r15, %rdi
callq 0x1f98
movq 0x28(%rsp), %rax
incq %r13
addq $0x30, %r15
jmp 0x1925
incl %ebp
addl 0x8(%rsp), %ebx
jmp 0x1908
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x16e0(%rip), %rdi      # 0x3045
leaq 0x16fc(%rip), %rsi      # 0x3068
leaq 0x1716(%rip), %rcx      # 0x3089
pushq $0x28
popq %rdx
callq 0x10a0
movq %rax, %rbx
movq (%rsp), %rdi
movq %rbp, %rsi
jmp 0x19b3
movq %rax, %rbx
testq %r14, %r14
je 0x19aa
negq %r14
movq 0x10(%rsp), %r15
addq $-0x18, %r15
leaq (%r15,%r14), %rdi
callq 0x1ffe
addq $-0x20, %r14
jne 0x199b
movq 0x10(%rsp), %rdi
movq (%rsp), %rsi
callq 0x1160
movq %rbx, %rdi
callq 0x1150