forked from encse/adventofcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c1bfdf
commit 5ba3bdd
Showing
4 changed files
with
100 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,106 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
using System.Text; | ||
using AngleSharp.Media.Dom; | ||
|
||
namespace AdventOfCode.Y2023.Day12; | ||
|
||
[ProblemName("Hot Springs")] | ||
class Solution : Solver | ||
{ | ||
private readonly Dictionary<(long, long, long), long> dp = new(); | ||
|
||
public object PartOne(string input) | ||
{ | ||
var lines = ParseLines(input); | ||
var answer = 0; | ||
|
||
foreach (var line in lines) | ||
long answer = 0; | ||
foreach (var line in ParseLines(input)) | ||
{ | ||
var splits = line.Split(" ", StringSplitOptions.RemoveEmptyEntries); | ||
var dots = splits[0]; | ||
var numbers = splits[1]; | ||
|
||
var blocks = numbers.Split(",") | ||
.Select(int.Parse); | ||
|
||
var score = Resolve(dots, blocks, 0); | ||
.Select(int.Parse) | ||
.ToList(); | ||
|
||
dp.Clear(); | ||
|
||
var score = Resolve(dots, blocks, 0, 0, 0); | ||
answer += score; | ||
} | ||
|
||
return answer; | ||
} | ||
|
||
public object PartTwo(string input) | ||
{ | ||
var lines = ParseLines(input); | ||
return 0; | ||
long answer = 0; | ||
foreach (var line in ParseLines(input)) | ||
{ | ||
var splits = line.Split(" ", StringSplitOptions.RemoveEmptyEntries); | ||
var dots = string.Join("?", Enumerable.Repeat(splits[0], 5)); | ||
var numbers = string.Join(",", Enumerable.Repeat(splits[1], 5)); | ||
var blocks = numbers.Split(",") | ||
.Select(int.Parse) | ||
.ToList(); | ||
|
||
dp.Clear(); | ||
|
||
var score = Resolve(dots, blocks, 0, 0, 0); | ||
answer += score; | ||
} | ||
|
||
return answer; | ||
} | ||
|
||
private static string[] ParseLines(string input) => | ||
input.Split("\n", StringSplitOptions.RemoveEmptyEntries); | ||
private static int Resolve(string dots, IEnumerable<int> blocks, int index) | ||
|
||
private long Resolve(string dots, IReadOnlyList<int> blocks, int index, int blockIndex, long current) | ||
{ | ||
if (index == dots.Length) | ||
{ | ||
return IsValid(dots, blocks) ? 1 : 0; | ||
} | ||
var key = (index, blockIndex, current); | ||
|
||
if (dots[index] == '?') | ||
if (dp.TryGetValue(key, out long value)) | ||
{ | ||
return Resolve($"{dots[..index]}#{dots[(index+1)..]}", blocks, index+1) + | ||
Resolve($"{dots[..index]}.{dots[(index+1)..]}", blocks, index+1); | ||
return value; | ||
} | ||
|
||
return Resolve(dots, blocks, index+1); | ||
} | ||
|
||
private static bool IsValid(string dots, IEnumerable<int> blocks) | ||
{ | ||
var current = 0; | ||
List<int> seen = []; | ||
|
||
foreach (var dot in dots) | ||
if (index == dots.Length) | ||
{ | ||
if (dot == '.') | ||
{ | ||
if (current > 0) | ||
{ | ||
seen.Add(current); | ||
} | ||
|
||
current = 0; | ||
} | ||
else if (dot == '#') | ||
if (blockIndex == blocks.Count && current == 0) | ||
{ | ||
current++; | ||
return 1; | ||
} | ||
else | ||
|
||
if (blockIndex == blocks.Count - 1 && blocks[(int)blockIndex] == current) | ||
{ | ||
throw new Exception("Invalid dot"); | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
if (current > 0) | ||
long answer = 0; | ||
|
||
foreach (var c in new[] { '.', '#' }) | ||
{ | ||
seen.Add(current); | ||
if (dots[(int)index] == c || dots[(int)index] == '?') | ||
{ | ||
if (c == '.' && current == 0) | ||
{ | ||
answer += Resolve(dots, blocks, index + 1, blockIndex, 0); | ||
} | ||
else if (c == '.' && current > 0 && blockIndex < blocks.Count() && blocks[(int)blockIndex] == current) | ||
{ | ||
answer += Resolve(dots, blocks, index + 1, blockIndex + 1, 0); | ||
} | ||
else if (c == '#') | ||
{ | ||
answer += Resolve(dots, blocks, index + 1, blockIndex, current + 1); | ||
} | ||
} | ||
} | ||
|
||
return seen.SequenceEqual(blocks); | ||
dp.Add(key, answer); | ||
|
||
return answer; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
7939 | ||
850504257483930 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.