Skip to content

Instantly share code, notes, and snippets.

@sevperez
Last active October 14, 2018 18:46
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 sevperez/826d3fe1a07e11f4251d03a1b23ce2fb to your computer and use it in GitHub Desktop.
Save sevperez/826d3fe1a07e11f4251d03a1b23ce2fb to your computer and use it in GitHub Desktop.
(ns clojure-auction-house.core
(:require [clojure.string :as s :only :join]))
(declare announce-status run-auction)
(defn -main [& args]
(let [auction {:items { "Night Watch" nil "American Gothic" nil "Tower of Babel" nil
"Friend In Need" nil "Potato Eaters" nil "Red Balloon" nil }
:total-sales 0}
bids [["Night Watch" 550000] ["Night Watch" 700000] ["American Gothic" 145000],
["Friend In Need" 180000] ["Potato Eaters" 240000] ["Potato Eaters" 300000],
["Red Balloon" 1500000] ["Red Balloon" 25] ["Red Balloon" 1800000]]]
(do
(announce-status auction)
(announce-status (run-auction auction bids)))))
; Available items:
; 1: Night Watch
; 2: American Gothic
; 3: Tower of Babel
; 4: Friend In Need
; 5: Potato Eaters
; 6: Red Balloon
; Total sales: $0
; Available items:
; 1: Tower of Babel
; Total sales: $3,125,000
(defn item-exists? [items item] (contains? items item))
(defn accept-bid? [items item amount]
(or (= nil (get items item)) (> amount (get items item))))
(defn handle-bid [items item amount]
(if (and (item-exists? items item) (accept-bid? items item amount))
(assoc items item amount)
items))
(defn handle-bid-list [items bids]
(loop [bid-number 0
items items]
(if (>= bid-number (count bids))
items
(let [bid (get bids bid-number)
bid-item (first bid)
bid-amount (last bid)]
(recur
(inc bid-number)
(handle-bid items bid-item bid-amount))))))
(defn dollarize [n]
(str "$" (s/reverse (s/join "," (re-seq #".{1,3}" (s/reverse (str n)))))))
(defn build-items-string [items]
(loop [counter 0
output "Available items:\n"]
(if (>= counter (count items))
output
(recur
(inc counter)
(str output (inc counter) ": " (get items counter) "\n")))))
(defn build-sales-string [sales]
(str "Total sales: " (dollarize sales)))
(defn announce-status [auction]
(let [items (:items auction)
item-names (vec (keys items))
sales (:total-sales auction)]
(println (str (build-items-string item-names) (build-sales-string sales)))))
(defn remove-sold-items [items]
(into {} (filter (complement (comp some? val)) items)))
(defn calculate-new-sales [items] (reduce + (filter some? (vals items))))
(defn finalize-sales [auction]
(let [current-items (:items auction)
all-sales (calculate-new-sales current-items)]
(assoc auction :items (remove-sold-items current-items) :total-sales all-sales)))
(defn run-auction [auction bids]
(let [pre-bid-items (:items auction)
post-bid-items (handle-bid-list pre-bid-items bids)]
(finalize-sales (assoc auction :items post-bid-items))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment