bin/exord
#!/usr/bin/env ruby
# by stephan.com _
# _____ _____ _ __ __| |
# / _ \ \/ / _ \| '__/ _` |
# | __/> < (_) | | | (_| |
# \___/_/\_\___/|_| \__,_|
# exord - for exact orders
# based on XKCD 287 - https://xkcd.com/287/
# in fulfillment of a programming challenge
require 'methadone'
require 'pry'
require 'exord'
include Methadone::Main
include Methadone::CLILogging
include Exord
Money.locale_backend = :currency
main do |filename|
total = 0
menu = Menu.new(options[:restaurant])
File.open(filename) do |f|
total_string = f.readline
total_string = options[:total] if options.key?(:total)
total = Monetize.parse(total_string)
menu.parse_lines(f)
end
Logger.info "Finding orders with total: #{total.format} in menu:"
Logger.info menu.inspect
exactinator = case options[:method]
when 'recursive'
Exactinator::Recursive.new(menu, total)
when 'montecarlo'
Exactinator::MonteCarlo.new(menu, total)
end
exactinator.run
if exactinator.orders.any?
Logger.info "Success! Found #{exactinator.orders.count} order(s)"
else
Logger.info 'No orders were found fulfilling the desired total'
end
exactinator.orders.each_with_index do |order, i|
Logger.info "\nOrder #{i + 1} of #{exactinator.orders.count}"
Logger.info order.inspect
end
end
options[:restaurant] = 'Menu'
options[:method] = 'recursive'
description 'Given an input file containing a target total and menu items, find all possible combinations of menu items that meet the total exactly'
on('-r VALUE', '--restaurant', 'name of restaurant')
on('-t VALUE', '--total', 'override total in the input file (don\'t forget to escape \$!)')
methods = %w[recursive montecarlo]
on('-m VALUE', '--method', methods, 'possible methods to use', "(#{methods.join('|')})")
arg :filename, :required, 'input filename. first line must have target total, remaining lines each have a menu item name a price, separated by a comma'
version Exord::VERSION, compact: true
go!