I ended up feeling pretty sick today so I wasn't able to spend time doing my usual amount of work on Clojure today.
But regardless, I did want to make some progress. So I worked on a few 4Clojure Problems. And my first PR to the Athens repo got successfully merged!
Write a predicate which checks whether or not a given sequence represents a binary tree. Each node in the tree must have a value, a left child, and a right child.
(defn istree?
[tree]
(if (coll? tree)
(if (= (count tree) 3)
(and (istree? (second tree)) (istree? (nth tree 2)))
false)
(nil? tree)))
(istree? [1 nil [2 [3 nil nil] [4 nil nil]]])
Map is one of the core elements of a functional programming language. Given a function f and an input sequence s, return a lazy sequence of (f x) for each element x in s.
(= [3 4 5 6 7] ;; (__ inc [2 3 4 5 6]))
(defn reimplement-map
[f s]
(if-not (nil? (next s))
(lazy-seq (cons (f (first s)) (reimplement-map f (rest s))))
(list (f (first s)))))
(reimplement-map inc [2 3 4 5 6])
(reimplement-map (fn [_] nil) (range 10))
This one was interesting since my first intuition was to implement map in terms of reduce. But reduce doesn't play well with lazy-seq so I had to switch to using cons.
Write a function which converts (for example) the string "SJ" into a map of {:suit :spade, :rank 9}. A ten will always be represented with the single character "T", rather than the two characters "10".
(= {:suit :diamond :rank 10} (__ "DQ"))
(defn cards
[c]
(let [info {}
f (first c)
s (second c)
iparse #(Integer/parseInt (str %))]
(-> info
(assoc :suit
(case f
\S :spade
\C :club
\H :heart
\D :diamond))
(assoc :rank
(case s
\T 8
\J 9
\Q 10
\K 11
\A 12
(- (iparse s) 2))))))
(cards "CA")
Couple of things I learned from submitting my PR.
- I should have read the CONTRIBUTING.md document a little more carefully and figured out how to deploy my version of devcards before commenting on the issue. This could have prevented some back and forths and led to a faster PR merge.
- GitHub Actions are very cool. It might be worth playing around with them for some other projects
- I need to figure out how to make
cljstyle
play better with VS Code.
It did feel nice to make even a small contribution to the project and I think I am more confident in working with the Athens code now.