Skip to content

Instantly share code, notes, and snippets.

# timmc/rest.swear.clj Last active Dec 15, 2016

rest in curje [now called swearjure]
 ;; An exercise in writing #'rest without [0-9a-zA-Z], by Tim McCormack ;; Note that the input must be a vector, although the code could easily be ;; modified to vector-ify any input coll. ;; Let's take this a step at a time... (#(((% 1) :main) %) ;; call the main method with the input and fns [[0 1 2 3 4 5] ;; the input is hardcoded here ;; fns are accessed by static indices into the fn table {:main #(if (= (% 0) []) ;; empty input -> [] [] ;; recur with extra accumulator args (((% 1) :loop) [(% 0) (% 1) {:nexdex 1 :accum []}])) :loop #(if (= (% 0) (vec (concat [((% 0) 0)] ((% 2) :accum)))) ;; if first + rest = input, we're done ((% 2) :accum) ;; otherwise recur with new accumulator (((% 1) :loop) [(% 0) (% 1) {:nexdex (+ 1 ((% 2) :nexdex)) :accum (vec (concat ((% 2) :accum) [((% 0) ((% 2) :nexdex))]))}])) }]) ;; Translate vec/concat expressions (#(((% 1) :main) %) ;; call the main method with the input and fns [[0 1 2 3 4 5] ;; the input is hardcoded here ;; fns are accessed by static indices into the fn table {:main #(if (= (% 0) []) ;; empty input -> [] [] ;; recur with extra accumulator args (((% 1) :loop) [(% 0) (% 1) {:nexdex 1 :accum []}])) :loop #(if (= (% 0) `[~((% 0) 0) ~@((% 2) :accum)]) ;; if first + rest = input, we're done ((% 2) :accum) ;; otherwise recur with new accumulator (((% 1) :loop) [(% 0) (% 1) {:nexdex (+ 1 ((% 2) :nexdex)) :accum `[~@((% 2) :accum) ~((% 0) ((% 2) :nexdex))]}])) }]) ;; Translate if statements into explicit delayed eval and map dispatch (#(((% 1) :main) %) ;; call the main method with the input and fns [[0 1 2 3 4 5] ;; the input is hardcoded here ;; fns are accessed by static indices into the fn table {:main #(({[] ((% 1) :always-empty)} ;; empty input -> [] (% 0) ;; dispatch on input's value ;; else, recur with extra accumulator args ((% 1) :do-recur)) [(% 0) (% 1)]) :always-empty #({} %& []) :do-recur #(((% 1) :loop) [(% 0) (% 1) {:nexdex 1 :accum []}]) :loop #(({(% 0) ((% 1) :done)} ;; if first + rest = input, we're done ;; dispatch on first + accum-rest to see if it matches the input `[~((% 0) 0) ~@((% 2) :accum)] ;; else, update accumulator args ((% 1) :incloop)) [(% 0) (% 1) (% 2)]) :done #((% 2) :accum) :incloop #(((% 1) :loop) [(% 0) (% 1) {:nexdex (+ 1 ((% 2) :nexdex)) :accum `[~@((% 2) :accum) ~((% 0) ((% 2) :nexdex))]}])}]) ;; fns indexed in vector instead of named in map (same for accum args) (#(((% 1) 0) %) [[0 1 2 3 4 5] [#(({[] ((% 1) 1)} (% 0) ((% 1) 2)) [(% 0) (% 1)]) #({} %& []) #(((% 1) 3) [(% 0) (% 1) [1 []]]) #(({(% 0) ((% 1) 4)} `[~((% 0) 0) ~@((% 2) 1)] ((% 1) 5)) [(% 0) (% 1) (% 2)]) #((% 2) 1) #(((% 1) 3) [(% 0) (% 1) [(+ 1 ((% 2) 0)) `[~@((% 2) 1) ~((% 0) ((% 2) 0))]]])]]) ;; replace all the numeric literals with arithmetic expressions -- done! (#(((% (+(*))) (+)) %) [[:a :b :c :d :e] ;; input has alphanumeric for ease of reading [#(({[] ((% (+(*))) (+(*)))} (% (+)) ((% (+(*))) (+(*)(*)))) [(% (+)) (% (+(*)))]) #({} %& []) #(((% (+(*))) (+(*)(*)(*))) [(% (+)) (% (+(*))) [(+(*)) []]]) #(({(% (+)) ((% (+(*))) (+(*)(*)(*)(*)))} `[~((% (+)) (+)) ~@((% (+(*)(*))) (+(*)))] ((% (+(*))) (+(*)(*)(*)(*)(*)))) [(% (+)) (% (+(*))) (% (+(*)(*)))]) #((% (+(*)(*))) (+(*))) #(((% (+(*))) (+(*)(*)(*))) [(% (+)) (% (+(*))) [(+ (+(*)) ((% (+(*)(*))) (+))) `[~@((% (+(*)(*))) (+(*))) ~((% (+)) ((% (+(*)(*))) (+)))]]])]])
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.