@@ -21,10 +21,12 @@ rather, the difficulty is equivalent. I'll explain why in the epilogue below.
21
21
So yeah, we're going to play some bingo. Seems legit. Of course we're going to start with parsing, but first let's
22
22
spend some time figuring out what we want to represent in data. I decided that I would represent a game as a map of
23
23
three properties - ` :numbers-to-draw ` as a sequence of numbers we're ready to draw, ` :numbers-drawn ` as a sequence of
24
- the numbers we did draw, and ` :boards ` for the current state of the game board. To represent each board, I need to know
24
+ the numbers we did draw, and ` :boards ` for the current state of each game board. To represent each board, I need to know
25
25
two things - the set of coordinates that have been marked, and where to find the spaces we haven't marked yet.
26
- So rather than storing each cell in the board, with its coordinates, numeric value, and a flag for whether or not it's
27
- been seen yet, I went with something more deconstructed. The final format of the game becomes this:
26
+ Eventually, we can also declare that a board has achieved Bingo status too, but since ` nil ` and ` false ` are both
27
+ falsey in Clojure, I don't record that value until it's true. So rather than storing each cell in the board, with its
28
+ coordinates, numeric value, and a flag for whether or not it's been seen yet, I went with something more deconstructed.
29
+ The final format of the game becomes this:
28
30
29
31
``` clojure
30
32
; Structure of a game
@@ -45,8 +47,8 @@ the numbers to draw, so that's easy enough.
45
47
```
46
48
47
49
Parsing the each board is a little more complex. A board is represented by a line of text for each row, where the line
48
- is a space-separated list of the numbers on the board. There should be five rows and 5 columns. To parse each line into
49
- five numbers, we will use ` re-seq ` to return the sequence of numeric strings within the line, and then parse each
50
+ is a space-separated list of the numbers on the board. There should be five rows and five columns. To parse each line
51
+ into five numbers, we use ` re-seq ` to return the sequence of numeric strings within the line, and then parse each
50
52
number using ` parse-int ` . From there, we use doubly-nested ` map-indexed ` functions to derive the ` x ` and ` y `
51
53
coordinates, which we associate together into one giant map called ` :unmarked ` .
52
54
@@ -62,8 +64,8 @@ coordinates, which we associate together into one giant map called `:unmarked`.
62
64
```
63
65
64
66
Now that we can parse the incoming numbers and the boards, we put them together using ` parse-game ` . In previous years,
65
- I created the ` utils/split-blank-line ` function to split a single strings into smaller strings when we see two
66
- consecutive blank lines, accommodating for Windows newline nonsense. And as with the day 3 puzzle, we use a variatic
67
+ I created the ` utils/split-blank-line ` function to split a single string into smaller strings when we see two
68
+ consecutive blank lines, accommodating for Windows' newline nonsense. And as with the day 3 puzzle, we use a variatic
67
69
deconstruction by binding the results of ` split-blank-line ` using ` [drawn & boards] ` , which has the effect of binding
68
70
the first string to ` drawn ` and the remaining strings into a sequence named ` boards ` .
69
71
@@ -78,15 +80,15 @@ the first string to `drawn` and the remaining strings into a sequence named `boa
78
80
We're not quite ready to play the game yet. First, I want to make a few helper functions to make working with boards a
79
81
little easier. The ` coords-of ` function takes in a number, and returns the ` [x y] ` coordinates of that number, if it's
80
82
on the board. Then ` unmarked-values ` returns the sequence of numbers that have not yet been marked. They're both simple
81
- to look at, but will make the game logic later easier to read.
83
+ to look at, but will make the game logic easier to read later .
82
84
83
85
``` clojure
84
86
(defn coords-of [board n] (get-in board [:unmarked n]))
85
87
(defn unmarked-values [board] (-> board :unmarked keys))
86
88
```
87
89
88
90
Now let's figure out how a board changes once we draw a number. If we can find the coordinates of that number in an
89
- unmarked cell, we'll need to move it from marked to unmarked , and then check to see if the board has won. This means
91
+ unmarked cell, we'll need to move it from unmarked to marked , and then check to see if the board has won. This means
90
92
using ` conj ` to add the number to the set of marked coordinates,` dissoc ` to remove the mapping from that number to its
91
93
coordinates, and then check for a bingo (TBD). If that number doesn't appear anywhere on the board, just return the
92
94
board itself.
0 commit comments