Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Last active January 6, 2020 16:37
Show Gist options
  • Save ericnormand/1e968f6366ac2b215b1d269b5072b01b to your computer and use it in GitHub Desktop.
Save ericnormand/1e968f6366ac2b215b1d269b5072b01b to your computer and use it in GitHub Desktop.

unmix string

Oh no! My strings have been mixed up. Each pair of letters has been swapped.

Here are examples: "eHllo" should be "Hello". "lCjorue" should be "Clojure".

Write a function to unmix these strings. If the length of the string is odd, the last character is not altered.

(unmix "aHpp yeN weYra !eS eoy uni2 20 0):")

Implement and run the line above to decode the secret message!

Thanks to to this site for the challenge idea!

(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]
[clojure.string :as str]))
(s/defn unmix
[msg :- s/Str]
(it-> msg
(partition-all 2 it)
(mapv reverse it)
(flatten it)
(str/join it)))
(defn unmix
[s]
(->> (partition 2 2 [""] s)
(mapcat (fn [[a b]] [b a]))
(apply str)))
(defn unmix-str
[s]
(->> s
(partition-all 2)
(mapcat reverse)
(apply str)))
(defn unmix [s]
(->> s
(partition-all 2)
(map reverse)
flatten
(apply str)))
(use '[clojure.string :only (join split)])
(defn unmix [s]
(defn unmix-inner [c]
(cond
(empty? c) ""
(= (count c) 1) (let [[first] c] first)
:else (let [[first second & rest] c]
(concat [second first] (unmix-inner rest)))))
(join (unmix-inner (split s #""))))
(defn unmix [s]
(loop [c (split s #"") r []]
(cond
(empty? c) (join r)
(= (count c) 1) (let [[first] c] (join (concat r first)))
:else (let [[first second & rest] c]
(recur rest (concat r second first))))))
(defn unmix [s] (clojure.string/replace s #"(.)(.)" "$2$1"))
(defn unmix [s]
(apply str (apply concat (map reverse (partition-all 2 s)))))
(defn unmix [s]
(apply str (flatten (map reverse (partition-all 2 s)))))
(defn unmix [s] (clojure.string/join (flatten (map reverse (partition-all 2 s)))))
(defn unmix [s]
(reduce (fn [res [a b]]
(str res b a))
""
(partition 2 (conj (vec s) nil))))
(defn unmix
([input]
(unmix input ""))
([input output]
(if-not input
output
(recur (nthnext input 2)
(apply str output (reverse (take 2 input)))))))
(defn unmix [s]
(->> (partition-all 2 s)
(mapcat reverse)
(apply str)))
(ns eu.teod.scratch2.newsletter.pftv-358)
(->> "aHpp yeN weYra !eS eoy uni2 20 0):"
(partition 2)
(map reverse)
(apply concat)
(apply str))
;; - unmix1 is my go-to solution
;; - unmix2 is 21% faster than unmix1
;; - unmix3 is 212% faster than unmix1
;; - unmix3 is a classic car-cdr lispy solution
;;
;; Benchmarked with criterium
(defn unmix1 [s]
(reduce (fn [memo [a b]] (str memo b a))
""
(partition-all 2 s)))
;; Results for unmix1
;;
;; Evaluation count : 5196780 in 60 samples of 86613 calls.
;; Execution time mean : 11,874229 µs
;; Execution time std-deviation : 372,407530 ns
;; Execution time lower quantile : 11,389739 µs ( 2,5%)
;; Execution time upper quantile : 12,736383 µs (97,5%)
;; Overhead used : 7,558749 ns
(defn unmix2 [s]
(loop [[a b] (take 2 s)
s (nthrest s 2)
memo ""]
(if (or a b)
(recur
(take 2 s)
(nthrest s 2)
(str memo b a))
memo)))
;; Results for unmix2
;;
;; Evaluation count : 6179220 in 60 samples of 102987 calls.
;; Execution time mean : 9,805924 µs
;; Execution time std-deviation : 219,493487 ns
;; Execution time lower quantile : 9,574716 µs ( 2,5%)
;; Execution time upper quantile : 10,450540 µs (97,5%)
;; Overhead used : 7,558749 ns
(defn unmix3 [s]
(loop [a (first s)
b (second s)
s (rest (rest s))
memo ""]
(if (or a b)
(recur
(first s)
(second s)
(rest (rest s))
(str memo b a))
memo)))
;; Results for unmix3
;;
;; Evaluation count : 15704100 in 60 samples of 261735 calls.
;; Execution time mean : 3,800963 µs
;; Execution time std-deviation : 65,247816 ns
;; Execution time lower quantile : 3,745129 µs ( 2,5%)
;; Execution time upper quantile : 3,986512 µs (97,5%)
;; Overhead used : 7,558749 ns
(defn- unmix
[s]
#_(clojure.string/join (map clojure.string/join (map reverse (partition 2 s))))
(->> (partition 2 s)
(map reverse)
(map clojure.string/join)
clojure.string/join))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment