aboutsummaryrefslogtreecommitdiff
path: root/advent-of-code/2023/07/part1.rkt
blob: a22571d79de14b4e4325153e7cf466818ffdffff (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
69
70
71
72
73
74
75
76
77
78
79
80
#lang racket

(define input 
  (with-input-from-file "input"
    (lambda ()
      (let loop ((cards '()))
        (define line (read-line))
        (if (or (eof-object? line)
              (= 0 (string-length line)))
          (reverse cards)
          (let ()
            (define splited-line (string-split line))
            (define hand (car splited-line))
            (define bid (string->number (cadr splited-line)))
            (loop (cons (list hand bid) cards))))))))

(define (card-number char)
  (cond ((eq? char #\A) 12)
        ((eq? char #\K) 11)
        ((eq? char #\Q) 10)
        ((eq? char #\J) 9)
        ((eq? char #\T) 8)
        (else (- (string->number (make-string 1 char))
                 2))))

(define (hand-type hand)
  (define vec (make-vector 13 0))
  (let loop ((i 0))
    (if (>= i 5)
      (vector->list (vector-sort vec >))
      (let ()
        (define index (card-number (string-ref hand i)))
        (vector-set! vec index (+ 1 (vector-ref vec index)))
        (loop (+ i 1))))))

(define (hand-type<? type1 type2)
  (if (or (null? type1)
          (null? type2))
    #f
    (if (= (car type1) (car type2))
      (hand-type<? (cdr type1) (cdr type2))
      (< (car type1) (car type2)))))

(define (hand-type=? type1 type2)
  (if (null? type1)
    #t
    (if (= (car type1) (car type2))
      (hand-type=? (cdr type1) (cdr type2))
      #f)))

(define (raw-hand<? hand1 hand2)
    (define h1 (map card-number (string->list hand1)))
    (define h2 (map card-number (string->list hand2)))
    (hand-type<? h1 h2))

(define (hand<? hand1 hand2)
  (define type1 (hand-type hand1))
  (define type2 (hand-type hand2))
  (if (hand-type=? type1 type2)
    (raw-hand<? hand1 hand2)
    (hand-type<? type1 type2)))

(define sorted-cards
  (sort input (lambda (a b)
                (hand<? (car a) (car b)))))

(define (calc-points card)
    (* (cadar card) (cadr card)))

(define (enumerate lst)
  (let loop ((i 1) (ret '()) (remain lst))
    (if (null? remain)
      (reverse ret)
      (loop (+ 1 i) (cons (list (car remain) i) ret) (cdr remain)))))

(define result
  (apply + (map calc-points (enumerate sorted-cards))))

(display result)
(newline)