-
-
Save corasaurus-hex/9cbe6a0190f1dce0acbe79ccfdcc9593 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns user | |
(:require [clojure.string :as str] | |
[hyperfiddle.rcf :refer [tests]])) | |
(hyperfiddle.rcf/enable!) | |
(defn window-for-index | |
[index rows] | |
(cond | |
(= 0 index) | |
[0 (vec (take 2 rows))] | |
(= (-> rows count dec) index) | |
[1 (vec (take-last 2 rows))] | |
(and (>= index 0) (<= index (-> rows count dec))) | |
[1 (->> rows (take (+ 2 index)) (take-last 3) vec)] | |
:else | |
nil)) | |
(tests | |
(window-for-index 0 [:a :b :c :d :e]) := [0 [:a :b]] | |
(window-for-index 1 [:a :b :c :d :e]) := [1 [:a :b :c]] | |
(window-for-index 2 [:a :b :c :d :e]) := [1 [:b :c :d]] | |
(window-for-index 3 [:a :b :c :d :e]) := [1 [:c :d :e]] | |
(window-for-index 4 [:a :b :c :d :e]) := [1 [:d :e]] | |
(window-for-index 5 [:a :b :c :d :e]) := nil | |
(window-for-index -1 [:a :b :c :d :e]) := nil | |
) | |
(defn parse-number-ranges | |
[row] | |
(let [matcher (.matcher (re-pattern "(\\d+)") row)] | |
(loop [ranges []] | |
(if (.find matcher) | |
(recur (conj ranges [(.start matcher) (.end matcher)])) | |
ranges)))) | |
(tests | |
(parse-number-ranges "467..114..") := [[0 3] [5 8]] | |
(subs "467..114.." 0 3) := "467" | |
(subs "467..114.." 5 8) := "114" | |
(parse-number-ranges "..*.467..114") := [[4 7] [9 12]] | |
(subs "..*.467..114" 4 7) := "467" | |
(subs "..*.467..114" 9 12) := "114" | |
) | |
(defn indexes-around-number-range | |
[window cursor-index number-range] | |
(let [[from to] number-range | |
max-index (count (get window cursor-index)) | |
border-range (range (max 0 (dec from)) (min max-index (inc to)))] | |
(cond-> [] | |
(> from 0) | |
(conj [cursor-index (dec from)]) | |
(< to max-index) | |
(conj [cursor-index to]) | |
(get window (dec cursor-index)) | |
(into (map #(do [(dec cursor-index) %]) border-range)) | |
(get window (inc cursor-index)) | |
(into (map #(do [(inc cursor-index) %]) border-range))))) | |
(tests | |
(indexes-around-number-range ["...*......" | |
"..35..633." | |
"......#..."] | |
1 | |
[2 4]) := [[1 1] | |
[1 4] | |
[0 1] | |
[0 2] | |
[0 3] | |
[0 4] | |
[2 1] | |
[2 2] | |
[2 3] | |
[2 4]]) | |
(defn adjacent-characters | |
[window cursor-index number-range] | |
(map (comp str #(get-in window %)) | |
(indexes-around-number-range window | |
cursor-index | |
number-range))) | |
(tests | |
(adjacent-characters ["-*&!+..58." | |
"%617@....." | |
"^)($#..58."] | |
1 | |
[1 4]) := ["%" "@" "-" "*" "&" "!" "+" "^" ")" "(" "$" "#"] | |
(adjacent-characters ["617*......" | |
"-*&!.+.58."] | |
0 | |
[0 3]) := ["*" "-" "*" "&" "!"] | |
(adjacent-characters [".+.58.-*&!" | |
"......*617"] | |
1 | |
[7 10]) := ["*" "-" "*" "&" "!"] | |
(adjacent-characters [".*!*$....." | |
".%35#.633." | |
".&^-_.#..."] | |
1 | |
[2 4]) := ["%" "#" "*" "!" "*" "$" "&" "^" "-" "_"] | |
) | |
(def non-symbol-characters? #{"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "."}) | |
(defn symbol-character? | |
[s] | |
(not (non-symbol-characters? s))) | |
(defn adjacent-to-symbol? | |
[window cursor-index number-range] | |
(boolean (some symbol-character? (adjacent-characters window cursor-index number-range)))) | |
(tests | |
(adjacent-to-symbol? ["...*......" | |
"..35..633." | |
"......#..."] 1 [2 4]) := true | |
(adjacent-to-symbol? ["....*....." | |
"..35..633." | |
"......#..."] 1 [2 4]) := true | |
(adjacent-to-symbol? [".........." | |
"..35*.633." | |
"......#..."] 1 [2 4]) := true | |
(adjacent-to-symbol? [".........." | |
"..35..633." | |
"....*.#..."] 1 [2 4]) := true | |
(adjacent-to-symbol? [".........." | |
"..35..633." | |
".*....#..."] 1 [2 4]) := true | |
(adjacent-to-symbol? [".........." | |
".*35..633." | |
"......#..."] 1 [2 4]) := true | |
(adjacent-to-symbol? [".*........" | |
"..35..633." | |
"......#..."] 1 [2 4]) := true | |
(adjacent-to-symbol? [".........." | |
"..35..633." | |
"......#..."] 1 [2 4]) := false | |
) | |
(defn parse-number | |
[window cursor-index number-range] | |
(parse-long (apply subs (get window cursor-index) number-range))) | |
(tests | |
(parse-number [".........." | |
"..35..633." | |
"......#..."] 1 [2 4]) := 35 | |
) | |
(defn parse-input | |
[input-text] | |
(let [rows (str/split input-text #"\n")] | |
(loop [index 0 | |
total 0] | |
(if (get rows index) | |
(let [[cursor-index window] (window-for-index index rows) | |
ranges (parse-number-ranges (get window cursor-index)) | |
numbers-with-adjacent-symbols (->> ranges | |
(filter #(adjacent-to-symbol? window cursor-index %)) | |
(map #(parse-number window cursor-index %)))] | |
(recur (inc index) (reduce + total numbers-with-adjacent-symbols))) | |
total)))) | |
(tests | |
(let [input-text (str/join | |
"\n" | |
["467..114.." | |
"...*......" | |
"..35..633." | |
"......#..." | |
"617*......" | |
".....+.58." | |
"..592....." | |
"......755." | |
"...$.*...." | |
".664.598.."]) | |
output-value 4361] | |
(parse-input input-text) := output-value) | |
) | |
(comment | |
(parse-input | |
(slurp "input"))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{:deps {com.hyperfiddle/rcf {:mvn/version "20220926-202227"}}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment