// File: /workspace/github_cpp_makefile_star2_O3/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
movq %rsi, 0x20(%rsp)
orl %esi, %eax
orl %ecx, %eax
js 0x19a0
movl %ecx, %r14d
movq %rdi, %r13
movl %edx, 0x10(%rsp)
addl %edx, %r14d
callq 0x1658
movq %r14, %rbp
shlq $0x5, %rbp
leaq 0x8(%rbp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x1030
movq %r14, (%rax)
movq %rax, 0x8(%rsp)
leaq 0x8(%rax), %r12
testl %r14d, %r14d
je 0x1754
negq %rbp
xorl %r15d, %r15d
movq %r12, %rbx
movq %rbx, %rdi
callq 0x1fcc
addq $-0x20, %r15
addq $0x20, %rbx
cmpq %r15, %rbp
jne 0x173f
movq (%r13), %rax
movq %r12, 0x8(%rax)
movslq %r14d, %rcx
leal -0x1(%r14), %edx
movl %edx, 0x18(%rsp)
movq %rcx, %rdx
shlq $0x5, %rdx
addq %r12, %rdx
addq $-0x20, %rdx
movq %rdx, (%rax)
movq %rax, (%r12)
movq %rax, 0x8(%rdx)
cmpl $0x2, %ecx
jl 0x17a6
movl 0x18(%rsp), %eax
movq 0x8(%rsp), %rcx
addq $0x28, %rcx
leaq -0x20(%rcx), %rdx
movq %rcx, -0x18(%rcx)
movq %rdx, (%rcx)
addq $0x20, %rcx
decq %rax
jne 0x1792
testl %r14d, %r14d
movq 0x20(%rsp), %r12
jle 0x17d6
movslq 0x10(%rsp), %rax
movq 0x8(%rsp), %rcx
addq $0x24, %rcx
xorl %edx, %edx
movl %r12d, -0x4(%rcx)
cmpq %rax, %rdx
setl (%rcx)
incq %rdx
addq $0x20, %rcx
cmpq %rdx, %r14
jne 0x17c0
movl %r14d, %ebx
imull %r12d, %ebx
movq %rbx, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rbp
movq %rbp, %rdi
callq 0x1030
movq %rax, %r13
testl %ebx, %ebx
je 0x180c
xorl %r15d, %r15d
leaq (%r15,%r13), %rdi
callq 0x1f5c
addq $0x30, %r15
cmpq %r15, %rbp
jne 0x17fa
testl %r12d, %r12d
jle 0x1991
leaq -0x30(%r13), %rsi
leal -0x1(%r12), %eax
imull %r14d, %eax
movslq %r14d, %rdi
movslq %eax, %r8
movq %rdi, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rax
movq %r13, %rcx
subq %rax, %rcx
movq %rcx, 0x30(%rsp)
addq $0x18, 0x8(%rsp)
movq %r14, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %r10
xorl %ecx, %ecx
xorl %r11d, %r11d
movq %r13, 0x10(%rsp)
testl %r14d, %r14d
jle 0x192e
movslq %ecx, %rcx
movq %rcx, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rbp
movq %r13, %r12
addq %rbp, %r12
leaq (%rdi,%rcx), %rax
leaq (%rax,%rax,2), %r9
shlq $0x4, %r9
addq %r13, %r9
addq 0x30(%rsp), %rbp
movq 0x8(%rsp), %r15
xorl %r13d, %r13d
movl %r11d, 0x28(%r12,%r13)
leaq -0x10(%r15), %rax
movq %rax, 0x20(%r12,%r13)
movl %ecx, %eax
cltd
idivl %r14d
testl %edx, %edx
je 0x18af
movq %rcx, %rbx
jmp 0x18b3
leaq (%rdi,%rcx), %rbx
leaq (%r12,%r13), %rax
leaq (%rbx,%rbx,2), %rbx
shlq $0x4, %rbx
addq %rsi, %rbx
movq %rbx, (%r12,%r13)
cmpl 0x18(%rsp), %edx
je 0x18d1
movq %rax, %rdx
jmp 0x18d7
movq %rbp, %rdx
addq %r13, %rdx
addq $0x30, %rdx
movq %rdx, 0x8(%r12,%r13)
cmpq %rdi, %rcx
jge 0x18ee
movq (%r15), %rdx
movq %rax, 0x18(%rdx)
jmp 0x18f4
movq %rbp, %rdx
addq %r13, %rdx
movq %rdx, 0x10(%r12,%r13)
cmpq %r8, %rcx
jge 0x1904
leaq (%r9,%r13), %rdx
jmp 0x190b
movq (%r15), %rdx
movq %rax, 0x10(%rdx)
movq %rdx, 0x18(%r12,%r13)
incq %rcx
addq $0x30, %r13
addq $0x20, %r15
cmpq %r13, %r10
jne 0x1892
movq 0x20(%rsp), %r12
movq 0x10(%rsp), %r13
incl %r11d
cmpl %r12d, %r11d
jne 0x1859
testl %r12d, %r12d
jle 0x1991
xorl %ebx, %ebx
xorl %ebp, %ebp
testl %r14d, %r14d
jle 0x198a
movslq %ebx, %rax
movq 0x28(%rsp), %rcx
leaq (%rcx,%rax), %r15
leaq (%rax,%rax,2), %r12
shlq $0x4, %r12
addq %r13, %r12
xorl %r13d, %r13d
cmpb $0x0, (%r15,%r13)
jne 0x1971
movq %r12, %rdi
callq 0x1fa6
incq %r13
addq $0x30, %r12
cmpl %r13d, %r14d
jne 0x1962
addl %r13d, %ebx
movq 0x20(%rsp), %r12
movq 0x10(%rsp), %r13
incl %ebp
cmpl %r12d, %ebp
jne 0x1943
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x169e(%rip), %rdi      # 0x3045
leaq 0x16ba(%rip), %rsi      # 0x3068
leaq 0x16d4(%rip), %rcx      # 0x3089
movl $0x28, %edx
callq 0x10a0
movq %rax, %rbx
movq %r13, %rdi
movq %rbp, %rsi
jmp 0x19f7
movq %rax, %rbx
testq %r15, %r15
je 0x19ed
negq %r15
movq 0x8(%rsp), %r14
addq $-0x18, %r14
leaq (%r14,%r15), %rdi
callq 0x201e
addq $-0x20, %r15
jne 0x19de
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
callq 0x1160
movq %rbx, %rdi
callq 0x1150