Skip to content

Instantly share code, notes, and snippets.

@tompng
Created December 13, 2023 20:00
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 tompng/498b8ec5756eca58938d69d03e0d292f to your computer and use it in GitHub Desktop.
Save tompng/498b8ec5756eca58938d69d03e0d292f to your computer and use it in GitHub Desktop.
require 'matrix'
module RegexpMatrixSolver
refine Array do
def ~
keys = map(&:first).flat_map(&:keys).uniq
matrix = []
binding = first.last
vec = map{_2}
each do |values, rhs|
matrix << keys.map { values[_1] || 0 }
end
keys.zip Matrix[*matrix].lup.solve(vec) do
binding.local_variable_set _1, _2
end
end
end
refine Regexp do
def =~(binding)
segments = source.scan(/(^|[+-])(?:(?:(\d+)\*)?\(\?<([^<>]+)>\)(?:\*(\d+))?|(\d+))/)
values = Hash.new(0)
lhs = 0
segments.map do |sgn, n, name, m, c|
sign = sgn == '-' ? -1 : 1
if c
lhs += sign * c.to_i
else
values[name] += sign * (n || 1).to_i * (m || 1).to_i
end
end
[values, $rhs - lhs, binding]
end
end
refine Integer do
def ~
[$rhs = self].tap{
_1.singleton_class.class_eval{
alias ~ binding
public :~
}
}
end
end
end
using RegexpMatrixSolver
~[
/2*(?<x>)+3*(?<y>)-3/ =~~~ 5,
/2*(?<y>)-(?<z>)+3/ =~~~ 4,
/-(?<x>)+5*(?<y>)-2*(?<z>)/ =~~~ 3,
]
p [x, y, z] #=> [(1/1), (2/1), (3/1)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment