Skip to content

Instantly share code, notes, and snippets.

@mikelikesbikes
Last active December 12, 2015 08:29
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 mikelikesbikes/4744386 to your computer and use it in GitHub Desktop.
Save mikelikesbikes/4744386 to your computer and use it in GitHub Desktop.
My solution to XKCD #287 http://xkcd.com/287/
$15.05
mixed fruit,$2.15
french fries,$2.75
side salad,$3.35
hot wings,$3.55
mozzarella sticks,$4.20
sampler plate,$5.80
#!/bin/bash
lein run -m xkcd287.core ./input.txt
(ns xkcd287.core
(:require [clojure.java.io :as io]
[clojure.string :as s]))
(defn purchasable?
[value item]
(<= (:price item) value))
(defn order-builder
[menu value]
(let [menu (filter (partial purchasable? value) menu)]
(cond
(zero? value) [[]]
(empty? menu) nil
:else
(let [[item & new-menu] menu
new-value (- value (item :price))]
(concat (order-builder new-menu value)
(map (partial cons item) (order-builder menu new-value)))))))
(defn parse-price
[s]
(Integer/parseInt (apply str (re-seq #"\d" s))))
(defn parse-menu-item
[line]
(let [[name-str price-str] (re-seq #"[^,]+" line)]
{:name name-str :price (parse-price price-str)}))
(defn print-item
[[item n]]
(str n " x " (item :name)))
(defn print-order
[order]
(prn (s/join ", " (map print-item (frequencies order)))))
(defn -main
[filename & args]
(with-open [rdr (io/reader filename)]
(let [lines (line-seq rdr)
target-price (parse-price (first lines))
menu (map parse-menu-item (rest lines))
orders (order-builder menu target-price)]
(if (seq orders)
(doseq [order orders]
(print-order order))
(prn (str "Sorry, no combination can equal $" target-price))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment