Add Advent 2021 - day 14.

Two solutions: p.rkt is the naive solution and works for part 1, but
fails hard at part 2. It was slow enough I couldn't even get to memory
exhaustion. p2.rkt uses a hash map for pairs and a hash map for
character count, both of which are updated for each iteration. This one
can probably deal with any reasonable number of iterations.
This commit is contained in:
Érico Nogueira 2021-12-14 03:38:08 -03:00
parent 3bb8648786
commit 78747594b7
4 changed files with 193 additions and 0 deletions

30
2021/day14/p.rkt Normal file
View File

@ -0,0 +1,30 @@
#lang racket/base
(require racket/string)
(require racket/list)
(define (make-line t)
(let ([l (string-split t " -> ")])
(values (car l) (second l))))
(define template (read-line))
(define throwaway (read-line))
(define transforms (for/hash ([t (in-lines)]) (make-line t)))
(define (apply-transfomation t)
(define new-string "")
(for ([index (in-range (sub1 (string-length t)))])
(set! new-string (string-append new-string (string (string-ref t index)) (hash-ref transforms (string (string-ref t index) (string-ref t (add1 index))) ""))))
(set! new-string (string-append new-string (string (string-ref t (sub1 (string-length t))))))
new-string)
; works for 10 iterations, blows up at 40!
(for ([i (in-range 10)])
(set! template (apply-transfomation template)))
; part 1
(define template-list (sort (string->list template) char<?))
(define count-hash-table (for/hash ([c (remove-duplicates template-list)])
(values c (for/sum ([nc template-list] #:when (equal? c nc)) 1))))
count-hash-table
(- (apply max (hash-values count-hash-table)) (apply min (hash-values count-hash-table)))

43
2021/day14/p2.rkt Normal file
View File

@ -0,0 +1,43 @@
#lang racket/base
(require racket/string)
(require racket/list)
(define (make-line t)
(let ([l (string-split t " -> ")])
(values (car l) (second l))))
(define template (read-line))
(define throwaway (read-line))
(define transforms (for/hash ([t (in-lines)]) (make-line t)))
(define template-hash (make-hash))
(for ([index (in-range (sub1 (string-length template)))])
(hash-update! template-hash (string (string-ref template index) (string-ref template (add1 index))) add1 0))
(define (apply-transfomation t chars)
(define new-hash (make-hash))
(for ([h (hash-keys t)])
(define (updater v)
(+ v (hash-ref t h)))
(let
([c1 (string-ref h 0)] [c2 (string-ref h 1)] [nc (string-ref (hash-ref transforms h) 0)])
(hash-update! new-hash (string c1 nc) updater 0)
(hash-update! new-hash (string nc c2) updater 0)
; build the character count as we go
(hash-update! chars nc updater 0)))
new-hash)
(define char-hash (make-hash))
(for ([c (string->list template)])
(hash-update! char-hash c add1 0))
; doesn't blow up at 40 iterations!
(for ([i (in-range 40)])
(set! template-hash (apply-transfomation template-hash char-hash)))
(- (apply max (hash-values char-hash)) (apply min (hash-values char-hash)))

18
2021/day14/test1.txt Normal file
View File

@ -0,0 +1,18 @@
NNCB
CH -> B
HH -> N
CB -> H
NH -> C
HB -> C
HC -> B
HN -> C
NN -> C
BH -> H
NC -> B
NB -> B
BN -> B
BB -> N
BC -> B
CC -> N
CN -> C

102
2021/day14/test2.txt Normal file
View File

@ -0,0 +1,102 @@
FSHBKOOPCFSFKONFNFBB
FO -> K
FF -> H
SN -> C
CC -> S
BB -> V
FK -> H
PC -> P
PH -> N
OB -> O
PV -> C
BH -> B
HO -> C
VF -> H
HB -> O
VO -> N
HK -> N
OF -> V
PF -> C
KS -> H
KV -> F
PO -> B
BF -> P
OO -> B
PS -> S
KC -> P
BV -> K
OC -> B
SH -> C
SF -> P
NH -> C
BS -> C
VH -> F
CH -> S
BC -> B
ON -> K
FH -> O
HN -> O
HS -> C
KK -> V
OK -> K
VC -> H
HV -> F
FS -> H
OV -> P
HF -> F
FB -> O
CK -> O
HP -> C
NN -> V
PP -> F
FC -> O
SK -> N
FN -> K
HH -> F
BP -> O
CP -> K
VV -> S
BO -> N
KN -> S
SB -> B
SC -> H
OS -> S
CF -> K
OP -> P
CO -> C
VK -> C
NB -> K
PB -> S
FV -> B
CS -> C
HC -> P
PK -> V
BK -> P
KF -> V
NS -> P
SO -> C
CV -> P
NP -> V
VB -> F
KO -> C
KP -> F
KH -> N
VN -> S
NO -> P
NF -> K
CB -> H
VS -> V
NK -> N
KB -> C
SV -> F
NC -> H
VP -> K
PN -> H
OH -> K
CN -> N
BN -> F
NV -> K
SP -> S
SS -> K
FP -> S