adventofcode

2022-12-03T05:23:03.788819Z

Day 3 - solutions

dumrat 2022-12-22T16:47:01.997549Z

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 +)))

πŸ‘ 1
2022-12-03T05:29:02.194979Z

Oh - intersection can be passed more than two sets - how did I miss that. πŸ™‚

liebs 2022-12-03T05:35:47.200719Z

(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...

Martin PΕ―da 2022-12-03T07:28:02.837389Z

(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)))

jaihindhreddy 2022-12-03T07:33:03.694839Z

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)]))

Luis Santos 2022-12-03T07:42:16.458379Z

(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 +)))

peterh 2022-12-04T11:40:47.435949Z

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. :)

mchampine 2022-12-03T08:23:37.169999Z

;; 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))) ;; 2581

pieterbreed 2022-12-03T09:26:53.912789Z

Nice solutions all. Haven't seen anybody use str/index-of for item-type score fn:

(fn [it]
  (-> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
      (str/index-of it)
      inc))

πŸ‘ 4
2022-12-03T10:17:09.216829Z

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))}))

πŸ‘ 1
πŸ‘πŸ½ 1
tschady 2022-12-03T11:04:48.895269Z

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

πŸ‘ 2
carnundotcom 2022-12-03T11:17:42.352829Z

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
  )

πŸ‘πŸ½ 1
1
tschady 2022-12-03T11:30:57.087919Z

A cool hack from a coworker, priority is > (-> (int c) (- 96) (mod 58))

πŸ‘ 6
πŸ‘πŸ» 1
πŸ‘πŸ½ 1
pieterbreed 2022-12-03T11:41:07.918009Z

@tws Imagine having to explain that one to a beginner and having to start with β€œin the beginning there was C…”

πŸ‘ 1
2022-12-03T11:44:05.121559Z

Like many of you, using sets. https://github.com/zamansky/advent2022/blob/main/src/day03.clj

Apple 2022-12-03T12:29:01.890449Z

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)

nooga 2022-12-03T12:53:10.356549Z

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.

nooga 2022-12-03T12:54:59.942629Z

These (partial apply set) and (comp (partial apply set) seq) would be just set in Clojure

2022-12-03T13:16:44.398549Z

https://github.com/volesen/aoc2022/blob/main/day3/day3.clj. I would love feedback on style!

nooga 2022-12-03T13:26:53.314399Z

@vincolesen I'd (let [i (int char)] ... in priority to avoid repetition

Michael Ducharm 2022-12-03T17:22:38.461929Z

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

πŸ‘ 1
Thierry 2022-12-03T18:14:03.561589Z

(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))))

bhauman 2022-12-03T21:54:59.958009Z

@tsulej great solution, v/similar to mine. Yours is the only other one I’ve read who encoded the data first.

πŸ‘ 2
bhauman 2022-12-03T21:55:26.430569Z

OK I’ve read most of the solutions and I have unsolicited thoughts.

genmeblog 2022-12-03T21:57:50.709149Z

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.

bhauman 2022-12-03T21:59:23.087379Z

@tsulej yeah that makes sense especially when the encoding is one to one and not many to one

bhauman 2022-12-03T21:59:24.644659Z

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.

bhauman 2022-12-03T22:00:54.021279Z

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.

genmeblog 2022-12-03T22:06:00.015369Z

this is a deep true: https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L6343

mbjarland 2022-12-08T09:45:34.740949Z

(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))))

2022-12-03T06:00:49.199679Z

Wild, part 1 was "solved" in 10 seconds: https://twitter.com/ostwilkens/status/1598458146187628544

🀯 3
J 2022-12-03T07:08:16.358659Z

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))))

πŸ‘€ 2
solf 2022-12-03T13:26:07.154469Z

that priority function is nicer than mine 😞

1
Thierry 2022-12-03T18:10:34.622599Z

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))))))))))

erwinrooijakkers 2022-12-05T14:06:38.900169Z

@jean.boudet11 what question do you ask to chatGPT?

J 2022-12-05T14:08:48.478309Z

The all aoc day3 state. I only add in Clojure at the end of the part1 question

tschady 2022-12-03T11:22:45.432879Z

Did I miss the memo about Advent-of-Transduce? πŸŽ…

πŸ‘ 3
πŸ˜… 6
ray 2022-12-03T15:51:53.583799Z

maybe that's what AOT meant all along thinking-face

Thierry 2022-12-03T17:55:30.334319Z

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      0

1
nbardiuk 2022-12-03T19:36:09.203489Z

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

bhauman 2022-12-03T19:37:42.816429Z

Thanks man!

πŸ‘ 1
bhauman 2022-12-03T19:44:38.483269Z

Solutions now properly filed in the appropriate locations!

πŸ˜‚ 2
πŸ§‘β€πŸŽ„ 1
nooga 2022-12-03T23:28:59.132569Z

there, I've implemented HashSet and then fixed my implementation thanks to today's AoC challenge

πŸ‘ 1