@@ -15,84 +15,56 @@ protected override List<List<int>> ParseInput(string input)
15
15
protected override object SolvePart1 ( List < List < int > > reports )
16
16
{
17
17
return reports
18
- . Select ( report => report . Steps ( ) . ToList ( ) )
19
- . Count ( steps => steps . AllInRange ( ) && ( steps . AllIncreasing ( ) || steps . AllDecreasing ( ) ) ) ;
18
+ . Count ( report => report . Steps ( ) . AreSafe ( ) ) ;
20
19
}
21
20
22
21
protected override object SolvePart2 ( List < List < int > > reports )
23
22
{
24
23
var safeReports = reports
25
- . Where ( report =>
26
- {
27
- var steps = report . Steps ( ) . ToList ( ) ;
28
- return steps . AllInRange ( ) && ( steps . AllIncreasing ( ) || steps . AllDecreasing ( ) ) ;
29
- } )
30
- . ToList ( ) ;
31
-
32
- var unsafeReports = reports . Except ( safeReports ) . ToList ( ) ;
33
-
34
- unsafeReports . ForEach ( report =>
35
- {
36
- var wrongStep = report . Steps ( ) . ToList ( ) . FindIndex ( ( number ) => report . IsIncreasing ( ) ? number is < 1 or > 3 : number is < - 3 or > - 1 ) ;
37
-
38
- for ( var index = Math . Max ( 0 , wrongStep - 1 ) ; index < Math . Min ( wrongStep + 2 , report . Count ) ; index ++ )
39
- {
40
- var filteredReport = report . ToList ( ) ;
41
- filteredReport . RemoveAt ( index ) ;
42
- var steps = filteredReport . Steps ( ) . ToList ( ) ;
24
+ . Where ( report => report . Steps ( ) . AreSafe ( ) )
25
+ . ToArray ( ) ;
43
26
44
- if ( steps . AllInRange ( ) && ( steps . AllIncreasing ( ) || steps . AllDecreasing ( ) ) )
45
- {
46
- safeReports . Add ( report ) ;
47
- break ;
48
- }
49
- }
50
- } ) ;
27
+ var fixedReports = reports
28
+ . Except ( safeReports )
29
+ . Select ( report => ( Report : report , Steps : report . Steps ( ) , Increasing : report [ ^ 1 ] > report [ 0 ] ) )
30
+ . Select ( data => ( Report : data . Report , WrongStep : data . FindFirstWrongStep ( ) ) )
31
+ . Count ( data => data . Report . CompensateForStep ( data . WrongStep ) . Any ( report => report . Steps ( ) . AreSafe ( ) ) ) ;
51
32
52
- return safeReports . Count ;
33
+ return safeReports . Length + fixedReports ;
53
34
}
54
35
}
55
36
56
37
internal static class Day02Extensions
57
38
{
58
- internal static bool AllInRange ( this List < int > numbers )
39
+ internal static bool AreSafe ( this IEnumerable < int > steps )
59
40
{
60
- return numbers . Count ( number => Math . Abs ( number ) is >= 1 and <= 3 ) == numbers . Count ;
61
- }
62
-
63
- internal static bool AllDecreasing ( this List < int > numbers )
64
- {
65
- return numbers . CountDecreasing ( ) == numbers . Count ;
66
- }
67
-
68
- internal static bool AllIncreasing ( this List < int > numbers )
69
- {
70
- return numbers . CountIncreasing ( ) == numbers . Count ;
41
+ return steps . All ( n => n is >= 1 and <= 3 )
42
+ || steps . All ( n => n is >= - 3 and <= - 1 ) ;
71
43
}
72
44
73
- internal static IEnumerable < int > Steps ( this IEnumerable < int > numbers )
45
+ internal static int FindFirstWrongStep ( this ( List < int > Report , List < int > Steps , bool Increasing ) data )
74
46
{
75
- foreach ( var levelSet in numbers . SlidingWindow ( 2 ) )
76
- {
77
- var left = levelSet [ 0 ] ;
78
- var right = levelSet [ 1 ] ;
79
-
80
- yield return right - left ;
81
- }
47
+ return data
48
+ . Steps
49
+ . FindIndex ( ( number ) => data . Increasing ? number is < 1 or > 3 : number is < - 3 or > - 1 ) ;
82
50
}
83
51
84
- internal static bool IsIncreasing ( this List < int > numbers )
52
+ internal static List < int > [ ] CompensateForStep ( this List < int > report , int position )
85
53
{
86
- return numbers [ 1 ] > numbers [ 0 ] ;
87
- }
88
-
89
- private static int CountDecreasing ( this List < int > numbers )
90
- {
91
- return numbers . Count ( number => number < 0 ) ;
54
+ return
55
+ [
56
+ // Create new reports without the values that cause the
57
+ // wrong step at "position" in an attempt to compensate.
58
+ [ ..report [ ..position ] , ..report [ ( position + 1 ) ..] ] ,
59
+ [ ..report [ ..( position + 1 ) ] , ..report [ ( position + 2 ) ..] ]
60
+ ] ;
92
61
}
93
62
94
- private static int CountIncreasing ( this List < int > numbers )
63
+ internal static List < int > Steps ( this IEnumerable < int > numbers )
95
64
{
96
- return numbers . Count ( number => number > 0 ) ;
65
+ return numbers
66
+ . Zip ( numbers . Skip ( 1 ) , Tuple . Create )
67
+ . Select ( tuple => tuple . Item2 - tuple . Item1 )
68
+ . ToList ( ) ;
97
69
}
98
70
}
0 commit comments