aboutsummaryrefslogtreecommitdiff
path: root/2024/day01/main.scm
blob: 9334264c68a992c46100110158db0b40bb2f3657 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/guile -s
!#

(add-to-load-path (format #f "~a/2024" (getcwd)))
(add-to-load-path (format #f "~a/.." (dirname (current-filename))))

(use-modules
 (aoc-utils)
 (srfi srfi-1)
 (srfi srfi-9)
 (ice-9 regex))

(define line-rx "([0-9]+)\\s+([0-9]+)")

(define (match-line line)
  (let ((match (string-match line-rx line)))
    (list (string->number (match:substring match 1))
          (string->number (match:substring match 2)))))

(define (first-sorted-list l)
  (sort (map (lambda (pair) (car pair)) l) <))
(define (second-sorted-list l)
  (sort (map (lambda (pair) (car (cdr pair))) l) <))

(define (part1 lines)
  (let* ((lines (map (lambda (line) (match-line line))
                     lines))
         (first-list (first-sorted-list lines))
         (second-list (second-sorted-list lines)))
    (fold (lambda (pair acc)
            (+ acc (abs (- (first pair) (second pair)))))
          0
          (zip first-list second-list))))

(define (make-counter l)
  (let ((h (make-hash-table)))
    (for-each (lambda (n)
                (if (hash-ref h n)
                    (hash-set! h n (1+ (hash-ref h n)))
                    (hash-set! h n 1)))
              l)
    h))

(define (part2 lines)
  (let* ((lines (map (lambda (line) (match-line line)) lines))
         (first-list (map (lambda (pair) (car pair)) lines))
         (second-list (map (lambda (pair) (car (cdr pair))) lines))
         (counter-map (make-counter second-list)))
    (fold (lambda (n acc)
            ;; (display n) (display "-") (display acc) (newline)
            (+ (* n (if (hash-ref counter-map n)
                        (hash-ref counter-map n)
                        0))
               acc))
          0
          first-list)))


(define (main)
  (let ((lines (file->list "input.txt")))
    (display "Part1: ")
    (display (part1 lines))
    (newline)
    (display "Part2: ")
    (display (part2 lines))
    (newline)))

(main)