Skip to content

Instantly share code, notes, and snippets.

@abhilater
Last active May 17, 2017 15:22
Show Gist options
  • Save abhilater/998506ec0d6b695aff4ce77d7ea3af46 to your computer and use it in GitHub Desktop.
Save abhilater/998506ec0d6b695aff4ce77d7ea3af46 to your computer and use it in GitHub Desktop.
Caesar cipher's implementation using Clojure Transducer
;; The Caesar Cipher implementation using Clojure Transducers
;; Author: Abhishek Gupta
;The Caesar Cipher
;Given a string, use transducers to:
;
;Filter out vowels and non-ASCII characters
;Filter out upper-case characters
;Rotate all remaining characters via a Caesar cipher,
;And reduce the rotated characters into a map counting the number of occurrences of each character.
;Example:
;
;(defn caesar-count
; [string cipher]
; ???)
;
;(caesar-count "abc" 0)
;; ⇒ {\c 1, \b 1}
;
;(caesar-count "abc" 1)
;; ⇒ {\d 1, \c 1}
;
;(caesar-count "hello world" 0)
;; ⇒ {\d 1, \r 1, \w 1, \l 3, \h 1}
;
;(caesar-count "hello world" 13)
;; ⇒ {\q 1, \e 1, \j 1, \y 3, \u 1}
(defn rotate [cipher]
(fn [c]
(let [base-c (- (int c) 97)
rotated-c (mod (+ base-c cipher) 26)]
(char (+ rotated-c 97)))))
(defn caesar-xform
[cipher]
(comp
(map int)
; only small aplphabets
(filter #(and (<= % 122) (>= % 97)))
; not vowels
(filter #(not (or (= % 97) (= % 101) (= % 105) (= % 111) (= % 117))))
; rotate characters
(map (rotate cipher))
))
(defn caesar-reducing
([]
[])
([result]
result)
([result input] (update-in result (str input) (fnil inc 0)))
; (fnil + 0) replaces use of #(+ (or % 0) 1), for when the key does not exist
; yet (and thus value is nil)
)
(defn caesar-count
[string cipher]
;(transduce (caesar-xform cipher) caesar-reducing {} string)
(transduce (caesar-xform cipher) caesar-reducing {} string)
)
(comment
(caesar-count "hello world" 13)
;=> {\u 1, \y 3, \j 1, \e 1, \q 1}
(caesar-count "abc" 1)
;=> {\c 1, \d 1})
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment