Created
May 11, 2013 19:12
-
-
Save postspectacular/5561043 to your computer and use it in GitHub Desktop.
Project Euler #59 solution w/ Clojure
This file contains hidden or 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
(ns toxi.euler.problem59) | |
;; http://projecteuler.net/problem=59 | |
;; solution by: toxi <k at postspectacular dot com> | |
;; 2012-12-23 | |
(defn xor-decrypt | |
"Applies bit-xor to all items in src using key as cyclic sequence." | |
[src key] (map bit-xor src (cycle key))) | |
(defn as-str | |
"Translates seq of numbers into ASCII string." | |
[x] (->> x (map char) (apply str))) | |
(defn in-interval? | |
"Returns true if a <= x <= b." | |
[a b x] (and (<= a x) (<= x b))) | |
(def alphanum? | |
"Returns true if x is in alphanumeric ASCII range (space ... z)." | |
(partial in-interval? (int \space) (int \z))) | |
(defn letter-or-space? | |
"Returns true if x is an ASCII letter (upper or lowercase) or space." | |
[x] (or (= x 32) (in-interval? 65 90 x) (in-interval? 97 122 x))) | |
(defn text-like? | |
"Returns true if the n most frequent vals in coll are an ASCII letter or space." | |
[n coll] | |
(->> coll frequencies (sort-by second) (take-last n) keys (every? letter-or-space?))) | |
(defn euler59 | |
"Loads encrypted file and returns map of decrypted text, encryption key | |
and ASCII sum of plain text (107359 for cipher1.txt)." | |
[path] | |
(let [src (read-string (str "[" (slurp path) "]")) | |
a-z (range (int \a) (inc (int \z))) | |
[key txt] (->> | |
;; generate all 26^3 key combinations | |
(for [a a-z b a-z c a-z] [a b c]) | |
;; decrypt with each key | |
(map (fn [k] [k (xor-decrypt src k)])) | |
;; filter out results with chars outside alphanum range | |
(filter #(->> % second (every? alphanum?))) | |
;; drop all remaining non-text like | |
(drop-while #(not (text-like? 10 (second %)))) | |
;; use first valid as result | |
first)] | |
{:key (as-str key) :text (as-str txt) :sum (reduce + txt)})) | |
(euler59 "cipher1.txt") | |
;; {:key "god", :text "(The Gospel of John, chapter 1) 1 In the | |
;; beginning the Word already existed. He was with God, and he was | |
;; God. 2 He was in the beginning with God. 3 He created everything | |
;; there is. Nothing exists that he didn't make. 4 Life itself was in | |
;; him, and this life gives light to everyone. 5 The light shines | |
;; through the darkness, and the darkness can never extinguish it. 6 | |
;; God sent John the Baptist 7 to tell everyone about the light so | |
;; that everyone might believe because of his testimony. 8 John | |
;; himself was not the light; he was only a witness to the light. 9 | |
;; The one who is the true light, who gives light to everyone, was | |
;; going to come into the world. 10 But although the world was made | |
;; through him, the world didn't recognize him when he came. 11 Even | |
;; in his own land and among his own people, he was not accepted. 12 | |
;; But to all who believed him and accepted him, he gave the right to | |
;; become children of God. 13 They are reborn! This is not a physical | |
;; birth resulting from human passion or plan, this rebirth comes from | |
;; God.14 So the Word became human and lived here on earth among us. | |
;; He was full of unfailing love and faithfulness. And we have seen | |
;; his glory, the glory of the only Son of the Father.", :sum 107359} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@postspectacular reads like prose!