// File: /workspace/github_cpp_makefile_star2_O1/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, 0x30(%rsp)
movl %edx, %eax
movq %rsi, 0x18(%rsp)
orl %esi, %eax
orl %ecx, %eax
js 0x1990
movl %ecx, %r14d
movq %rdi, %r13
movl %edx, (%rsp)
addl %edx, %r14d
callq 0x1636
movq %r14, %rbx
shlq $0x5, %rbx
leaq 0x8(%rbx), %rdi
movq %rdi, 0x10(%rsp)
callq 0x1030
movq %r14, (%rax)
movq %rax, 0x8(%rsp)
leaq 0x8(%rax), %r12
testl %r14d, %r14d
je 0x1731
negq %rbx
xorl %r15d, %r15d
movq %r12, %rbp
movq %rbp, %rdi
callq 0x1fdc
addq $-0x20, %r15
addq $0x20, %rbp
cmpq %r15, %rbx
jne 0x171c
movq (%r13), %rax
movq %r12, 0x8(%rax)
movslq %r14d, %rcx
leal -0x1(%r14), %edx
movl %edx, 0x10(%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 0x178e
movl 0x10(%rsp), %ecx
cmpl $0x2, %ecx
movl $0x1, %eax
cmovgel %ecx, %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 0x177a
testl %r14d, %r14d
movq 0x18(%rsp), %r12
jle 0x17bd
movslq (%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 0x17a7
movl %r14d, %r15d
imull %r12d, %r15d
movq %r15, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rbp
movq %rbp, %rdi
callq 0x1030
movq %rax, (%rsp)
testl %r15d, %r15d
je 0x17f9
xorl %r15d, %r15d
movq (%rsp), %rax
leaq (%rax,%r15), %rdi
callq 0x1f60
addq $0x30, %r15
cmpq %r15, %rbp
jne 0x17e3
testl %r12d, %r12d
jle 0x192e
leal -0x1(%r12), %eax
imull %r14d, %eax
movslq %r14d, %rsi
movslq %eax, %rdi
leaq (%rsi,%rsi,2), %rax
shlq $0x4, %rax
movq (%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x28(%rsp)
movq %rsi, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rax
subq %rax, %rcx
movq %rcx, 0x20(%rsp)
addq $0x18, 0x8(%rsp)
movq %r14, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %r10
xorl %ecx, %ecx
xorl %r11d, %r11d
testl %r14d, %r14d
jle 0x1922
movslq %ecx, %rcx
movq %rcx, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rbp
movq 0x28(%rsp), %rax
leaq (%rax,%rbp), %r12
movq (%rsp), %rax
leaq (%rax,%rbp), %r9
addq 0x20(%rsp), %rbp
movq 0x8(%rsp), %r8
xorl %r15d, %r15d
leaq (%r9,%r15), %r13
movl %r11d, 0x28(%r9,%r15)
leaq -0x10(%r8), %rax
movq %rax, 0x20(%r9,%r15)
movl %ecx, %eax
cltd
idivl %r14d
testl %edx, %edx
movl $0x0, %eax
cmovel %r14d, %eax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
addq %r15, %rax
leaq (%r9,%rax), %rbx
addq $-0x30, %rbx
leaq (%r15,%rbp), %rax
cmpl 0x10(%rsp), %edx
movq %r13, %rdx
cmoveq %rax, %rdx
movq %rbx, (%r9,%r15)
addq $0x30, %rdx
movq %rdx, 0x8(%r9,%r15)
cmpq %rsi, %rcx
jge 0x18e8
movq (%r8), %rax
movq %rax, 0x10(%r9,%r15)
movq %r13, 0x18(%rax)
jmp 0x18ed
movq %rax, 0x10(%r9,%r15)
cmpq %rdi, %rcx
jge 0x18fd
leaq (%r12,%r15), %rax
movq %rax, 0x18(%r9,%r15)
jmp 0x1909
movq (%r8), %rax
movq %rax, 0x18(%r9,%r15)
movq %r13, 0x10(%rax)
incq %rcx
addq $0x30, %r15
addq $0x20, %r8
cmpq %r15, %r10
jne 0x1883
movq 0x18(%rsp), %r12
incl %r11d
cmpl %r12d, %r11d
jne 0x184e
testl %r12d, %r12d
jle 0x1981
xorl %ebx, %ebx
xorl %ebp, %ebp
testl %r14d, %r14d
jle 0x197a
movslq %ebx, %rax
movq 0x30(%rsp), %rcx
leaq (%rcx,%rax), %r15
leaq (%rax,%rax,2), %r12
shlq $0x4, %r12
addq (%rsp), %r12
xorl %r13d, %r13d
cmpb $0x0, (%r15,%r13)
jne 0x1966
movq %r12, %rdi
callq 0x1fae
incq %r13
addq $0x30, %r12
cmpl %r13d, %r14d
jne 0x1957
addl %r13d, %ebx
movq 0x18(%rsp), %r12
incl %ebp
cmpl %r12d, %ebp
jne 0x1937
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x16ae(%rip), %rdi      # 0x3045
leaq 0x16ca(%rip), %rsi      # 0x3068
leaq 0x16e4(%rip), %rcx      # 0x3089
movl $0x28, %edx
callq 0x10a0
movq %rax, %rbx
movq (%rsp), %rdi
movq %rbp, %rsi
jmp 0x19e8
movq %rax, %rbx
testq %r15, %r15
je 0x19de
negq %r15
movq 0x8(%rsp), %r14
addq $-0x18, %r14
leaq (%r14,%r15), %rdi
callq 0x202e
addq $-0x20, %r15
jne 0x19cf
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x1160
movq %rbx, %rdi
callq 0x1150
nop