The following code solves this problem:
The 3072 characters below contain a sequence of 5 characters which is repeated. However, there is a twist: one of the sequences has a typo. To be specific, you're looking for two groups of 5 characters which share 4 of those characters. Enter the 4 shared characters below to proceed.
Any suggestions on how it can be improved using idiomatic Lisp/Clojure?
(ns slurp.slurp) (defn get-five [in] (if (> (.length in) 4) (subs in 0 5) nil)) (defn how-good [a b position goodness bad-position] (if (= position 5) (list goodness bad-position) (if (= (subs a position (+ 1 position)) (subs b position (+ 1 position))) (recur a b (+ 1 position) (+ 1 goodness) bad-position) (recur a b (+ 1 position) goodness position)))) (defn matches [a b] (let [x (how-good a b 0 0 -1)] (list (> (first x) 3) (last x)))) (defn remove-bad-char [in-string bad-index] (str (subs in-string 0 bad-index) (subs in-string (+ 1 bad-index)))) (defn sub-parse [left in] (let [right (get-five in)] (if (not (= right nil)) (let [match-result (matches left right)] (if (first match-result) (let [bad-index (last match-result)] (println left "is a match. bad-position:" (last match-result) "ans: "(remove-bad-char right bad-index))) (recur left (subs in 1))))))) (defn parse [in] (let [left (get-five in)] ;; as soon as we hit the ass end of the input string, get-five returns null and we stop trying to match. (if (not (= left nil)) (do (sub-parse left (subs in 1)) (recur (subs in 1)))))) (parse (slurp "/Users/clojure/challange.txt")) ;; https://www.readyforzero.com/challenge/491f97bc25574346aed237d43e7d0404 ;; (answer is i2+r)