Created
September 26, 2012 02:03
-
-
Save mjansen401/3785573 to your computer and use it in GitHub Desktop.
GildedRose Clojure solution (with @patrickgombert)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;the code | |
(ns gilded-rose.core) | |
(def vest "+5 Dexterity Vest") | |
(def brie "Aged Brie") | |
(def elixir "Elixir of the Mongoose") | |
(def sulfuras "Sulfuras, Hand of Ragnaros") | |
(def passes "Backstage passes to a TAFKAL80ETC concert") | |
(def cake "Conjured Mana Cake") | |
(defn expired? [item] | |
(< (:sell-in item) 0)) | |
(defn- update-item-attribute [item key value] | |
(merge item {key value})) | |
(defn- update-sell-in [item] | |
(update-item-attribute item :sell-in (dec (:sell-in item)))) | |
(defn- item-name [item] (:name item)) | |
(defn- do-for-updated-sell-in [age-fn item] | |
(let [item (update-sell-in item)] | |
(age-fn item))) | |
(defmulti age-item item-name) | |
(defmethod age-item cake [item] | |
(do-for-updated-sell-in | |
(fn [item] | |
(if (<= (:quality item) 0) | |
item | |
(update-item-attribute item :quality (- (:quality item) 2)))) | |
item)) | |
(defmethod age-item brie [item] | |
(do-for-updated-sell-in | |
(fn [item] | |
(if (>= (:quality item) 50) | |
item | |
(update-item-attribute item :quality (inc (:quality item))))) | |
item)) | |
(defn- normal-quality-item [item] | |
(do-for-updated-sell-in | |
(fn [item] | |
(cond | |
(= 0 (:quality item)) | |
item | |
(expired? item) | |
(update-item-attribute item :quality (- (:quality item) 2)) | |
:else | |
(update-item-attribute item :quality (dec (:quality item))))) | |
item)) | |
(defmethod age-item vest [item] | |
(normal-quality-item item)) | |
(defmethod age-item elixir [item] | |
(normal-quality-item item)) | |
(defn in-range-inclusive [start end value] | |
(and (>= value start) (< value end))) | |
(defmethod age-item passes [item] | |
(do-for-updated-sell-in | |
(fn [item] | |
(let [sell-in (:sell-in item) | |
quality (:quality item)] | |
(cond | |
(expired? item) | |
(update-item-attribute item :quality 0) | |
(in-range-inclusive 0 5 sell-in) | |
(update-item-attribute item :quality (+ 3 quality)) | |
(in-range-inclusive 5 10 sell-in) | |
(update-item-attribute item :quality (+ 2 quality)) | |
:else | |
(update-item-attribute item :quality (+ 1 quality))))) | |
item)) | |
(defmethod age-item :default [item] | |
item) | |
(defn update-quality [items] | |
(map age-item items)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;the specs | |
(ns gilded-rose.core-spec | |
(:require [speclj.core :refer :all] | |
[gilded-rose.core :refer [update-quality update-sell-in update-item-quality expired? normal-quality?]])) | |
(def vest "+5 Dexterity Vest") | |
(def brie "Aged Brie") | |
(def elixir "Elixir of the Mongoose") | |
(def sulfuras "Sulfuras, Hand of Ragnaros") | |
(def passes "Backstage passes to a TAFKAL80ETC concert") | |
(def cake "Conjured Mana Cake") | |
(def inventory | |
[ | |
{:name vest :sell-in 10 :quality 20} | |
{:name brie :sell-in 2 :quality 0} | |
{:name elixir :sell-in 5 :quality 7} | |
{:name sulfuras :sell-in 0 :quality 80} | |
{:name passes :sell-in 15 :quality 20} | |
{:name cake :sell-in 3 :quality 6} | |
]) | |
(defn update-quality-n-times [i, n] | |
(loop [items i count 0] | |
(if (= count n) | |
items | |
(recur (update-quality items) (inc count))))) | |
(defn item-by-name [item-name items] | |
(first (filter (fn[item] (= item-name (:name item))) items))) | |
(defn updated-sell-in [item-name updated-items] | |
(:sell-in (item-by-name item-name updated-items))) | |
(defn updated-quality [item-name updated-items] | |
(:quality (item-by-name item-name updated-items))) | |
(describe "gilded rose" | |
(describe "acceptance tests" | |
(describe "sell_in values" | |
(it "decreases by 1 after one update for non-legendary items" | |
(let [[updated-items] [(update-quality-n-times inventory 1)]] | |
(should= 9 (updated-sell-in vest updated-items)) | |
(should= 1 (updated-sell-in brie updated-items)) | |
(should= 4 (updated-sell-in elixir updated-items)) | |
(should= 14 (updated-sell-in passes updated-items)) | |
)) | |
(it "decreases by 2 after two updates for non-legendary items" | |
(let [[updated-items] [(update-quality (update-quality-n-times inventory 1))]] | |
(should= 8 (updated-sell-in vest updated-items)) | |
(should= 0 (updated-sell-in brie updated-items)) | |
(should= 3 (updated-sell-in elixir updated-items)) | |
(should= 13 (updated-sell-in passes updated-items)) | |
)) | |
(it "stays constant for legendary items" | |
(let [[items-updated-once] [(update-quality-n-times inventory 1)]] | |
(should= 0 (updated-sell-in sulfuras items-updated-once)) | |
(should= 0 (updated-sell-in sulfuras (update-quality items-updated-once))) | |
)) | |
) | |
(describe "quality values" | |
(describe "normal items" | |
(it "decreases the quality by 1" | |
(should= 19 (updated-quality vest (update-quality-n-times inventory 1))) | |
(should= 6 (updated-quality elixir (update-quality-n-times inventory 1)))) | |
(it "decreases the quality by 2 when item expired" | |
(should= 8 (updated-quality vest (update-quality-n-times inventory 11))) | |
(should= 0 (updated-quality elixir (update-quality-n-times inventory 6)))) | |
) | |
(describe "aged brie" | |
(it "increases in quality as it ages" | |
(should= 1 (updated-quality brie (update-quality-n-times inventory 1)))) | |
(it "never gets above 50 quality" | |
(should= 50 (updated-quality brie (update-quality-n-times inventory 55)))) | |
) | |
(describe "sulfuras" | |
(it "never decreases in quality" | |
(should= 80 (updated-quality sulfuras (update-quality-n-times inventory 10)))) | |
) | |
(describe "passes" | |
(it "increases in quality by 1 with more than 10 days to sell" | |
(should= 25 (updated-quality passes (update-quality-n-times inventory 5)))) | |
(it "increases in quality by 2 with more than 5 days and less than 10 to sell" | |
(should= 35 (updated-quality passes (update-quality-n-times inventory 10)))) | |
(it "increases in quality by 3 with more than 0 days and less than 5 to sell" | |
(should= 50 (updated-quality passes (update-quality-n-times inventory 15)))) | |
(it "drops to 0 when expired" | |
(should= 0 (updated-quality passes (update-quality-n-times inventory 16)))) | |
) | |
) | |
) | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment