Browse Source

Adding day 4

bodicsek 4 years ago
parent
commit
5657830aa7
4 changed files with 728 additions and 41 deletions
  1. 1 1
      .editorconfig
  2. 104 19
      day04/day04.ts
  3. 21 21
      day04/input.test.ts
  4. 602 0
      day04/input.ts

+ 1 - 1
.editorconfig

@@ -9,7 +9,7 @@ root = true
 
 # Change these settings to your own preference
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 # We recommend you to keep these unchanged
 end_of_line = lf

+ 104 - 19
day04/day04.ts

@@ -1,9 +1,15 @@
 import * as O from "fp-ts/Option";
+import * as N from "fp-ts/number";
 
-import { findFirst, map, reduce } from "fp-ts/lib/Array";
+import { chunksOf, concat, every, exists, filter, findFirst, isOutOfBound, map, mapWithIndex, reduce, replicate, tail } from "fp-ts/lib/Array";
 import { pipe } from "fp-ts/lib/function";
+import { concatAll } from "fp-ts/lib/Monoid";
+import { isEmpty } from "fp-ts/lib/string";
 
 import { draws as testDraws, RawTable, tables as testTables } from "./input.test";
+import { draws as inputDraws, tables as inputTables } from "./input";
+
+
 
 type Value = {
   value: number,
@@ -11,34 +17,113 @@ type Value = {
 };
 
 type Table = {
+  id: number;
   lastMarked?: number,
+  won?: number;
   table: Value[][]
 }
 
-const calc = (draws: number[]) => (table: Table) => pipe(
-  draws,
-  reduce(table, (t, d) => pipe(
-    [...t.table],
-    map(findFirst((v: Value) => v.value === d)),
-    reduce(O.none as O.Option<Value>, (v, o) => pipe(o, O.alt(() => v))),
+
+const parseTables = (tables: string) => pipe(
+  tables.split("\n"),
+  filter(s => !isEmpty(s)),
+  chunksOf(5),
+  map(table => pipe(table, map(row => row.split(" ").filter(n => !isEmpty(n)).map(s => parseInt(s)))))
+);
+
+const tables: Table[] = pipe(
+  // testTables,
+  parseTables(inputTables),
+  mapWithIndex<RawTable, Table>((i, t) => ({
+    id: i,
+    table: pipe(t, map(r => pipe(r, map<number, Value>(v => ({ value: v, marked: false })))))
+  }))
+);
+
+const draws: number[] =
+  // testDraws;
+inputDraws;
+
+
+
+const product = (a: number) => (b: number) =>
+  N.MonoidProduct.concat(a, b);
+
+const result = (table: Table): number => pipe(
+  [...table.table],
+  reduce([] as Value[], (all, curr) => pipe(all, concat(curr))),
+  filter(v => !v.marked),
+  map(v => v.value),
+  concatAll(N.MonoidSum),
+  product(table.lastMarked ?? 1)
+);
+
+const evalRows = (table: Table): O.Option<number> => pipe(
+  [...table.table],
+  map(every(v => v.marked)),
+  reduce(false, (acc, r) => acc || r),
+  O.guard,
+  O.map(() => result(table))
+);
+
+const evalColumns = (table: Table): O.Option<number> => pipe(
+  [...table.table],
+  reduce(
+    replicate(table.table[0].length, true),
+    (marks, row) => pipe(row, map(v => v.marked), mapWithIndex((i, m) => marks[i] && m))
+  ),
+  exists(m => m),
+  O.guard,
+  O.map(() => result(table))
+);
+
+const evalTable = (table: Table): Table => pipe(
+  table,
+  evalRows,
+  O.alt(() => evalColumns(table)),
+  O.fold(
+    () => ({...table}),
+    n => ({...table, won: n})
+  )
+);
+
+const findValue = (draw: number) => (table: Table): O.Option<Value> => pipe(
+  [...table.table],
+  map(findFirst((v: Value) => v.value === draw)),
+  reduce(O.none as O.Option<Value>, (v, o) => pipe(v, O.alt(() => o)))
+);
+
+const calc = (tables: Table[]) => (draw: number): Table[] => pipe(
+  tables,
+  filter(t => t.won === undefined),
+  map(t => pipe(
+    t,
+    findValue(draw),
     O.fold<Value, Table>(
-      () => t,
+      () => ({
+        ...t,
+        lastMarked: undefined
+      }),
       v => {
         v.marked = true;
         return {
-          lastMarked: d,
-          table: t.table
+          ...t,
+          lastMarked: draw
         };
       }
-    )))
+    ),
+    evalTable
+  ))
 );
 
-const results = pipe(
-  testTables,
-  map<RawTable, Table>(t => ({
-    table: pipe(t, map(r => pipe(r, map<number, Value>(v => ({ value: v, marked: false })))))
-  })),
-  map(calc(testDraws))
-);
+const play = (ts: Table[], ds: number[]): Table[] => {
+  if(isOutOfBound(0, ds)) {
+    return ts;
+  }
+  const newTables = calc(ts)(ds[0]);
+  console.log("new winners:", pipe(newTables, filter(t => t.won !== undefined)));
+  return play(newTables, pipe(ds, tail, O.getOrElse(() => [] as number[])));
+}
+
 
-console.log("results: ", results[0]);
+play(tables, draws);

+ 21 - 21
day04/input.test.ts

@@ -2,25 +2,25 @@ export const draws = [7, 4, 9, 5, 11, 17, 23, 2, 0, 14, 21, 24, 10, 16, 13, 6, 1
 
 export type RawTable = number[][];
 export const tables: RawTable[] = [
-  [
-    [22, 13, 17, 11, 0],
-    [8, 2, 23, 4, 24],
-    [21, 9, 14, 16, 7],
-    [6, 10, 3, 18, 5],
-    [1, 12, 20, 15, 19]
-  ],
-  [
-    [3, 15, 0, 2, 22],
-    [9, 18, 13, 17, 5],
-    [19, 8, 7, 25, 23],
-    [20, 11, 10, 24, 4],
-    [14, 21, 16, 12, 6]
-  ],
-  [
-    [14, 21, 17, 24, 4],
-    [10, 16, 15, 9, 19],
-    [18, 8, 23, 26, 20],
-    [22, 11, 13, 6, 5],
-    [2, 0, 12, 3, 7]
-  ]
+    [
+        [22, 13, 17, 11, 0],
+        [8, 2, 23, 4, 24],
+        [21, 9, 14, 16, 7],
+        [6, 10, 3, 18, 5],
+        [1, 12, 20, 15, 19]
+    ],
+    [
+        [3, 15, 0, 2, 22],
+        [9, 18, 13, 17, 5],
+        [19, 8, 7, 25, 23],
+        [20, 11, 10, 24, 4],
+        [14, 21, 16, 12, 6]
+    ],
+    [
+        [14, 21, 17, 24, 4],
+        [10, 16, 15, 9, 19],
+        [18, 8, 23, 26, 20],
+        [22, 11, 13, 6, 5],
+        [2, 0, 12, 3, 7]
+    ]
 ];

+ 602 - 0
day04/input.ts

@@ -0,0 +1,602 @@
+export const draws = [93,35,66,15,6,51,49,67,16,77,80,8,1,57,99,92,14,9,13,23,33,11,43,50,60,96,40,25,22,39,56,18,2,7,34,68,26,90,75,41,4,95,71,30,42,5,46,55,27,98,79,12,65,73,29,28,17,48,81,32,59,63,85,91,52,21,38,31,61,83,97,62,44,70,19,69,36,47,74,58,78,24,72,0,10,88,37,87,3,45,82,76,54,84,20,94,86,53,64,89];
+
+export const tables = `14 33 79 61 44
+85 60 38 13 48
+51 34 11 19  7
+21 30 73  6 76
+41  4 65 18 91
+
+ 3 82 68 26 93
+61 90 29 69 92
+60 94 99  6 83
+77 80  2 58 55
+59 65 95 38 62
+
+41  9 73 71 74
+66 24 45  5 55
+97 82 53 63 16
+12 19 88 87 27
+31  8 75 98 83
+
+63 24 86 90 45
+41 92 42 83 77
+64 28 54 94 10
+15 93 57 29 50
+23 39 37 48 38
+
+ 1 31  7  0 54
+ 9 59 79 19 96
+51 14 77 38 45
+30 76 42 65 91
+72 60 37 43 71
+
+22 81 40 97 27
+83 28 41  1 76
+69 68 64 57 78
+59 38 63 89 29
+ 8 58 18 66 72
+
+39 32 21 94 37
+20  1 66 82 52
+10 56 40 13 62
+59 96 44 75 50
+41 83  6 90 28
+
+90 33  1 57 34
+14 86 93 92 68
+54 37 95 11 77
+88 13 62 72 48
+96 65 67 85 80
+
+47 48 82 96 85
+78 91 42 38 11
+79 94 49 24 27
+56 92 72 45 73
+75  0 70  4 68
+
+48 51 94 17 58
+37 88 56 66 16
+27 97 14 45 83
+53 39  6  5 68
+47 57 28 31 11
+
+35 66 19 68 73
+41 49 10 80 48
+39 50 79 23 59
+15 45 40 17 75
+88 86 71  8  0
+
+58 48 41 22 11
+97 59 17 71 44
+ 6 24 49 84 42
+89 27 23 82  9
+60 86 90 65 34
+
+11 58  2 98 26
+90 52 60 14 12
+69 63 56 36 30
+ 3 44 19  5 85
+95 84 31 51 79
+
+39 62 64 29 24
+56  9  0 18  3
+22 74 77 47 98
+55 93 79  4 33
+78 53 11 26 75
+
+38 82  8 25 55
+74  1 21 30 46
+12  4 62 45 52
+24 39  0 92 15
+19 54 51 57 88
+
+16 28 48 19 43
+58 96 67 22 61
+ 8  9 74  5 81
+78 59 49 71 15
+82 46 42 32 70
+
+73 89 80 92 42
+ 4 60 99 75 39
+ 5 50 64 98 91
+49 11  9 51 85
+27 97 54 93 14
+
+70 41 37 53 62
+ 0 57 48 39 61
+10 85 59 74 76
+ 2  7  1  4 81
+26 78 60 80 72
+
+ 8 50 43 73 80
+74 86 64 95 30
+45 69 71 65 55
+52 66 36 62 60
+25 53 63 46  5
+
+ 5 57 15 82 46
+23 96 72 29 43
+98 91 42 51 99
+70 25 64 45 16
+ 4 40 48 97 11
+
+37 93 48 23 99
+98  8 21 78 36
+52 73  5 55 11
+63 42 88 38 94
+ 1 80 71 68 15
+
+51 34 66 87 17
+20 54 74 14 55
+84 64 96 31  2
+62 43 76  5 45
+98 71 50 56 82
+
+13 59 67 25 94
+41 89 27 60  2
+77 31 48 63 62
+24 49 32 76 87
+70 85 51 52 66
+
+31 22 23 36 47
+45 55 61 89 72
+62 81 35 79  8
+24 82 38 91 76
+74  5 29 94 58
+
+ 2 41  6 13 34
+86 46 44 38 56
+28 19 50  1 12
+96 23 33 91 64
+ 7 89 59  9 70
+
+81 69 97 10 87
+83 56  7 53 96
+93 42 68 29 62
+78 66  2 55 60
+ 4  5 15 98 99
+
+80 40 93 94 25
+95 99 55 31 12
+29 90 43 52 38
+51 64 92 37 77
+21  4 85 20 17
+
+44 73 69 38 95
+11 47 19 83 91
+96 92 22 31 21
+70 62 88 25 82
+18 40 98 34 94
+
+ 6 14 86 29 99
+ 8  5 15 38 90
+44 43 51 77 80
+78 32 75 83  3
+53 13 71 66 52
+
+55  3 93 75 54
+58 57 60 15 70
+67 51 81 96 74
+ 6 35 29 32 44
+38 56  5 50 88
+
+38 46 11 16 33
+83  6 88 93 43
+42 56 77  9 85
+76 69 49 58 22
+15 14  4 54 23
+
+27 84 97 50 46
+98 14 60 87 72
+20 38 74 13 32
+18 96 92 21 99
+93 43 86 16 66
+
+53 12 29 78 41
+13 70 71  4 97
+44  1 37 84 49
+17  0 22 72 63
+61 66 60 32 68
+
+92 44 20 56 69
+73 22 18 31 48
+71 93 83 16 49
+81 89 79 38 30
+80 24 26 86 62
+
+82 58 76 20  5
+56 34 84 80 38
+12 49  8 52 91
+41 62  1 77 48
+23 83 51 81  2
+
+77  5 96 13 52
+61 85 46 54 48
+56 80 20 83 69
+39 42 28 87 16
+59 40 45 58 62
+
+35 87 52 85  9
+18 55 71 63 58
+86 28 20  5 68
+26 76 93 66 44
+53  2 95  6 60
+
+19 53 33 59 27
+58 95 74 26  9
+98 25 49 92 44
+76 20 41 66 88
+47 50 57 24 28
+
+54 63 31 74 72
+91 19  3 23 14
+85 44 66 55 33
+18 17 86  7 78
+42 22 15 99 93
+
+33 31 15 40 44
+41 86 18 94 66
+19 69 91 76 95
+99 11 70 42 56
+68 82 90 12 83
+
+79 21 74 63 22
+99 76 27 17 34
+91 52 14  2 26
+13 93 81 35 75
+48 62  0 39  6
+
+61  3 96 95 10
+ 4 39 22 29 49
+ 5  7 15 54 83
+ 2 33 65 62 14
+ 8 73 24 47 87
+
+24 75 54 90  5
+59 26 52 37 23
+11 36 42 47 93
+44 88 45 21 96
+ 6 58 73 60 86
+
+57  2 67 75 90
+87 51 80 35 24
+98 36 79  5 21
+ 6 78  0 94 25
+16  3 81 41 45
+
+63 84 58 52  9
+38 57 87 20 40
+ 5 68 14 98 29
+71 88 21 80 61
+ 3 43 31 48 26
+
+ 2 92 45 28 18
+89 20 90 42 99
+40 52 87 63 91
+13 31 59 24 29
+70 79 34 82 15
+
+95 82 62  2 53
+63 19 10 42 16
+69 28 22 92 56
+11  3 17 76 71
+58 70 27  6 93
+
+83 43 99 11 58
+ 9 79  4 76  6
+18 49 56 36 72
+31 91  8 34 78
+ 7 96 66 98 95
+
+87 31 90 33 53
+70 39 50 73  3
+89 17 64 97 65
+11 85 42 57  6
+88 44 26 47 54
+
+37 90 50 65 25
+68 15 87 33  0
+24 63 30 98 57
+13  7 93 22 34
+55 75 70 14 16
+
+48 77 51 15 33
+84 52 22 73 67
+25 47 34 95 89
+ 3 45 42 17 93
+56 53 68 72  8
+
+60 44 46 84 70
+34 94 76 79 98
+36 37 59 90 22
+23 39  2 48 15
+81  4  7  3 21
+
+60 58 26 10 66
+53 18 38 80 24
+93 56 11 27 21
+51 86 94 64 52
+65 57 28 98 69
+
+32 45 64 94 68
+66 67 53 50 16
+37 60 10 33 70
+76 87 69 78 88
+71 99 63 38 25
+
+54 14 31 45 40
+27 17 91 78 96
+70 84 11 98 75
+ 6 94 72 88 18
+65  9 56 33 92
+
+40 33 82 38 85
+98 91 44 26 57
+73 34 32 25 46
+58  8 16 42 95
+20  1 67 54 90
+
+34 88 27 63 73
+92 70  5 21 15
+ 1 82 74  9 23
+33 66 78 85 30
+ 3 75 53 37 72
+
+22 11 43  8 69
+57 30 72 26 58
+45 55 23 88 21
+53  0 19 31 65
+62 66 46 39 15
+
+57 71 75 51 44
+49 96 10 53 47
+77 93 28 91 74
+70 41 79 89 97
+26 45 59 56 80
+
+28 69 48 13 43
+10 75 80 58 40
+ 1 92 82 94 33
+47 74 60 53 18
+51 11 77  9 55
+
+50  3 89 47 34
+26 15 68 79 45
+94 90 19 59 73
+62 29 46 74 44
+91  5 39 10 14
+
+11 49 87 19  2
+ 9 33 71 57 66
+82 46 83 64 55
+52 76 67 15 73
+88 39 34 85 61
+
+34 82 64 97 39
+53 30 71 22 85
+73 86 88 93 44
+56 25 52 87  4
+67  7 31  2 83
+
+ 9  6 54 84 46
+ 4 75 65 63  1
+81 66 72 71 43
+17 61 51 48 35
+14 56 70 50 13
+
+ 0 48 33 27 35
+ 7 20  9 97 46
+ 8 13 52 11 24
+40 56 50 64 75
+32 92 36 54  5
+
+19 49 78 92 20
+97 87 80 64  9
+26 34 67 21 91
+63 85 68 88 28
+18 93 41 31 79
+
+97 13  9 26 58
+ 1 19 76 31 51
+95 65 37 48 88
+92 72 98 10 43
+69 28 29  5 62
+
+81 86 83 31 43
+37 95 51 42 17
+54  3 99 23 40
+15 72 16  4 78
+49 48 76 38 52
+
+66 97 55  6 62
+38 95 58  7 96
+61 93 45 41 50
+13 51 92  2 52
+15  8 36 37 17
+
+27 60 58 69 16
+ 0 92 24 25 61
+65 28 52 20 99
+87 12  3 21 31
+48 67 63 70 11
+
+51 32 36 37 62
+33 38 46  6 63
+88 97 67 72 84
+54 23  3 81 94
+59 50 40 11 21
+
+30 22 59 53 35
+46 88 12  9 78
+95 31 39 10 67
+86 73 42 43  1
+93 21 16 51 28
+
+61 98 77 62 41
+42 93 58 66 89
+64 14 18 67 76
+21 17 43 79 44
+47  0 20 95 97
+
+47 75 70  8 26
+82 98 13 61 96
+94 74 17 78 30
+15 85 46 31 11
+99 28 39 51 92
+
+ 8 54 19  9 30
+63 90 99  7 50
+14 45 74 65 82
+10 76 85 21 20
+80 48 94  6 93
+
+32 13 76 35  2
+57 51 25 43 85
+89 87 26 15 95
+24 67 33 34 14
+23 47 39 64 71
+
+83 82 79 50 23
+77 60 67  8 32
+55 38 33 26 37
+17 36 69 44 43
+49  9 52 70 39
+
+94 79 82 74 99
+ 7 90  6 76  3
+ 0 91 81 11 17
+ 2 28 29 22 78
+33  1 23 16 86
+
+53 18 72 38  1
+75 70 19 10 99
+34 60 30 61 95
+80 78 51 83 22
+25 23 11  6 44
+
+ 8 17 15 21  6
+46 79 77 11 23
+25 14 59 42 95
+50 16 90 49  2
+81 56 51 96 76
+
+37 27 62  8 35
+67 81 84 47 53
+32 13 80 15 66
+95 94 59 38 97
+64 26 63 75 78
+
+23 71 88 61 20
+35 32 59 10 67
+17 36 38 89 75
+74  8 30 57 39
+97 58 55 70 15
+
+82 37 71 56 15
+92 66 10  1 14
+26 60 70 50 89
+97 58 83  3 61
+41  6 35 88 13
+
+16  7 54  9 31
+47 91 50 17 51
+ 6 38 24 14 69
+48  3  0 77  5
+43 86 70 80 40
+
+39 94 95 47 98
+46 41 45 38 48
+18 73 56 99 76
+74 75 26 30 16
+42 11 85 86 51
+
+39 68 42 79 14
+48 90 75  4 41
+34 76 63 49 83
+64 86 92 98 65
+40 15 54 20  1
+
+17  4 47 37  8
+19 15 36  6 60
+23  5 24 87 55
+51 12 94 18 90
+81  3 86 39 88
+
+58 46 25 13 81
+72 17 64 28 51
+91  1 55 57 49
+20 39 11  5 52
+60 22 24 15 53
+
+40 50 55 39  6
+79 38 44 52 81
+83 36 11 42 88
+48  4 32  8 71
+34 65 51  2 46
+
+21 47 96 94 19
+31 38 55 64 24
+36 57 32  9 34
+43 61 11 41 56
+58  2  4 28 59
+
+47 14 83 62 76
+18 61 22 80 54
+24 87 49 13 40
+44 82 34 78 10
+94 55 29 95 71
+
+68 54 76  1 39
+46  4 50 82 85
+75 26 43 58 98
+29 47 49 81 12
+14 19 57 11 41
+
+65 38  2  0 57
+23 19  4 79 70
+88  8 73 25 34
+15 28 77 24 39
+31 97 11 62 37
+
+29 26 19 14 40
+12 88 22 42 96
+95 63 78 21 53
+35 50  9 39 43
+10 46 24 87 13
+
+ 4 94 52 42 67
+71 33 15 75 80
+45 49 61 64 58
+35 37 62 55 30
+87 79 31 96 41
+
+75 61 94  3 52
+59 13 35 53 54
+85 81 79 96 57
+36 38 40 28 93
+70 95 39 43  5
+
+33 79 74 21 32
+ 0 18 43  5 28
+82 63 66 56 27
+42 76 61 98 73
+83  9  2 96 23
+
+96 47 61 45 89
+40 77 15 55 25
+23 39 10 18 91
+31 70  1 30 75
+67 94 37  4 51
+
+ 3  5 10 80 89
+60 17 42 55 92
+38 32 52  0 56
+96 61 79 34 90
+43  2 98  4 27
+
+74 95 14 35 49
+67 66 57 76 88
+89 71 68 69 48
+20 70  3  0 12
+13 21 15 51 24
+`