Skip to content

Instantly share code, notes, and snippets.

@jgomo3
Created March 16, 2018 03:03
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 jgomo3/305afa6baddf893f0c6cea3d3fedffc5 to your computer and use it in GitHub Desktop.
Save jgomo3/305afa6baddf893f0c6cea3d3fedffc5 to your computer and use it in GitHub Desktop.
Chapter 3 excercise for the "Clojure for the Brave and True" -- For hitting hobbits
(ns clojure-noob.smash-hobbits
(:require [clojure.string :as str]))
(def asym-hobbit-body-parts [{:name "head" :size 3}
{:name "left-eye" :size 1}
{:name "left-ear" :size 1}
{:name "mouth" :size 1}
{:name "nose" :size 1}
{:name "neck" :size 2}
{:name "left-shoulder" :size 3}
{:name "left-upper-arm" :size 3}
{:name "chest" :size 10}
{:name "back" :size 10}
{:name "left-forearm" :size 3}
{:name "abdomen" :size 6}
{:name "left-kidney" :size 1}
{:name "left-hand" :size 2}
{:name "left-knee" :size 2}
{:name "left-thigh" :size 4}
{:name "left-lower-leg" :size 3}
{:name "left-achilles" :size 1}
{:name "left-foot" :size 2}])
(defn set-map [f coll] (set (map f (set coll))))
(defn matching-parts-by
[{:keys [seed-part rest-parts] :as mapping}
{:keys [name size] :as part}]
(let
[seed-pattern (re-pattern (str "^" seed-part "-"))
pattern-replacer (comp (partial str/replace name seed-pattern) #(str % "-"))]
(for [part-name (set-map pattern-replacer (conj rest-parts seed-part))]
{:name part-name
:size size})))
(defn symmetrize-body-parts-for
[mapping asym-body-parts]
(let [matching-parts (partial matching-parts-by mapping)]
(reduce (fn [final-body-parts part]
(into final-body-parts (matching-parts part)))
[]
asym-body-parts)))
(def left-right-mapping {:seed-part "left"
:rest-parts ["right"]})
(def four-parts-mapping {:seed-part "left"
:rest-parts ["right" "up" "down"]})
(def symmetrize-body-parts (partial symmetrize-body-parts-for left-right-mapping))
(defn hit
[asym-body-parts]
(let [sym-parts (symmetrize-body-parts asym-body-parts)
body-part-size-sum (reduce + (map :size sym-parts))
target (rand body-part-size-sum)]
(loop [[part & remaining] sym-parts
accumulated-size (:size part)]
(if (> accumulated-size target)
part
(recur remaining (+ accumulated-size (:size (first remaining))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment