Created
August 21, 2012 15:55
-
-
Save ideamonk/3416803 to your computer and use it in GitHub Desktop.
Brainfuck Printer Printer / can be still optimised for shorter output
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
; http://www.reddit.com/r/dailyprogrammer/comments/yj32c/8202012_challenge_89_intermediate_printing/ | |
; put http://pastebin.com/raw.php?i=v8AbQRFv in data/the-raven | |
; | |
; brainfuck printer printer | |
; ------------------------- | |
; lame version - spits 206325 bytes | |
; (defn change-set | |
; [op n] | |
; "get n repeated operations with last call to output" | |
; (apply str (concat (repeat n op) "."))) | |
; (defn change-for | |
; "get changes needed from source to destination" | |
; [to from] | |
; (let [diff (- to from) op (cond (> diff 0) "+" :else "-")] | |
; (change-set op (Math/abs diff)))) | |
; (defn brainfuck | |
; [string] | |
; "takes a string, returns brainfuck code that prints it" | |
; (let [chars (map int string) shifted-chars (concat [0] (butlast chars))] | |
; (apply str (map change-for chars shifted-chars)))) | |
; (println (brainfuck (slurp "data/the-raven"))) | |
; optimized dancer - spits 56808 bytes, still no good for the 38k mark | |
(defn centralize | |
"assuming a list descending by freq, centers most frequent, aligns lesser ones on the edges" | |
[nums-sorted] | |
(loop [left [] right [(first nums-sorted)] nums (rest nums-sorted)] | |
(if (empty? nums) | |
(concat left right) | |
(if (== (mod (count nums) 2) 0) | |
(recur (concat [(first nums)] left) right (rest nums)) | |
(recur left (conj right (first nums)) (rest nums) ))))) | |
(defn sort-descending | |
[freqs] | |
(map #(first %1) (into (sorted-map-by (fn [k1 k2] (>= (freqs k1) (freqs k2)))) freqs))) | |
(defn movement-for | |
"gets movement for a dance step. to, from are char values, we dance on a floor of centralized-keys" | |
[to from] | |
(let [diff (- to from) op (cond (pos? diff) ">" :else "<")] | |
(apply str (concat (repeat (Math/abs diff) op) ".")))) | |
(def data (map int (slurp "data/the-raven"))) | |
(def descending-keys (sort-descending (frequencies data))) | |
(def centralized-keys (centralize descending-keys)) | |
(def midway (quot (count descending-keys) 2)) | |
(def cell-maker (apply str (map #(apply str (concat (repeat %1 "+") ">")) centralized-keys))) | |
(def to-center (apply str (repeat (inc midway) "<"))) ; set pointer to most-frequent letter | |
; now we're at center, start dancing | |
(def dance | |
(loop [data data prev-pos midway dance-steps ""] | |
(let [to-pos (.indexOf centralized-keys (first data))] | |
(if (empty? data) | |
dance-steps | |
(recur (rest data) to-pos (apply str (concat dance-steps (movement-for to-pos prev-pos)))))))) | |
; TODO: ^ I guess that could be written in a better way, also seems to be slow | |
(println (str cell-maker to-center dance)) | |
; | |
; TODO: | |
; | |
; Notes: haven't used things other than > < . + . The cell-maker could be optimized further with [ ] | |
; as rest of the meat is for movemnt & prints | |
; | |
; But cell-maker is about 4772 bytes, wouldn't be a great saving in size | |
; | |
; This movement is statistical, so need not be the most optimal arrangement of centralized-keys | |
; for the bf generator to move on... | |
; | |
; 57! = 40526919504877216755680601905432322134980384796226602145184481280000000000000 is a bit | |
; too much for a search space ;P | |
; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment