Committer: hpcdisrespecter <noreply@git.asperger.pro> modified: .gitignore modified: README.md new file: menus/peoples-organic.sexp new file: menus/townhall-shortnorth.sexp new file: organic-cafe.asd new file: run.lisp new file: src/package.lisp new file: src/planner.lisp new file: test/tests.lisp
organicCafe
Practical joke vent art SERIOUS DISCUSSION code for generating multi-day,
budget-constrained meal plans from a menu using MC sampling.
- Never make a decision about food at a technical conference again!
- Make wait staff feel awkward by ordering as soon as you arrive!
- Avoid the temptation to eat the same thing every day!
The menu and meal templates are a small, data-only S-expression DSL.
Shoutout to People's Organic in MSP (Federal per diem: $92, FY2026) and TownHall Short North in Columbus ($80, FY2025), the respective off-site ordering adventures for ACM PEARC26 and PEARC25.
People's Organic has a small menu and fewer options, whereas TownHall produces a Cartesian product of garnishes. Both are supported in this framework.
General Ideas
Prices are converted to integer cents when loaded, so budget comparisons do not rely on floating-point arithmetic.
For normal generation, the planner computes the weighted number of completions at each remaining budget and samples only branches that can finish beneath the cap. This avoids both rejection loops and materializing large Cartesian products.
Any given day, a small pool of feasible days is drawn, and least-repetitive candidates are favored.
feasible-candidates still eagerly enumerates combinations for tests,
diagnostics, and suitably small menus such as People's Organic.
Variables
--budget DOLLARSsets the daily per diem.--days Nsets the number of days to plan.--menu FILEselects a menu file frommenus/.--plan PLANselects a plan from the menu. If omitted, the first plan is used.--add-lazy-day DOLLARSappends a breakfast-only day with its own budget. For outbound flight days.--seed Nsets the random seed for reproducibility (don't use this you orthorexic nerd).
Usage
SBCL and ASDF are the only requirements.
# PEARC26 default
sbcl --script run.lisp
# the same thing explicitly with seed
sbcl --script run.lisp -- --budget 92 --days 3 --seed 1337 --add-lazy-day 30
# PEARC25 default
sbcl --script run.lisp -- \
--menu menus/townhall-shortnorth.sexp \
--budget 80 --add-lazy-day 30 --seed 1337
Use --help for all options.
Ask for help if you need it. Someone will probably answer.
Tests
Run the tests:
sbcl --non-interactive \
--eval '(require "asdf")' \
--eval '(asdf:load-asd (truename "organic-cafe.asd"))' \
--eval '(asdf:test-system "organic-cafe/tests")'
The DSL
The complete menus live in menus/ and defaults to menus/peoples-organic.sexp. The DSL is a small S-expression language for describing menus and meal plans.
:lazy-day is a special plan item, for the day you leave town.
Basic example
(:menu "A Cafe"
(:group :mains
(:item "Soup and sandwich" 12.50)
(:item "Grain bowl" 14))
(:group :drinks
(:item "Coffee" 3.25))
(:plan :lunch
(:meal :lunch
(:one :main :mains)
(:maybe :drink :drinks :chance 1/2))))
(:one LABEL GROUP) always chooses one item. (:maybe LABEL GROUP :chance P)
chooses no item with probability 1-P; if present, each item in the group has
an equal share of P.
Composable forms
TownHall's menu has options, so it demonstrates compositional forms:
(:choose :side :bowl-side :count 2)
(:either :meal
(:branch 1/2
(:one :shared-plate :pour-la-table))
(:branch 1/2
(:one :protein :bowl-protein)
(:one :base :bowl-base)))
:choose samples the requested number of distinct items. :either selects one
weighted branch, whose body may contain any number of other plan forms. Branch
weights must sum to one. :one and :maybe are also valid. You are also valid.
License and Sharing
Do what the fuck you want.