Advent of Code 2015 - Day 1 - Not Quite Lisp
{:deps {org.clojure/clojure {:mvn/version "1.10.1-RC1"}}}
Santa is trying to deliver presents in a large apartment building, but he can't find the right floor – the directions he got are a little confusing. He starts on the ground floor (floor 0
) and then follows the instructions one character at a time.
An opening parenthesis, (
, means he should go up one floor, and a closing parenthesis, )
, means he should go down one floor.
The apartment building is very tall, and the basement is very deep; he will never find the top or bottom floors.
For example:
(())
and()()
both result in floor0
.(((
and(()(()(
both result in floor3
.))(((((
also results in floor3
.())
and))(
both result in floor-1
(the first basement level).)))
and)())())
both result in floor-3
.
1. Part One
To what floor do the instructions take Santa?
1.1. Bash
echo 'c=0; n=1 for i in $(fold -b1 $1); do [ "$i" = "(" ] && c=$((c+1)) [ "$i" = ")" ] && c=$((c-1)) echo $c $n n=$((n+1)) done' > day1.sh
sh day1.sh input | tail -n1 | cut -d' ' -f1
1.2. AWK
awk 'BEGIN { FS = ""; } { for (i = 1; i <= NF; i++) { if ($i == "(") floor++; else if ($i == ")") floor--; } } END { print floor; }' input
1.3. Clojure
(- (count (re-seq "\(" (slurp "input"))) (count (re-seq "\)" (slurp "input"))))
(defn parse-step [floor step] (case step \( (inc floor) \) (dec floor) floor)) (defn parse-floor [steps] (reduce parse-step 0 steps)) (parse-floor (slurp "input"))
2. Part Two
Now, given the same instructions, find the position of the first character that causes him to enter the basement (floor -1
). The first character in the instructions has position 1
, the second character has position 2
, and so on.
For example:
)
causes him to enter the basement at character position1
.()())
causes him to enter the basement at character position5
.What is the position of the character that causes Santa to first enter the basement?
2.1. Bash
sh day1.sh input | grep -e '-1 ' | head -n1 | cut -d' ' -f2
2.2. AWK
awk 'BEGIN { # split the input into one field per character. FS = ""; THE_BASEMENT = -1; } { for (i = 1; i <= NF; i++) { if ($i == "(") floor++; else if ($i == ")") floor--; if (floor == THE_BASEMENT) break; } } END { # i is the position, if santa never entered the basement then we have: # i == (NR + 1) print i; }' input
2.3. Clojure
(defn basement [instructions] (->> instructions (reductions parse-step 0) (map vector (drop 1 (range))) (drop-while (fn [[position floor]] (not (neg? floor)))) first first)) (dec (basement (slurp "input")))