(deftest test-records
(testing "edge cases"
(is (= (breaking-records '()[]) {:nbetter 0 :nworse 0}) "no games played yet")
(is (= (breaking-records '(5)[5]) {:nbetter 0 :nworse 0}) "single game"))
(testing "hackerrank examples"
(is (= (breaking-records '(10[10 5 20 20 4 5 2 25 1)1]) {:nbetter 2 :nworse 4}))
(is (= (breaking-records '(3[3 4 21 36 10 28 35 5 24 42)42]) {:nbetter 4 :nworse 0}))))
; ***** NOTE: it's much easier to use vectors like [1 2 3] instead of a quoted list `(1 2 3)
Please see this list of documentation, esp. the Clojure CheatSheet. Also, the template project as a whole shows how I like to structure things. :)
The function that helps the most is partition. See the docs.
Slight refactoring
You can simplify it a small amount and make it a bit more compact by using more specialized functions like reduce and cond->. This version uses a map to hold state and reduce to perform the looping:
(defn breaking-records
[scores]
(let [state-init {:low (first scores)
:high (first scores)
:nworse 0
:nbetter 0}
accum-stats-fn (fn [state score-pair]
; Use map destructuring to pull out the 4 state variables
(let [{:keys [low high nworse nbetter]} state
new-score (second score-pair)
state-new {:low (min new-score low)
:high (max new-score high)
:nworse (cond-> nworse
(< new-score low) (inc))
:nbetter (cond-> nbetter
(< high new-score) (inc))}]
state-new))
state-final (reduce accum-stats-fn
state-init
(partition 2 1 scores))
result (select-keys state-final [:nworse :nbetter])]
result))