Skip to content

Instantly share code, notes, and snippets.

@zenspider
Created April 12, 2023 18:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zenspider/f73689ebca6d617028f49b9bff7885e3 to your computer and use it in GitHub Desktop.
Save zenspider/f73689ebca6d617028f49b9bff7885e3 to your computer and use it in GitHub Desktop.
class CompressedSystemStackError < StandardError # NOT SystemStackError
def self.raise_from sse
raise CompressedSystemStackError, sse.message, compress(sse.backtrace)
end
##
# Compress an array of strings by finding cycles within and
# reformatting them.
# ---
# FFS this is an unreadable mess. Please forgive, I didn't want to
# infect Enumerable.
def self.compress bt, max=3
bt.size # size
.times # 0...size = idxs
.group_by { |i| bt[i] } # val => [idx...]
.values # [[idx...]...]
.flat_map { |vs| vs.each_cons(2).map { |a, b| b-a } } # [lengths of repeats]
.then { |ary| # aka count_by(&:itself) # [lengths] => count
ary
.group_by(&:itself)
.transform_values(&:size)
.sort_by { |k, v| [-v, k] }
.to_h
}
.keys # [lengths]
.first(max) # top N lengths
.flat_map { |w| [w].product w.times.to_a } # [[w, 0], [w, 1], ...
.min_by { |w, o| cut_up(bt, w, o).uniq.size } # width, off
.then { |w, o| cut_up(bt, w, o).to_a } # [vals, [vals], ...]
.then { |ary| # aka count_chunks # [[len, val]...]
ary
.chunk(&:itself)
.map { |lines, a| [a.size, lines] }
}
.flat_map { |n, lines|
if n > 1 then
[
" +->> #{n} cycles of #{lines.size} lines:",
*lines.map { |s| " | #{s}" },
" +-<<",
]
else
lines
end
}
end
##
# [1, 2, 3, 4, 5].eswo(2, 1) => [[1], [2, 3], [4, 5]]
def self.cut_up bt, n, off # aka each_slice_with_offset
front, back = bt.take(off), bt.drop(off)
[front].chain back.each_slice(n)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment