Day 3 - solutions
Very late. I tend to like these long pipelines of transformations instead of breaking them up. Inscrutable but fun. Everyone seems to have had the same idea though.
(ns aoc2022.day3
(:require [ :refer [resource]]
[clojure.string :as str]
[clojure.set :refer [intersection]]))
(defn data []
(->> (resource "inputs/day3.txt")
(slurp)
(str/split-lines)))
(defn part1 []
(->> (data)
(map #(vector (into #{} (subs % 0 (/ (count %) 2)))
(into #{} (subs % (/ (count %) 2) (count %)))))
(map (partial apply intersection))
(map (comp int first))
(map #(if (> % 96) (- % 96) (- % 38)))
(reduce +)))
(defn part2 []
(->> (data)
(map (partial into #{}))
(partition 3)
(map (partial apply intersection))
(map (comp int first))
(map #(if (> % 96) (- % 96) (- % 38)))
(reduce +))) https://gitlab.com/maximoburrito/advent2022/-/blob/main/src/day03/main.clj
Oh - intersection can be passed more than two sets - how did I miss that. π
(ns slothrop.day-three.rucksacks
(:require [ :as io]
[clojure.string :as string]
[clojure.set :refer [intersection]]))
(def lower (zipmap (map char (range 97 123)) (range 1 27)))
(def upper (zipmap (map char (range 65 91)) (range 27 53)))
(with-open [rdr (-> "public/puzzle_inputs/day_three.txt"
io/resource
io/reader)]
(->> rdr
line-seq
(partition 3) ; pt 2
#_(map #(split-at (/ (count %) 2) %)) ; pt 1
(map (fn [[s1 s2 s3]] (intersection (set s1) (set s2) (set s3))))
(map #(if (Character/isUpperCase (first %))
(get upper (first %))
(get lower (first %))))
(apply +)))
Continuing to phone it in on readability...https://coyotesqrl.github.io/advent-of-code/2022/src/coyotesqrl/2022/day03.html
https://github.com/rap1ds/advent-of-code-2022/blob/main/src/day3.clj
(ns aoc2022.day03
(:require [clojure.string :as s]
[clojure.set :as set])
(:gen-class))
(def data (-> (slurp "resources/input03.txt")
(s/split-lines)))
(defn priority [^Character c]
(- (int c) (if (Character/isLowerCase c) 96 38)))
(defn common-char-with-rating [group]
(->> (map set group)
(apply set/intersection)
first
priority))
(defn line-get-common-char [line]
(let [c (count line)]
(common-char-with-rating (split-at (/ c 2) line))))
(defn part1 [data]
(transduce (map line-get-common-char)
+
data))
(defn part2 [data]
(transduce (map common-char-with-rating)
+
(partition 3 data)))Nothing very interesting.
(ns com.jaihindhreddy.advent22
(:require [clojure.string :as str]
[clojure.set :as set]))
(defn day3 [fs]
(let [priority (fn [c]
(let [x (int c)]
(- x (if (> x 96) 96 38))))
lines (str/split-lines fs)]
[(transduce
(map #(let [n (quot (count %) 2)]
(priority
(first
(set/intersection
(set (subs % 0 n))
(set (subs % n)))))))
+ 0 lines)
(transduce
(comp (partition-all 3)
(map #(priority (first (apply set/intersection (map set %))))))
+ 0 lines)]))My https://github.com/abyala/advent-2022-clojure/blob/main/docs/day03.md with linked https://github.com/abyala/advent-2022-clojure/blob/main/src/advent_2022_clojure/day03.clj.
(defn char-range [start end]
(map char (range (int start) (inc (int end)))))
(def priorities
(zipmap
(concat (char-range \a \z) (char-range \A \Z))
(range 1 53)))
(defn parse-rucksack [rs]
(let [rs (seq rs)]
(split-at (/ (count rs) 2) rs)))
(defn item-priority [col]
(->> col
(map set)
(apply clojure.set/intersection)
(first)
(priorities)))
(defn day3-part1 []
(->> (string/split-lines (slurp "input/day-3-input-1.txt"))
(map parse-rucksack)
(map item-priority)
(reduce +)))
(defn day3-part2 []
(->> (string/split-lines (slurp "input/day-3-input-1.txt"))
(partition 3)
(map seq)
(map item-priority)
(reduce +)))Here is mine, now in the https://github.clerk.garden: https://github.clerk.garden/formsandlines/aoc2022-clojure/commit/1dd601cb5f5d590162e9cb3ab62c68c78e83f3a6/src/advent_of_clerk/day_03.html Pretty much what everyone did, I guess, using intersection on sets. I converted the type mathematically on the char code, although not as sophisticated as the hack by tschadys coworker. :)
;; part1
(defn crr26 [c] (map char (range (int c) (+ (int c) 26))))
(def priorities (zipmap (concat (crr26 \a) (crr26 \A))
(range 1 53)))
(defn solvgrp [grp]
(->> (map set grp)
(apply set/intersection)
first
(get priorities)))
(->> (map #(split-at (/ (count %) 2) %) input)
(map solvgrp)
(apply +)) ;; 7850
;; part 2
(apply + (map solvgrp (partition 3 input))) ;; 2581Nice solutions all. Haven't seen anybody use str/index-of for item-type score fn:
(fn [it]
(-> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
(str/index-of it)
inc))I'm using it (without inc):
(defn pts [it]
(->> it (map set) (apply intersection) first
(index-of ":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")))
(defn -main [day]
(let [input (file->lines day)]
{:part1 (transduce (map #(pts (partition (/ (count %) 2) %))) + input)
:part2 (transduce (map pts) + (partition 3 input))}))I like when both parts have a common algo with just 1 HOF diff https://github.com/tschady/advent-of-code/blob/main/src/aoc/2022/d03.clj
https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2022/d3.clj
(ns y2022.d3
(:require [clojure.set :as set]
[hyperfiddle.rcf :refer [tests]]
[utils :as u]))
(def dummy-input ["vJrwpWtwJgWrhcsFMMfFFhFp"
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL"
"PmmdzqPrVvPwwTWBwg"
"wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn"
"ttgJtRGJQctTZtZT"
"CrZsJsPPZsGzwwsLwLmpwMDw"])
(def input (u/input))
; ---
(def char->priority
(->> (concat (range (int \a) (inc (int \z)))
(range (int \A) (inc (int \Z))))
(map-indexed (fn [i c] [(char c) (inc i)]))
(into {})))
(defn priority [partitions]
(->> (map set partitions)
(apply set/intersection)
first
char->priority))
(defn part-1 [input]
(->> (map #(priority (partition (/ (count %) 2) %)) input)
(reduce +)))
(defn part-2 [input]
(->> (partition 3 input)
(reduce #(+ %1 (priority %2)) 0)))
(tests
(part-1 dummy-input) := 157
(part-2 dummy-input) := 70)
(comment
(part-1 input) ; => 8105
(part-2 input) ; => 2363
)A cool hack from a coworker, priority is > (-> (int c) (- 96) (mod 58))
https://github.com/nbardiuk/adventofcode/blob/master/2022/src/day03.clj
@tws Imagine having to explain that one to a beginner and having to start with βin the beginning there was Cβ¦β
Like many of you, using sets. https://github.com/zamansky/advent2022/blob/main/src/day03.clj
collect ideas from you and i get this
(ns y2022.core
(:require [clojure.set :as cs]))
;; 202203
(let [m (merge
(zipmap (->> (range 97 123) (map char)) (range 1 27))
(zipmap (->> (range 65 91) (map char)) (range 27 53)))
f #(->> % (map set) (reduce cs/intersection) first m)
d (->> (slurp "src/y2022/input202203")
(re-seq #"[^\n]+"))]
(->> [(map #(split-at (/ (count %) 2) %) d)
(partition 3 d)]
(map #(transduce (map f) + %))))
;; (8233 2821)https://github.com/benjamin-asdf/advent-of-code-2021/blob/master/src/Y2022/day3.clj
https://github.com/nooga/aoc2022/blob/master/day3.lg
(ns day3)
(defn dupe [coll]
(first (apply intersection (map (partial apply set) (split-at (/ (count coll) 2) coll)))))
(defn badge [group]
(first (reduce intersection (map (comp (partial apply set) seq) group))))
(defn prio [c]
(let [a (int \a) A (int \A) c (int c)]
(if (neg? (- c a)) (- c A -27) (- c a -1))))
(def data (-> "input/day3.txt" slurp lines))
(println "1:" (reduce + (map (comp prio dupe) data)))
(println "2:" (reduce + (map (comp prio badge) (partition 3 data))))
Though, I'm not happy with how set works atm.These (partial apply set) and (comp (partial apply set) seq) would be just set in Clojure
https://github.com/volesen/aoc2022/blob/main/day3/day3.clj. I would love feedback on style!
@vincolesen I'd (let [i (int char)] ... in priority to avoid repetition
https://github.com/pwojnowski/advent-of-code/blob/master/src/aoc/aoc2022.clj#L42
Also used sets. https://github.com/stuartstein777/clj-advent-of-code/blob/master/src/stuartstein777/2022/day3.clj
my first year using clojure, please feel free to give me any tips/suggestions: https://github.com/mducharm/advent_of_code_2022/blob/main/src/advent_of_code/day_03.clj
(ns advent-of-code-2022.days.day-three
(:require [clojure.data :refer [diff]]
[clojure.set :refer [map-invert intersection]]
[clojure.string :as string]))
(def test-rucksacks
["vJrwpWtwJgWrhcsFMMfFFhFp"
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL"
"PmmdzqPrVvPwwTWBwg"
"wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn"
"ttgJtRGJQctTZtZT"
"CrZsJsPPZsGzwwsLwLmpwMDw"])
(def supply-value
(map-invert (into {} (map-indexed
#(vector (inc %1) (str %2))
(flatten (cons (map char (range (int \a) (inc (int \z))))
(map char (range (int \A) (inc (int \Z))))))))))
(defn compare-two-lists
"Compares two lists and returns the distinct
values that are in both lists"
[listone listtwo]
(distinct
(for [i listone
n listtwo
:when (= i n)]
i)))
(defn compare-three-lists
"Compares three lists and returns the distinct
values that are all three lists"
[listone listtwo listthree]
(distinct
(for [i listone
n listtwo
y listthree
:when (= i n y)]
i)))
(defn rucksack-item-priorities
[list-of-rucksacks]
(let [items (flatten
(for [rucksack list-of-rucksacks
:let [itemcount (count rucksack)
divided (/ itemcount 2)
compartment-one (map str (take divided rucksack))
compartment-two (map str (drop divided rucksack))]]
(compare-two-lists compartment-one compartment-two)))]
(map #(get supply-value %) items)))
(defn group-elves
[list-of-rucksacks]
(let [elvegroups (loop [elvestoskip 0
groups []]
(let [elvestotake 3
group (take elvestotake (drop elvestoskip list-of-rucksacks))]
(if (>= (count group) elvestotake)
(recur (+ elvestoskip elvestotake) (conj groups (into [] group)))
(concat groups group))))]
(vec elvegroups)))
(defn elvegroup-item-priorities
[list-of-rucksacklists]
(let [items (flatten
(for [list-of-rucksacks list-of-rucksacklists
:let [rucksack-one (map str (first list-of-rucksacks))
rucksack-two (map str (second list-of-rucksacks))
rucksack-three (map str (last list-of-rucksacks))]]
(compare-three-lists rucksack-one rucksack-two rucksack-three)))]
(map #(get supply-value %) items)))
-
(defn day-three-part-one
""
[]
(let [resource "resources/day-three.txt"
data (adventreader resource)
rucksacks (into [] data)
prio-values (daythree/rucksack-item-priorities rucksacks)]
(println "Total rucksacks:" (count rucksacks))
(println "Sum of all priorities:" (reduce + prio-values))))
(defn day-three-part-two
""
[]
(let [resource "resources/day-three.txt"
data (adventreader resource)
rucksacks (into [] data)
groupedelves (daythree/group-elves rucksacks)
prio-values (daythree/elvegroup-item-priorities groupedelves)]
(println "Total elve groups:" (count groupedelves))
(println "Sum of all priorities:" (reduce + prio-values))))
https://github.com/bhauman/advent-of-code-2022/blob/main/src/adv2022/day3/sol.clj
late one: https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2022/day03.clj
@tsulej great solution, v/similar to mine. Yours is the only other one Iβve read who encoded the data first.
OK Iβve read most of the solutions and I have unsolicited thoughts.
I usually make a rough round and then refactor to optimize the size of the code. One of the ideas was to work on numbers (priorities) instead of chars which was ok for both parts.
@tsulej yeah that makes sense especially when the encoding is one to one and not many to one
The biggest reflection after reading the answers Iβd make is that a function is a mapping from one value to another. Much like a Map is a mapping from one value to another.
And if you want to use a Map instead of a function for perf reasons then there is always memoize to make the Map for you.
this is a deep true: https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L6343
Day 3: https://github.com/dogenpunk/advent-of-code/blob/main/src/aoc22/day03.cljc
(ns day-03)
(def priority
(merge (zipmap "abcdefghijklmnopqrstuvwxyz" (range 1 27))
(zipmap "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (range 27 53))))
(def lines (re-seq #".+" (slurp "../day_03.data")))
(defn input-1 []
(for [line lines
:let [c (count line)
h (/ c 2)
[a b] [(subs line 0 h) (subs line h c)]]]
(some (set a) b)))
(defn input-2 []
(for [[a b c] (partition 3 lines)]
(some (set (filter (set a) b)) c)))
(defn solution-1 []
(reduce + (map priority (input-1))))
(defn solution-2 []
(reduce + (map priority (input-2))))Wild, part 1 was "solved" in 10 seconds: https://twitter.com/ostwilkens/status/1598458146187628544
Day 3 generated by chatGPT. Many errors in Clojure code:
(defn priority [ch]
(let [offset (if (Character/isLowerCase ch) 96 64)]
(- (char ch) offset)))
(defn solve [input]
(let [counts (frequencies input)]
(first (sort-by (comp second >) counts))))
(def input ["vJrwpWtwJgWrhcsFMMfFFhFp"
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL"
"PmmdzqPrVvPwwTWBwg"
"wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn"
"ttgJtRGJQctTZtZT"
"CrZsJsPPZsGzwwsLwLmpwMDw"])
(let [common-item (solve input)]
(println "The common item is" common-item)
(println "Its priority is" (priority common-item))
(println "The sum of the priorities is" (* (count input) (priority common-item))))that priority function is nicer than mine π
I like mine, but way to complicated haha
(def supply-value
(map-invert (into {} (map-indexed
#(vector (inc %1) (str %2))
(flatten (cons (map char (range (int \a) (inc (int \z))))
(map char (range (int \A) (inc (int \Z))))))))))@jean.boudet11 what question do you ask to chatGPT?
The all aoc day3 state. I only add in Clojure at the end of the part1 question
Did I miss the memo about Advent-of-Transduce? π
maybe that's what AOT meant all along thinking-face
Hmm too bad I didnt start sooner (as in when it started). Started this afternoon and I am really enjoying it!
--------Part 1--------- --------Part 2---------
Day Time Rank Score Time Rank Score
3 12:13:41 73953 0 12:50:11 69425 0
2 >24h 128429 0 >24h 122748 0
1 >24h 164805 0 >24h 158912 0Hey I wanna play! https://github.com/bhauman/advent-of-code-2022/blob/main/src/adv2022/day1/sol.clj https://github.com/bhauman/advent-of-code-2022/blob/main/src/adv2022/day2/sol.clj
checkout pinned messages - we have solution threads organized by day. This way it is easier to find other examples of the same day and we don't spoil the game for people who are solving on another days
Thanks man!
Solutions now properly filed in the appropriate locations!
https://github.com/bhauman/advent-of-code-2022/tree/main/src/adv2022/day3
there, I've implemented HashSet and then fixed my implementation thanks to today's AoC challenge