Skip to content

Instantly share code, notes, and snippets.


Mark Woodworth Solaxun

View GitHub Profile
Solaxun / tetris.clj
Created Aug 14, 2021
Tetris in Clojure (basic game-play mostly done, no UI yet - switching to CLJS for that (can't use threads, reworking to use channels)
View tetris.clj
(def rows 20)
(def cols 10)
(def board (vec (repeat rows (vec (repeat cols " ")))))
(defn new-game-state []
{:board board
:active-piece nil
:game-over? false
Solaxun / aoc-2020-day22.clj
Created Dec 22, 2020
Advent of Code 2020, Day 22... can't find the bug
View aoc-2020-day22.clj
(def game {:player1 [26 8 2 17 19 29 41 7 25 33 50 16 36 37 32 4 46 12 21 48 11 6 13 23 9],
:player2 [27 47 15 45 10 14 3 44 31 39 42 5 49 24 22 20 30 1 35 38 18 43 28 40 34]})
;; Treating the seen rule as needing to see the exact game (both decks) twice.
;; Doesn't terminate.
(defn play-round [game]
(loop [seen #{}
{:keys [player1 player2] :as game} game]
(if (or (empty? player1) (empty? player2))
(let [p1 (player1 0)
Solaxun / destructuring.clj
Created Jul 21, 2020
restructuring destructuring
View destructuring.clj
(defmulti destruct-type
(fn [binding value]
(cond (sequential? binding) clojure.lang.Sequential ; order matters, vector is associative too
(associative? binding) clojure.lang.Associative
:else (type binding))))
(defn coerce-binding-type [binding-type]
(case binding-type
:strs str
:syms (fn [sym] `'~sym)
Solaxun / compiletime-closures.clj
Last active Jul 20, 2020
At runtime, the function created by the macroexpansion captures lexical scope from wherever it's called, and is stored in the atom.
View compiletime-closures.clj
(def protos (atom nil))
(defn build-func [[name args body]]
(list 'fn name args body))
(defmacro bleh [fbody]
`(let [f# ~(build-func fbody)]
(do (reset! protos f#) f#)))
(macroexpand-1 '(bleh (foo [y] (+ x y))))
Solaxun / reify-toy.clj
Last active Jul 19, 2020
Toy implementation of reify, doesn't check the methods are actually part of the protocol, doesn't do namespacing, etc. Just mimicks the interface.
View reify-toy.clj
;;; implementation
(defn build-fn [[mname args body]]
{(keyword mname) (list 'fn mname args body)})
(defn make-generic-fn [[mname args body]]
`(defn ~mname ~args
(let [f# (get ~(first args) ~(keyword mname))]
(f# ~@args))))
Solaxun / multimethods-toy.clj
Last active Jul 20, 2020
toy multimethod implementation
View multimethods-toy.clj
;;;; machinery for multimethods
(defmacro defmethod2 [fname dispatch-val signature body]
`(swap! ~(symbol (str "multimethod-lkp-" fname)) assoc ~dispatch-val
(fn ~signature ~body)))
(defn make-generic-fn [fname dispatchfn]
`(defn ~fname [& ~'args]
(let [dispatch-val# (apply ~(symbol (str "multimethod-dispatch-" fname)) ~'args)
mm-table# (deref ~(symbol (str "multimethod-lkp-" fname)))
matching-fn# (some #(get mm-table# %) [dispatch-val# :default])]
View mm-vs-protocols.clj
Multimethods are an open dispatch mechanism, but is closed in it's
dispatch function. If the set of dispatch types is open, so is
the multimethod.
Protocols are always open because you can always add a new type.
Multimethods require you to pick something to dispatch on that
remains open so any user can create a new one.
For dependency injection, protocols work great because you can
Solaxun / ibid.clj
Created Dec 5, 2019
ibid clojure - from Gene Kim's interview on the Functional Geekery podcast.
View ibid.clj
;; couldn't resist after hearing the podcast...
(defn ibid [coll]
(reduce (fn [res cur]
(if (= cur "ibid")
(conj res (last res))
(conj res cur)))
[(first coll)]
(rest coll)))
Solaxun / my-cons.clj
Last active Jul 3, 2020
Clojure Cons Cell
View my-cons.clj
(def NIL (symbol "NIL"))
(deftype ConsCell [CAR CDR]
(cons [this x] (ConsCell. x this))
(first [this] (.CAR this))
;; next and more must return ISeq:
(more [this] (if
(= (.CDR this) NIL)
Solaxun / day13.clj
Created Dec 15, 2018
2018 Advent of Code Day 13
View day13.clj
(ns aoc2018-clj.day13
(:require [clojure.string :as str]
[ :as io]
[clojure.math.combinatorics :as combs]
[clojure.set :as set]))
(def track (str/split-lines (-> "day13.txt" io/resource slurp)))
(def race-track (mapv vec track))
(defn intersection-rule [{:keys [loc dir turn-count] :as car}]