// File: /workspace/github_c_makefile_star2_O2/barabo[P]advanced-shell-history/src/formatter.cpp
// Function: get_grouped_level_count(ash::ResultSet const*, std::vector<unsigned long, std::allocator<unsigned long>> const&)
int get_grouped_level_count(const ResultSet * rs, const vector<size_t> & widths)
{
  if (!rs) return 0;  // Sanity check.

  size_t width = 0, length = rs -> rows, XX = 4;
  for (size_t i = 0, e = widths.size(); i != e; ++i) width += widths[i];
  size_t min_area = length * width;
  
  // examine the columns from left to right simulating how much screen space
  // would be saved by grouping that column.  If there is a net reduction in
  // screen 'area', then the column will be grouped.  Otherwise it will not.

  // store area of output after simulating grouping at each level successively.
  // the rightmost minimum area will be chosen.
  //
  // For example, consider the following areas after simulating grouping:
  //   areas = [100, 90, 92, 90, 140, 281]
  //
  // With 1 level of grouping and with 3 levels of grouping we get the same
  // screen area, however the rightmost value is chosen, so the return value
  // will be 3.
  vector<size_t> areas(widths.size(), width * length);
  
  string prev;
  for (size_t c = 0, cols = rs -> columns; c < cols; ++c) {
    // test each row in the column to see if it is a duplicate of the previous
    // row.  If so, it will be de-duped in the output.  If not, it means an
    // extra row will be added, so we adjust the new_len variable accordingly.
    prev = "";
    for (size_t r = 0, rows = rs -> rows; r < rows; ++r) {
      if (prev != rs -> data[r][c]) {
        ++length;
        prev = rs -> data[r][c];
      }
    }
    // to calculate the new width, we need to consider both the width of the 
    // grouped column and the width of the remaining columns.  we also need to
    // consider the width of the indent.
    width = max(width - widths[c], widths[c]) + XX * (c + 1);
    min_area = min(length * width, min_area);
    if (c < rs -> columns - 1) areas[c + 1] = width * length;
  }
  // Find the rightmost minimum area from all simulated areas.
  for (size_t c = rs -> columns; c > 0; --c) {
    if (areas[c - 1] == min_area) return c - 1;
  }
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
testq %rdi, %rdi
je 0x61ae7
movq %rsi, %r14
movq %rdi, %rbx
movq 0x30(%rdi), %r13
movq (%rsi), %rax
movq 0x8(%rsi), %rsi
subq %rax, %rsi
sarq $0x3, %rsi
xorl %ecx, %ecx
xorl %ebp, %ebp
cmpq %rcx, %rsi
je 0x61995
addq (%rax,%rcx,8), %rbp
incq %rcx
jmp 0x61987
movq %rbp, %r12
imulq %r13, %r12
leaq 0x48(%rsp), %r15
movq %r12, (%r15)
leaq 0x30(%rsp), %rdi
leaq 0x7(%rsp), %rcx
movq %r15, %rdx
callq 0x61fda
leaq 0x58(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq 0x38(%rbx), %rax
movq %rax, 0x18(%rsp)
xorl %eax, %eax
movq %r14, 0x10(%rsp)
movq %rax, 0x8(%rsp)
cmpq 0x18(%rsp), %rax
je 0x61aa3
movq %rbp, 0x20(%rsp)
movq %r12, 0x28(%rsp)
movq %r15, %rdi
leaq 0xe94a(%rip), %rsi      # 0x70345
callq 0x87a0
movq 0x30(%rbx), %r12
movq 0x8(%rsp), %r14
shlq $0x5, %r14
xorl %ebp, %ebp
subq $0x1, %r12
jb 0x61a48
movq 0x18(%rbx), %rax
movq (%rax,%rbp), %rsi
addq %r14, %rsi
movq %r15, %rdi
callq 0x5c562
testb %al, %al
je 0x61a42
movq 0x18(%rbx), %rax
movq (%rax,%rbp), %rsi
addq %r14, %rsi
movq %r15, %rdi
callq 0x81d0
incq %r13
addq $0x18, %rbp
jmp 0x61a0f
movq 0x10(%rsp), %r14
movq (%r14), %rax
movq 0x8(%rsp), %rsi
movq (%rax,%rsi,8), %rax
movq 0x20(%rsp), %rbp
subq %rax, %rbp
cmpq %rax, %rbp
cmovbeq %rax, %rbp
leaq 0x4(%rbp,%rsi,4), %rbp
movq %rbp, %rcx
imulq %r13, %rcx
movq 0x28(%rsp), %r12
cmpq %rcx, %r12
cmovaeq %rcx, %r12
leaq 0x1(%rsi), %rax
movq 0x38(%rbx), %rdx
decq %rdx
cmpq %rdx, %rsi
jae 0x619d7
movq 0x30(%rsp), %rdx
movq %rcx, 0x8(%rdx,%rsi,8)
jmp 0x619d7
movq 0x38(%rbx), %rax
movq 0x30(%rsp), %rcx
leaq (%rcx,%rax,8), %rcx
addq $-0x8, %rcx
xorl %ebx, %ebx
xorl %edx, %edx
movq %rax, %rsi
addq %rdx, %rsi
je 0x61ad1
leaq -0x1(%rdx), %rsi
cmpq %r12, (%rcx,%rdx,8)
movq %rsi, %rdx
jne 0x61ab8
addl %esi, %eax
movl %eax, %ebx
leaq 0x48(%rsp), %rdi
callq 0x84b0
leaq 0x30(%rsp), %rdi
callq 0x6253a
jmp 0x61ae9
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x61b0e
jmp 0x61b01
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x84b0
leaq 0x30(%rsp), %rdi
callq 0x6253a
movq %rbx, %rdi
callq 0x86f0
movq %rax, %rdi
callq 0x5c505