Browse Source

Completed day 6 part 1

Tyler Hallada 5 years ago
parent
commit
bd6c348581
3 changed files with 327 additions and 170 deletions
  1. 50 0
      inputs/6.txt
  2. 260 155
      src/day6.rs
  3. 17 15
      src/main.rs

+ 50 - 0
inputs/6.txt

@@ -0,0 +1,50 @@
1
+84, 212
2
+168, 116
3
+195, 339
4
+110, 86
5
+303, 244
6
+228, 338
7
+151, 295
8
+115, 49
9
+161, 98
10
+60, 197
11
+40, 55
12
+55, 322
13
+148, 82
14
+86, 349
15
+145, 295
16
+243, 281
17
+91, 343
18
+280, 50
19
+149, 129
20
+174, 119
21
+170, 44
22
+296, 148
23
+152, 160
24
+115, 251
25
+266, 281
26
+269, 285
27
+109, 242
28
+136, 241
29
+236, 249
30
+338, 245
31
+71, 101
32
+254, 327
33
+208, 231
34
+289, 184
35
+282, 158
36
+352, 51
37
+326, 230
38
+88, 240
39
+292, 342
40
+352, 189
41
+231, 141
42
+280, 350
43
+296, 185
44
+226, 252
45
+172, 235
46
+137, 161
47
+207, 90
48
+101, 133
49
+156, 234
50
+241, 185

+ 260 - 155
src/day6.rs

@@ -3,17 +3,26 @@ extern crate regex;
3 3
 use std::error::Error;
4 4
 use std::fs::File;
5 5
 use std::io::{BufRead, BufReader};
6
-use std::{fmt, mem};
7
-use std::collections::HashMap;
6
+use std::fmt;
7
+use std::collections::{HashMap, HashSet};
8 8
 
9 9
 use regex::{Regex, Captures};
10 10
 
11
+static ALPHABET: [char; 52] = [
12
+    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
13
+    'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
14
+    'u', 'v', 'w', 'x', 'y', 'z',
15
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
16
+    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
17
+    'U', 'V', 'W', 'X', 'Y', 'Z',
18
+];
11 19
 const INPUT: &str = "inputs/6.txt";
12 20
 
13
-#[derive(Debug, PartialEq, Copy, Clone)]
21
+#[derive(Debug, PartialEq, Copy, Clone, Eq, Hash)]
14 22
 struct Coordinate {
15 23
     x: u32,
16 24
     y: u32,
25
+    letter: char,
17 26
 }
18 27
 
19 28
 #[derive(Debug, PartialEq)]
@@ -35,6 +44,44 @@ enum GridPoint {
35 44
     },
36 45
 }
37 46
 
47
+#[derive(Debug, PartialEq)]
48
+struct Grid {
49
+    points: Vec<GridPoint>,
50
+    boundary_coord: Coordinate,
51
+}
52
+
53
+impl fmt::Display for Coordinate {
54
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55
+        write!(f, "{}", self.letter)
56
+    }
57
+}
58
+
59
+impl fmt::Display for Grid {
60
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61
+        write!(f, "\n-----")?;
62
+        for (index, point) in self.points.iter().enumerate() {
63
+            if index as u32 % (self.boundary_coord.x + 1) == 0 {
64
+                write!(f, "\n")?;
65
+            }
66
+            match point {
67
+                GridPoint::Unfilled { x: _, y: _ } => { write!(f, "-")?; },
68
+                GridPoint::Tied { x: _, y: _, closest_dist: _} => {
69
+                    write!(f, ".")?;
70
+                },
71
+                GridPoint::Filled { x, y, closest_coord, closest_dist: _ } => {
72
+                    if *x == closest_coord.x && *y == closest_coord.y {
73
+                        write!(f, "#")?;
74
+                    } else {
75
+                        write!(f, "{}", closest_coord)?;
76
+                    }
77
+                },
78
+            }
79
+        }
80
+        write!(f, "\n-----")?;
81
+        Ok(())
82
+    }
83
+}
84
+
38 85
 #[derive(Debug, Clone, PartialEq)]
39 86
 struct MalformedCoordinate {
40 87
     details: String
@@ -58,6 +105,15 @@ impl Error for MalformedCoordinate {
58 105
     }
59 106
 }
60 107
 
108
+pub fn solve_part1() -> Result<u32, Box<Error>> {
109
+    let coords = read_coordinates(INPUT)?;
110
+    let boundary_coord = get_boundary_coordinate(&coords);
111
+    let mut grid = create_grid(boundary_coord);
112
+    fill_grid(&mut grid, &coords).unwrap();
113
+    println!("{}", grid);
114
+    Ok(find_largest_coord_area(grid))
115
+}
116
+
61 117
 fn read_coordinates(filename: &str) -> Result<Vec<Coordinate>, Box<Error>> {
62 118
     let mut records: Vec<Coordinate> = Vec::new();
63 119
     lazy_static! {
@@ -65,12 +121,13 @@ fn read_coordinates(filename: &str) -> Result<Vec<Coordinate>, Box<Error>> {
65 121
             r"(?P<x>\d+), (?P<y>\d+)").unwrap();
66 122
     }
67 123
     let file = File::open(filename)?;
68
-    for line in BufReader::new(file).lines() {
124
+    for (index, line) in BufReader::new(file).lines().enumerate() {
69 125
         match COORDINATE_REGEX.captures(&line?) {
70 126
             Some(captures) => {
71 127
                 records.push(Coordinate {
72 128
                     x: get_captured_field(&captures, "x")?.parse()?,
73 129
                     y: get_captured_field(&captures, "y")?.parse()?,
130
+                    letter: ALPHABET[index],
74 131
                 });
75 132
             },
76 133
             None => return Err(Box::new(MalformedCoordinate {
@@ -90,8 +147,8 @@ fn get_captured_field(captures: &Captures, field: &str) -> Result<String, Box<Er
90 147
     }
91 148
 }
92 149
 
93
-fn get_boundary_coordinate(coords: Vec<Coordinate>) -> Coordinate {
94
-    let mut boundary_coord = Coordinate { x: 0, y: 0 };
150
+fn get_boundary_coordinate(coords: &Vec<Coordinate>) -> Coordinate {
151
+    let mut boundary_coord = Coordinate { x: 0, y: 0, letter: '+' };
95 152
     for coord in coords {
96 153
         if coord.x > boundary_coord.x {
97 154
             boundary_coord.x = coord.x;
@@ -103,97 +160,109 @@ fn get_boundary_coordinate(coords: Vec<Coordinate>) -> Coordinate {
103 160
     boundary_coord
104 161
 }
105 162
 
106
-fn create_grid(boundary_coord: Coordinate) -> Vec<GridPoint> {
107
-    let mut grid = Vec::new();
108
-    for x in 0..boundary_coord.x + 1 {
109
-        for y in 0..boundary_coord.y + 1 {
110
-            grid.push(GridPoint::Unfilled { x, y });
163
+fn create_grid(boundary_coord: Coordinate) -> Grid {
164
+    let mut points = Vec::new();
165
+    for y in 0..boundary_coord.y + 1 {
166
+        for x in 0..boundary_coord.x + 1 {
167
+            points.push(GridPoint::Unfilled { x, y });
111 168
         }
112 169
     }
113
-    grid
170
+    Grid { points, boundary_coord }
114 171
 }
115 172
 
116
-fn fill_grid(
117
-    grid: &mut Vec<GridPoint>,
118
-    coords: Vec<Coordinate>,
119
-    boundary_coord: Coordinate,
120
-) -> Result<&mut Vec<GridPoint>, Box<Error>> {
173
+fn fill_grid<'a>(
174
+    grid: &'a mut Grid,
175
+    coords: &'a Vec<Coordinate>,
176
+) -> Result<&'a mut Grid, Box<Error>> {
121 177
     for coord in coords {
122
-        let start_index = (coord.x * (boundary_coord.y + 1)) + coord.y;
123
-        fill_grid_with_coordinate(grid, start_index, coord, boundary_coord, 0)?;
178
+        let start_index = (coord.x * (grid.boundary_coord.y + 1)) + coord.y;
179
+        fill_grid_with_coordinate(
180
+            grid,
181
+            start_index,
182
+            *coord,
183
+        )?;
124 184
     }
125 185
     Ok(grid)
126 186
 }
127 187
 
128 188
 fn fill_grid_with_coordinate(
129
-    grid: &mut Vec<GridPoint>,
189
+    grid: &mut Grid,
130 190
     index: u32,
131 191
     coord: Coordinate,
132
-    boundary_coord: Coordinate,
133
-    iterations: u32,
134
-) -> Result<&mut Vec<GridPoint>, Box<Error>> {
135
-    if iterations == 10 { return Ok(grid); }
136
-    println!("index: {}", index);
137
-    println!("grid: {:?}", grid);
138
-    let point = &mut grid.get_mut(index as usize).unwrap();
139
-    match point {
140
-        GridPoint::Unfilled { x, y } => {
141
-            grid[index as usize] = GridPoint::Filled {
142
-                x: *x,
143
-                y: *y,
144
-                closest_coord: coord,
145
-                closest_dist: manhattan_dist(coord.x, coord.y, *x, *y),
146
-            };
147
-        },
148
-        GridPoint::Tied { x, y, closest_dist } |
149
-            GridPoint::Filled { x, y, closest_coord: _, closest_dist } => {
150
-            let dist = manhattan_dist(coord.x, coord.y, *x, *y);
151
-            if dist < *closest_dist {
152
-                grid[index as usize] = GridPoint::Filled {
153
-                    x: *x,
154
-                    y: *y,
192
+) -> Result<&mut Grid, Box<Error>> {
193
+    let mut visited_indices = HashSet::new();
194
+    for point in &mut grid.points {
195
+        visited_indices.insert(index);
196
+        match *point {
197
+            GridPoint::Unfilled { x, y } => {
198
+                *point = GridPoint::Filled {
199
+                    x: x,
200
+                    y: y,
155 201
                     closest_coord: coord,
156
-                    closest_dist: dist,
202
+                    closest_dist: manhattan_dist(coord.x, coord.y, x, y),
157 203
                 };
158
-            } else if dist == *closest_dist {
159
-                grid[index as usize] = GridPoint::Tied {
160
-                    x: *x,
161
-                    y: *y,
162
-                    closest_dist: dist,
163
-                };
164
-            }
165
-        },
166
-    }
167
-    let row_index = index / (boundary_coord.y + 1);
168
-    let col_index = index % (boundary_coord.y + 1);
169
-    println!("row_index: {}", row_index);
170
-    println!("col_index: {}", col_index);
171
-    // South
172
-    if col_index < boundary_coord.y {
173
-        println!("south: {}", index + 1);
174
-        fill_grid_with_coordinate(grid, index + 1, coord, boundary_coord, iterations + 1)?;
175
-    }
176
-    // North
177
-    if col_index > 0 {
178
-        println!("north: {}", index - 1);
179
-        fill_grid_with_coordinate(grid, index - 1, coord, boundary_coord, iterations + 1)?;
180
-    }
181
-    // East
182
-    if row_index < boundary_coord.x {
183
-        println!("east: {}", index + (boundary_coord.y + 1));
184
-        fill_grid_with_coordinate(grid, index + (boundary_coord.y + 1), coord, boundary_coord, iterations + 1)?;
185
-    }
186
-    // West
187
-    if row_index > 0 {
188
-        println!("west: {}", index - (boundary_coord.y + 1));
189
-        fill_grid_with_coordinate(grid, index - (boundary_coord.y + 1), coord, boundary_coord, iterations + 1)?;
204
+            },
205
+            GridPoint::Tied { x, y, closest_dist } => {
206
+                let dist = manhattan_dist(coord.x, coord.y, x, y);
207
+                if dist < closest_dist {
208
+                    *point = GridPoint::Filled {
209
+                        x: x,
210
+                        y: y,
211
+                        closest_coord: coord,
212
+                        closest_dist: dist,
213
+                    };
214
+                }
215
+            },
216
+            GridPoint::Filled { x, y, closest_coord, closest_dist } => {
217
+                let dist = manhattan_dist(coord.x, coord.y, x, y);
218
+                if dist < closest_dist {
219
+                    *point = GridPoint::Filled {
220
+                        x: x,
221
+                        y: y,
222
+                        closest_coord: coord,
223
+                        closest_dist: dist,
224
+                    };
225
+                } else if dist == closest_dist && closest_coord != coord {
226
+                    *point = GridPoint::Tied {
227
+                        x: x,
228
+                        y: y,
229
+                        closest_dist: dist,
230
+                    };
231
+                }
232
+            },
233
+        }
190 234
     }
191
-    println!("returning grid");
192 235
     Ok(grid)
193 236
 }
194 237
 
195 238
 fn manhattan_dist(x1: u32, y1: u32, x2: u32, y2: u32) -> u32 {
196
-    ((x2 as i32 - x1 as i32) + (y2 as i32 - y1 as i32)).abs() as u32
239
+    ((x2 as i32 - x1 as i32).abs() + (y2 as i32 - y1 as i32).abs()) as u32
240
+}
241
+
242
+fn find_largest_coord_area(
243
+    grid: Grid,
244
+) -> u32 {
245
+    let mut point_count = HashMap::new();
246
+    let mut infinite_coords = HashSet::new();
247
+    for point in grid.points.iter() {
248
+        match point {
249
+            GridPoint::Filled { x, y, closest_coord: coord, closest_dist: _ } => {
250
+                if *x == 0 || *x == grid.boundary_coord.x ||
251
+                    *y == 0 || *y == grid.boundary_coord.y {
252
+                    point_count.remove(coord);
253
+                    infinite_coords.insert(coord);
254
+                    continue;
255
+                }
256
+                if !infinite_coords.contains(coord) {
257
+                    let count = point_count.entry(coord).or_insert(0);
258
+                    *count += 1;
259
+                }
260
+            },
261
+            GridPoint::Unfilled { x: _, y: _ } |
262
+                GridPoint::Tied { x: _, y: _, closest_dist: _ } => {}
263
+        }
264
+    }
265
+    *point_count.values().max().unwrap_or(&0)
197 266
 }
198 267
 
199 268
 #[cfg(test)]
@@ -208,75 +277,89 @@ mod tests {
208 277
             Coordinate {
209 278
                 x: 1,
210 279
                 y: 1,
280
+                letter: 'a',
211 281
             },
212 282
             Coordinate {
213 283
                 x: 1,
214 284
                 y: 6,
285
+                letter: 'b',
215 286
             },
216 287
             Coordinate {
217 288
                 x: 8,
218 289
                 y: 3,
290
+                letter: 'c',
219 291
             },
220 292
             Coordinate {
221 293
                 x: 3,
222 294
                 y: 4,
295
+                letter: 'd',
223 296
             },
224 297
             Coordinate {
225 298
                 x: 5,
226 299
                 y: 5,
300
+                letter: 'e',
227 301
             },
228 302
             Coordinate {
229 303
                 x: 8,
230 304
                 y: 9,
305
+                letter: 'f',
231 306
             },
232 307
         ]);
233 308
     }
234 309
 
235 310
     #[test]
236 311
     fn gets_boundary_coordinate() {
237
-        assert_eq!(get_boundary_coordinate(vec![
312
+        assert_eq!(get_boundary_coordinate(&vec![
238 313
             Coordinate {
239 314
                 x: 1,
240 315
                 y: 1,
316
+                letter: 'a',
241 317
             },
242 318
             Coordinate {
243 319
                 x: 5,
244 320
                 y: 5,
321
+                letter: 'b',
245 322
             },
246 323
             Coordinate {
247 324
                 x: 2,
248 325
                 y: 7,
326
+                letter: 'c',
249 327
             }
250 328
         ]),
251 329
             Coordinate {
252 330
                 x: 5,
253 331
                 y: 7,
332
+                letter: '+',
254 333
             }
255 334
         )
256 335
     }
257 336
 
258 337
     #[test]
259 338
     fn creates_grid() {
339
+        let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
260 340
         assert_eq!(
261
-            create_grid(Coordinate { x: 1, y: 1 }),
262
-            vec![
263
-                GridPoint::Unfilled {
264
-                    x: 0,
265
-                    y: 0,
266
-                },
267
-                GridPoint::Unfilled {
268
-                    x: 0,
269
-                    y: 1,
270
-                },
271
-                GridPoint::Unfilled {
272
-                    x: 1,
273
-                    y: 0,
274
-                },
275
-                GridPoint::Unfilled {
276
-                    x: 1,
277
-                    y: 1,
278
-                },
279
-            ])
341
+            create_grid(boundary_coord),
342
+            Grid {
343
+                points: vec![
344
+                    GridPoint::Unfilled {
345
+                        x: 0,
346
+                        y: 0,
347
+                    },
348
+                    GridPoint::Unfilled {
349
+                        x: 1,
350
+                        y: 0,
351
+                    },
352
+                    GridPoint::Unfilled {
353
+                        x: 0,
354
+                        y: 1,
355
+                    },
356
+                    GridPoint::Unfilled {
357
+                        x: 1,
358
+                        y: 1,
359
+                    },
360
+                ],
361
+                boundary_coord,
362
+            })
280 363
     }
281 364
 
282 365
     #[test]
@@ -288,72 +371,94 @@ mod tests {
288 371
 
289 372
     #[test]
290 373
     fn fills_grid_with_one_coord() {
291
-        let boundary_coord = Coordinate { x: 1, y: 1 };
374
+        let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
292 375
         let mut grid = create_grid(boundary_coord);
293
-        let coord = Coordinate { x: 0, y: 0 };
376
+        let coord = Coordinate { x: 0, y: 0, letter: 'a' };
294 377
         assert_eq!(
295
-            fill_grid(&mut grid, vec![coord], boundary_coord).unwrap(),
296
-            &mut vec![
297
-                GridPoint::Filled {
298
-                    x: 0,
299
-                    y: 0,
300
-                    closest_coord: coord,
301
-                    closest_dist: 0,
302
-                },
303
-                GridPoint::Filled {
304
-                    x: 0,
305
-                    y: 1,
306
-                    closest_coord: coord,
307
-                    closest_dist: 1,
308
-                },
309
-                GridPoint::Filled {
310
-                    x: 1,
311
-                    y: 0,
312
-                    closest_coord: coord,
313
-                    closest_dist: 1,
314
-                },
315
-                GridPoint::Filled {
316
-                    x: 1,
317
-                    y: 1,
318
-                    closest_coord: coord,
319
-                    closest_dist: 2,
320
-                },
321
-            ]
378
+            fill_grid(&mut grid, &vec![coord]).unwrap(),
379
+            &mut Grid {
380
+                points: vec![
381
+                    GridPoint::Filled {
382
+                        x: 0,
383
+                        y: 0,
384
+                        closest_coord: coord,
385
+                        closest_dist: 0,
386
+                    },
387
+                    GridPoint::Filled {
388
+                        x: 1,
389
+                        y: 0,
390
+                        closest_coord: coord,
391
+                        closest_dist: 1,
392
+                    },
393
+                    GridPoint::Filled {
394
+                        x: 0,
395
+                        y: 1,
396
+                        closest_coord: coord,
397
+                        closest_dist: 1,
398
+                    },
399
+                    GridPoint::Filled {
400
+                        x: 1,
401
+                        y: 1,
402
+                        closest_coord: coord,
403
+                        closest_dist: 2,
404
+                    },
405
+                ],
406
+                boundary_coord
407
+            }
322 408
         );
323 409
     }
324 410
 
325 411
     #[test]
326 412
     fn fills_grid_with_two_coords() {
327
-        let boundary_coord = Coordinate { x: 1, y: 1 };
413
+        let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
328 414
         let mut grid = create_grid(boundary_coord);
329
-        let coord_a = Coordinate { x: 0, y: 0 };
330
-        let coord_b = Coordinate { x: 1, y: 1 };
415
+        let coord_a = Coordinate { x: 0, y: 0, letter: 'a' };
416
+        let coord_b = Coordinate { x: 1, y: 1, letter: 'b' };
331 417
         assert_eq!(
332
-            fill_grid(&mut grid, vec![coord_a, coord_b], boundary_coord).unwrap(),
333
-            &mut vec![
334
-                GridPoint::Filled {
335
-                    x: 0,
336
-                    y: 0,
337
-                    closest_coord: coord_a,
338
-                    closest_dist: 0,
339
-                },
340
-                GridPoint::Tied {
341
-                    x: 0,
342
-                    y: 1,
343
-                    closest_dist: 1,
344
-                },
345
-                GridPoint::Tied {
346
-                    x: 1,
347
-                    y: 0,
348
-                    closest_dist: 1,
349
-                },
350
-                GridPoint::Filled {
351
-                    x: 1,
352
-                    y: 1,
353
-                    closest_coord: coord_b,
354
-                    closest_dist: 2,
355
-                },
356
-            ]
418
+            fill_grid(&mut grid, &vec![coord_a, coord_b]).unwrap(),
419
+            &mut Grid {
420
+                points: vec![
421
+                    GridPoint::Filled {
422
+                        x: 0,
423
+                        y: 0,
424
+                        closest_coord: coord_a,
425
+                        closest_dist: 0,
426
+                    },
427
+                    GridPoint::Tied {
428
+                        x: 1,
429
+                        y: 0,
430
+                        closest_dist: 1,
431
+                    },
432
+                    GridPoint::Tied {
433
+                        x: 0,
434
+                        y: 1,
435
+                        closest_dist: 1,
436
+                    },
437
+                    GridPoint::Filled {
438
+                        x: 1,
439
+                        y: 1,
440
+                        closest_coord: coord_b,
441
+                        closest_dist: 0,
442
+                    },
443
+                ],
444
+                boundary_coord
445
+            }
446
+        );
447
+    }
448
+
449
+    #[test]
450
+    fn finds_largest_coord_area() {
451
+        let boundary_coord = Coordinate { x: 2, y: 2, letter: '+' };
452
+        let mut grid = create_grid(boundary_coord);
453
+        let coords = vec![
454
+            Coordinate { x: 0, y: 0, letter: 'a' },
455
+            Coordinate { x: 2, y: 2, letter: 'b' },
456
+            Coordinate { x: 1, y: 1, letter: 'c' },
457
+        ];
458
+        fill_grid(&mut grid, &coords).unwrap();
459
+        assert_eq!(
460
+            find_largest_coord_area(grid),
461
+            1
357 462
         );
358 463
     }
359 464
 }

+ 17 - 15
src/main.rs

@@ -9,19 +9,21 @@ mod day5;
9 9
 mod day6;
10 10
 
11 11
 fn main() {
12
-    println!("Day 1:");
13
-    println!("{}", day1::solve_part1().unwrap());
14
-    println!("{}", day1::solve_part2().unwrap().unwrap());
15
-    println!("Day 2:");
16
-    println!("{}", day2::solve_part1().unwrap());
17
-    println!("{}", day2::solve_part2().unwrap().unwrap());
18
-    println!("Day 3:");
19
-    println!("{}", day3::solve_part1().unwrap());
20
-    println!("{}", day3::solve_part2().unwrap().unwrap());
21
-    println!("Day 4:");
22
-    println!("{}", day4::solve_part1().unwrap());
23
-    println!("{}", day4::solve_part2().unwrap());
24
-    println!("Day 5:");
25
-    println!("{}", day5::solve_part1().unwrap());
26
-    println!("{}", day5::solve_part2().unwrap());
12
+    // println!("Day 1:");
13
+    // println!("{}", day1::solve_part1().unwrap());
14
+    // println!("{}", day1::solve_part2().unwrap().unwrap());
15
+    // println!("Day 2:");
16
+    // println!("{}", day2::solve_part1().unwrap());
17
+    // println!("{}", day2::solve_part2().unwrap().unwrap());
18
+    // println!("Day 3:");
19
+    // println!("{}", day3::solve_part1().unwrap());
20
+    // println!("{}", day3::solve_part2().unwrap().unwrap());
21
+    // println!("Day 4:");
22
+    // println!("{}", day4::solve_part1().unwrap());
23
+    // println!("{}", day4::solve_part2().unwrap());
24
+    // println!("Day 5:");
25
+    // println!("{}", day5::solve_part1().unwrap());
26
+    // println!("{}", day5::solve_part2().unwrap());
27
+    println!("Day 6:");
28
+    println!("{}", day6::solve_part1().unwrap());
27 29
 }