Skip to content

Instantly share code, notes, and snippets.

@ideamonk
Created August 21, 2012 15:55
Show Gist options
  • Save ideamonk/3416803 to your computer and use it in GitHub Desktop.
Save ideamonk/3416803 to your computer and use it in GitHub Desktop.
Brainfuck Printer Printer / can be still optimised for shorter output
; 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