Module: StackingOrder
- Defined in:
- lib/stacking_order.rb,
lib/stacking_order/version.rb
Overview
Calculates how to print entries in a grid so that stack-cut pages reassemble into sequential order.
Constant Summary collapse
- VERSION =
'1.1.0'
Class Method Summary collapse
- .apply_two_sided_flip(result, rows, columns) ⇒ Object
- .flip_page_rows(page, rows, columns) ⇒ Object
-
.order(entries:, rows:, columns:, two_sided_flipped: false) ⇒ Array<Integer, nil>
Public API for calculating the stacking order for printing entries on pages with a grid layout.
- .pad_page(page, cells_per_page) ⇒ Object
-
.visualize(entries:, rows:, columns:, two_sided_flipped: false, io: $stdout) ⇒ Object
Utility method that prints the layout for the provided configuration, showing the entries on each page and the resulting stacks after cutting.
Class Method Details
.apply_two_sided_flip(result, rows, columns) ⇒ Object
80 81 82 83 84 85 86 |
# File 'lib/stacking_order.rb', line 80 def apply_two_sided_flip(result, rows, columns) cells_per_page = rows * columns result.each_slice(cells_per_page).with_index.flat_map do |page, page_index| padded_page = pad_page(page, cells_per_page) page_index.odd? ? flip_page_rows(padded_page, rows, columns) : padded_page end end |
.flip_page_rows(page, rows, columns) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/stacking_order.rb', line 94 def flip_page_rows(page, rows, columns) if rows == 1 row_slice = page.slice(0, columns) || [] return row_slice.reverse end flipped = [] rows.times do |row_index| source_row_index = rows - 1 - row_index row_slice = page.slice(source_row_index * columns, columns) || [] flipped.concat(row_slice) end flipped end |
.order(entries:, rows:, columns:, two_sided_flipped: false) ⇒ Array<Integer, nil>
Public API for calculating the stacking order for printing entries on pages with a grid layout. See README for details.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/stacking_order.rb', line 17 def order(entries:, rows:, columns:, two_sided_flipped: false) validate_arguments!(entries, rows, columns) return [] if entries.zero? cells_per_page = rows * columns num_pages = (entries.to_f / cells_per_page).ceil result = [] num_pages.times do |page_index| cells_per_page.times do |cell_index| entry_number = (cell_index * num_pages) + page_index + 1 result << (entry_number <= entries ? entry_number : nil) end end if two_sided_flipped result = apply_two_sided_flip(result, rows, columns) end result.pop while result.last.nil? result end |
.pad_page(page, cells_per_page) ⇒ Object
88 89 90 91 92 |
# File 'lib/stacking_order.rb', line 88 def pad_page(page, cells_per_page) return page if page.length == cells_per_page page + Array.new(cells_per_page - page.length) end |
.visualize(entries:, rows:, columns:, two_sided_flipped: false, io: $stdout) ⇒ Object
Utility method that prints the layout for the provided configuration, showing the entries on each page and the resulting stacks after cutting. Useful for debugging or CLI demos.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/stacking_order.rb', line 45 def visualize(entries:, rows:, columns:, two_sided_flipped: false, io: $stdout) result = order(entries: entries, rows: rows, columns: columns, two_sided_flipped: two_sided_flipped) cells_per_page = rows * columns num_pages = (entries.to_f / cells_per_page).ceil io.puts io.puts('=' * 60) io.puts("Visualizing stacking order for #{entries} entries, #{rows} row(s), #{columns} column(s)") io.puts('=' * 60) io.puts("Result: #{result.inspect}") io.puts("\nPages layout:") result.each_slice(cells_per_page).with_index do |page, page_num| io.puts("\nPage #{page_num + 1}:") page.each_slice(columns).with_index do |row_values, row_num| formatted = row_values.map { |value| value ? format('%3d', value) : 'nil' }.join(' | ') io.puts(" Row #{row_num + 1}: #{formatted}") end end io.puts("\nAfter cutting and stacking:") cells_per_page.times do |cell_idx| row_idx = cell_idx / columns col_idx = cell_idx % columns stack = [] num_pages.times do |page_idx| pos = (page_idx * cells_per_page) + cell_idx stack << (pos < result.length ? result[pos] : nil) end io.puts(" Position [#{row_idx + 1},#{col_idx + 1}] stack (bottom→top): #{stack.compact.join(', ')}") end end |