Skip to content

Instantly share code, notes, and snippets.

@spacepluk
Last active August 29, 2015 14:26
Show Gist options
  • Save spacepluk/e228c98bf345ce8a9f60 to your computer and use it in GitHub Desktop.
Save spacepluk/e228c98bf345ce8a9f60 to your computer and use it in GitHub Desktop.
My take on the print diamond kata https://gist.github.com/trikitrok/378a8af7d9a4295a93f5
(ns diamonds.core
(:require [clojure.string :refer [upper-case]]))
(defn- repeat-space [n]
"Returns a string of n spaces"
(apply str (take n (repeat " "))))
(defn- ping-pong [n]
"Returns a sequence of numbers from 0 to n and back to 0."
(let [up (range 0 (inc n))
down (drop 1 (reverse up))]
(concat up down)))
(defn- diamond-width [row]
"Returns the diamond width for the given row number."
(inc (* 2 row)))
(defn- diamond-indent [max row]
"Returns the left spaces needed to indent the specified row/max."
(repeat-space (- max row)))
(defn- diamond-body [row]
"Returns a string with the diamond body for the specified row."
(let [letter (char (+ (int \A) row))]
(if (= row 0)
(str letter)
(str letter
(repeat-space (- (diamond-width row) 2))
letter))))
(defn- diamond-row [max row]
"Returns a string with both the indentation and the body for the given
row/max."
(str (diamond-indent max row)
(diamond-body row)))
(def ^:private diamond-row-memo (memoize diamond-row))
(defn- diamond [c]
"Returns the list of strings needed to render the diamond for c."
(let [width (- (int c) (int \A))]
(map (partial diamond-row-memo width)
(ping-pong width))))
(defn print-diamond [s]
(let [c (first (upper-case s))]
(doseq [l (diamond c)]
(println l))))
(defn -main
[& args]
(print-diamond (first args)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment