Add various uncommitted 2021 files for posterity

This commit is contained in:
Josh Creek
2022-10-12 18:28:43 +01:00
parent 3b3a25b9cd
commit fd8b8c7ef1
16 changed files with 848 additions and 18 deletions
+2 -2
View File
@@ -9,9 +9,9 @@
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/2021/03/bin/Debug/net6.0/03.dll",
"program": "${workspaceFolder}/2021/09/bin/Debug/net6.0/09.dll",
"args": [],
"cwd": "${workspaceFolder}/2021/03",
"cwd": "${workspaceFolder}/2021/09",
"console": "internalConsole",
"stopAtEntry": false
},
+3 -3
View File
@@ -7,7 +7,7 @@
"type": "process",
"args": [
"build",
"${workspaceFolder}/2021/03/03.csproj",
"${workspaceFolder}/2021/04/04.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
@@ -19,7 +19,7 @@
"type": "process",
"args": [
"publish",
"${workspaceFolder}/2021/03/03.csproj",
"${workspaceFolder}/2021/04/04.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
@@ -32,7 +32,7 @@
"args": [
"watch",
"run",
"${workspaceFolder}/2021/03/03.csproj",
"${workspaceFolder}/2021/04/04.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
+6
View File
@@ -8,4 +8,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Update="input.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+48
View File
@@ -56,12 +56,18 @@
string secondHalf = line.Substring(line.IndexOf("|") + 1);
List<string> numberSegments = secondHalf.Split(' ').ToList();
string lineTotal = string.Empty;
foreach (string numberSegment in numberSegments)
{
// Go through sorted in alphabetical order
string alphabetisedNumberSegment = String.Concat(numberSegment.OrderBy(c => c));
Console.WriteLine(alphabetisedNumberSegment);
if(alphabetisedNumberSegment == String.Concat("acedgfb".OrderBy(c => c)))
{
@@ -103,6 +109,8 @@
{
lineTotal += "1";
}
Console.WriteLine(lineTotal);
}
Console.WriteLine(lineTotal);
@@ -114,5 +122,45 @@
Console.WriteLine(total);
}
static Dictionary<int, string> DetermineMapping(string[] lines)
{
Dictionary<int, string> mapping = new Dictionary<int, string>();
foreach (string line in lines)
{
string secondHalf = line.Substring(line.IndexOf("|") + 1);
List<string> numberSegments = secondHalf.Split(' ').ToList();
foreach (string numberSegment in numberSegments)
{
switch (numberSegment.Length)
{
case 7:
// 8 has only 7 segments/letters
mapping.Add(8, numberSegment);
break;
case 3:
// 7 has only 3 segments/letters
mapping.Add(7, numberSegment);
break;
case 4:
// 4 has only 4 segments/letters
mapping.Add(4, numberSegment);
break;
case 2:
// 1 has only 2 segments/letters
mapping.Add(1, numberSegment);
break;
default:
// handle the non-unique lengths (0,2,3,5,6,9)
break;
}
}
}
return mapping;
}
}
}
+1 -10
View File
@@ -1,10 +1 @@
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
+17
View File
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>_11</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Update="input.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+175
View File
@@ -0,0 +1,175 @@
namespace Day11
{
class Program
{
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("input.txt");
Part1(lines);
//Part2(lines);
}
static void Part1(string[] lines)
{
int[,] octopusses = new int[10, 10];
// Load initial values
for (int i = 0; i < lines.Length; i++)
{
for (int k = 0; k < lines[i].Length; k++)
{
octopusses[i, k] = int.Parse(lines[i][k].ToString());
}
}
Console.WriteLine("Begin");
int totalFlashes = 0;
// How many total flashes are there after 100 steps?
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"Start {i}");
PerformStep(ref octopusses, ref totalFlashes);
Console.WriteLine($"End {i}");
}
Console.WriteLine($"There were {totalFlashes} total flashes after 100 steps.");
}
static void PerformStep(ref int[,] octopusses, ref int totalFlashes)
{
// First, the energy level of each octopus increases by 1.
for (int i = 0; i < 10; i++)
{
for (int k = 0; k < 10; k++)
{
octopusses[i, k] += 1;
}
}
bool[,] octopussFlashedDuringThisStep = new bool[10, 10];
// Then, any octopus with an energy level greater than 9 flashes.
// This increases the energy level of all adjacent octopuses by 1, including octopuses that
// are diagonally adjacent. If this causes an octopus to have an energy level greater than 9,
// it also flashes.This process continues as long as new octopuses keep having their energy
// level increased beyond 9. (An octopus can only flash at most once per step.)
bool stillFlashing = true;
while (stillFlashing)
{
// Loop through all
for (int i = 0; i < 10; i++)
{
for (int k = 0; k < 10; k++)
{
// mark any with a 9 as having flashed
if (octopusses[i, k] == 9)
{
if (!octopussFlashedDuringThisStep[i, k])
{
octopussFlashedDuringThisStep[i, k] = true;
totalFlashes += 1;
// handle any incrementing of neighbours of those who have flashed
List<(int x, int y)> neighbours = FindAdjacentCellsInclDiagonals((i, k), ref octopusses);
foreach ((int x, int y) neighbour in neighbours)
{
octopusses[neighbour.x, neighbour.y] += 1;
}
}
}
}
}
// if there are no 9s left then stop flashing
if (!ValueIsIn2dArray(9, octopusses))
{
stillFlashing = false;
}
}
// Finally, any octopus that flashed during this step has its energy level set to 0, as it
// used all of its energy to flash.
for (int i = 0; i < 10; i++)
{
for (int k = 0; k < 10; k++)
{
if (octopussFlashedDuringThisStep[i, k] == true)
{
octopusses[i, k] = 0; ;
}
}
}
}
static bool ValueIsIn2dArray(int value, int[,] twoDimensionalArray)
{
for (int x = 0; x < twoDimensionalArray.GetLength(0); x++)
{
for (int y = 0; y < twoDimensionalArray.GetLength(1); y++)
{
if (twoDimensionalArray[x, y] == value)
{
return true;
}
}
}
return false;
}
static List<(int x, int y)> FindAdjacentCellsInclDiagonals((int x, int y) currentCell, ref int[,] twoDimensionalArray)
{
List<(int x, int y)> list = new List<(int x, int y)>();
if (currentCell.x >= 1 && currentCell.y >= 1)
{
list.Add((currentCell.x - 1, currentCell.y - 1));
}
if (currentCell.y >= 1)
{
list.Add((currentCell.x, currentCell.y - 1));
}
if (currentCell.x < twoDimensionalArray.GetLength(0) - 1 && currentCell.y >= 1)
{
list.Add((currentCell.x + 1, currentCell.y - 1));
}
if (currentCell.x >= 1)
{
list.Add((currentCell.x - 1, currentCell.y));
}
if (currentCell.x < twoDimensionalArray.GetLength(0) - 1)
{
list.Add((currentCell.x + 1, currentCell.y));
}
if (currentCell.x >= 1 && currentCell.y < twoDimensionalArray.GetLength(1) - 1)
{
list.Add((currentCell.x - 1, currentCell.y + 1));
}
if (currentCell.y < twoDimensionalArray.GetLength(1) - 1)
{
list.Add((currentCell.x, currentCell.y + 1));
}
if (currentCell.x < twoDimensionalArray.GetLength(0) - 1 && currentCell.y < twoDimensionalArray.GetLength(1) - 1)
{
list.Add((currentCell.x + 1, currentCell.y + 1));
}
return list;
}
}
}
+293
View File
@@ -0,0 +1,293 @@
--- Day 11: Dumbo Octopus ---
You enter a large cavern full of rare bioluminescent dumbo octopuses! They seem to not like the Christmas lights on your submarine, so you turn them off for now.
There are 100 octopuses arranged neatly in a 10 by 10 grid. Each octopus slowly gains energy over time and flashes brightly for a moment when its energy is full. Although your lights are off, maybe you could navigate through the cave without disturbing the octopuses if you could predict when the flashes of light will happen.
Each octopus has an energy level - your submarine can remotely measure the energy level of each octopus (your puzzle input). For example:
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526
The energy level of each octopus is a value between 0 and 9. Here, the top-left octopus has an energy level of 5, the bottom-right one has an energy level of 6, and so on.
You can model the energy levels and flashes of light in steps. During a single step, the following occurs:
First, the energy level of each octopus increases by 1.
Then, any octopus with an energy level greater than 9 flashes. This increases the energy level of all adjacent octopuses by 1, including octopuses that are diagonally adjacent. If this causes an octopus to have an energy level greater than 9, it also flashes. This process continues as long as new octopuses keep having their energy level increased beyond 9. (An octopus can only flash at most once per step.)
Finally, any octopus that flashed during this step has its energy level set to 0, as it used all of its energy to flash.
Adjacent flashes can cause an octopus to flash on a step even if it begins that step with very little energy. Consider the middle octopus with 1 energy in this situation:
Before any steps:
11111
19991
19191
19991
11111
After step 1:
34543
40004
50005
40004
34543
After step 2:
45654
51115
61116
51115
45654
An octopus is highlighted when it flashed during the given step.
Here is how the larger example above progresses:
Before any steps:
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526
After step 1:
6594254334
3856965822
6375667284
7252447257
7468496589
5278635756
3287952832
7993992245
5957959665
6394862637
After step 2:
8807476555
5089087054
8597889608
8485769600
8700908800
6600088989
6800005943
0000007456
9000000876
8700006848
After step 3:
0050900866
8500800575
9900000039
9700000041
9935080063
7712300000
7911250009
2211130000
0421125000
0021119000
After step 4:
2263031977
0923031697
0032221150
0041111163
0076191174
0053411122
0042361120
5532241122
1532247211
1132230211
After step 5:
4484144000
2044144000
2253333493
1152333274
1187303285
1164633233
1153472231
6643352233
2643358322
2243341322
After step 6:
5595255111
3155255222
3364444605
2263444496
2298414396
2275744344
2264583342
7754463344
3754469433
3354452433
After step 7:
6707366222
4377366333
4475555827
3496655709
3500625609
3509955566
3486694453
8865585555
4865580644
4465574644
After step 8:
7818477333
5488477444
5697666949
4608766830
4734946730
4740097688
6900007564
0000009666
8000004755
6800007755
After step 9:
9060000644
7800000976
6900000080
5840000082
5858000093
6962400000
8021250009
2221130009
9111128097
7911119976
After step 10:
0481112976
0031112009
0041112504
0081111406
0099111306
0093511233
0442361130
5532252350
0532250600
0032240000
After step 10, there have been a total of 204 flashes. Fast forwarding, here is the same configuration every 10 steps:
After step 20:
3936556452
5686556806
4496555690
4448655580
4456865570
5680086577
7000009896
0000000344
6000000364
4600009543
After step 30:
0643334118
4253334611
3374333458
2225333337
2229333338
2276733333
2754574565
5544458511
9444447111
7944446119
After step 40:
6211111981
0421111119
0042111115
0003111115
0003111116
0065611111
0532351111
3322234597
2222222976
2222222762
After step 50:
9655556447
4865556805
4486555690
4458655580
4574865570
5700086566
6000009887
8000000533
6800000633
5680000538
After step 60:
2533334200
2743334640
2264333458
2225333337
2225333338
2287833333
3854573455
1854458611
1175447111
1115446111
After step 70:
8211111164
0421111166
0042111114
0004211115
0000211116
0065611111
0532351111
7322235117
5722223475
4572222754
After step 80:
1755555697
5965555609
4486555680
4458655580
4570865570
5700086566
7000008666
0000000990
0000000800
0000000000
After step 90:
7433333522
2643333522
2264333458
2226433337
2222433338
2287833333
2854573333
4854458333
3387779333
3333333333
After step 100:
0397666866
0749766918
0053976933
0004297822
0004229892
0053222877
0532222966
9322228966
7922286866
6789998766
After 100 steps, there have been a total of 1656 flashes.
Given the starting energy levels of the dumbo octopuses in your cavern, simulate 100 steps. How many total flashes are there after 100 steps?
View File
+10
View File
@@ -0,0 +1,10 @@
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526
+67 -3
View File
@@ -8,13 +8,77 @@ namespace Day14
{
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("input.txt");
var sr = new StreamReader("input.txt");
var translate = new Dictionary<string, string>();
string polymer = sr.ReadLine();
//Part1(lines);
Part2(lines);
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
if (line.Length > 0)
{
var p = line.Split(" -> ");
translate.Add(p[0], p[1]);
}
}
var pairs = new Dictionary<string, ulong>();
var elements = new Dictionary<string, ulong>();
for (int k = 0; k < polymer.Length - 1; k++)
{
var p = polymer.Substring(k, 2);
pairs.TryAdd(p, 0);
pairs[p]++;
}
for (int k = 0; k < polymer.Length; k++)
{
elements.TryAdd(polymer[k].ToString(), 0);
elements[polymer[k].ToString()]++;
}
for (int i = 0; i < 40; i++)
{
var newpairs = new Dictionary<string, ulong>();
foreach (var p in pairs.Keys)
{
var insert = translate[p];
var c = pairs[p];
newpairs.TryAdd(p[0] + insert, 0);
newpairs[p[0] + insert] += c;
newpairs.TryAdd(insert + p[1], 0);
newpairs[insert + p[1]] += c;
elements.TryAdd(insert, 0);
elements[insert] += c;
}
pairs = newpairs;
}
ulong min = ulong.MaxValue;
ulong max = ulong.MinValue;
ulong sum = 0;
foreach (var a in elements.Values)
{
if (a > max) max = a;
if (a < min) min = a;
sum += a;
}
Console.WriteLine($"Result: {max} - {min} = {max - min}, length = {sum}");
}
//static void Main(string[] args)
//{
// string[] lines = File.ReadAllLines("input.txt");
// //Part1(lines);
// Part2(lines);
//}
static void Part1(string[] lines)
{
string polymerTemplate = lines[0];
+101
View File
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Day15
{
public class Dijkstra
{
public object PartOne(string input) => Solve(GetRiskLevelMap(input));
public object PartTwo(string input) => Solve(ScaleUp(GetRiskLevelMap(input)));
int Solve(Dictionary<Point, int> riskMap)
{
// Disjktra algorithm
var topLeft = new Point(0, 0);
var bottomRight = new Point(riskMap.Keys.MaxBy(p => p.x).x, riskMap.Keys.MaxBy(p => p.y).y);
// Visit points in order of cumulted risk
// ⭐ .Net 6 finally has a PriorityQueue collection :)
var q = new PriorityQueue<Point, int>();
var totalRiskMap = new Dictionary<Point, int>();
totalRiskMap[topLeft] = 0;
q.Enqueue(topLeft, 0);
// It would be enough to go until we find the bottom right corner, but computing all
// risk levels is not much more work
while (q.Count > 0)
{
var p = q.Dequeue();
foreach (var n in Neighbours(p))
{
if (riskMap.ContainsKey(n) && !totalRiskMap.ContainsKey(n))
{
var totalRisk = totalRiskMap[p] + riskMap[n];
totalRiskMap[n] = totalRisk;
if (n == bottomRight)
{
break;
}
var h = 0; //bottomRight.y - n.y + bottomRight.x - n.x;
q.Enqueue(n, totalRisk + h);
}
}
}
// return bottom right corner's total risk:
return totalRiskMap[bottomRight];
}
// Create an 5x scaled up map, as described in part 2
Dictionary<Point, int> ScaleUp(Dictionary<Point, int> map)
{
var (ccol, crow) = (map.Keys.MaxBy(p => p.x).x + 1, map.Keys.MaxBy(p => p.y).y + 1);
var res = new Dictionary<Point, int>(
from y in Enumerable.Range(0, crow * 5)
from x in Enumerable.Range(0, ccol * 5)
// x, y and risk level in the original map:
let tileY = y % crow
let tileX = x % ccol
let tileRiskLevel = map[new Point(tileX, tileY)]
// risk level is increased by tile distance from origin:
let tileDistance = (y / crow) + (x / ccol)
// risk level wraps around from 9 to 1:
let riskLevel = (tileRiskLevel + tileDistance - 1) % 9 + 1
select new KeyValuePair<Point, int>(new Point(x, y), riskLevel)
);
return res;
}
// store the points in a dictionary so that we can iterate over them and
// to easily deal with points outside the area
Dictionary<Point, int> GetRiskLevelMap(string input)
{
var map = input.Split("\n");
return new Dictionary<Point, int>(
from y in Enumerable.Range(0, map[0].Length)
from x in Enumerable.Range(0, map.Length)
select new KeyValuePair<Point, int>(new Point(x, y), map[y][x] - '0')
);
}
IEnumerable<Point> Neighbours(Point point) =>
new[] {
point with {y = point.y + 1},
point with {y = point.y - 1},
point with {x = point.x + 1},
point with {x = point.x - 1},
};
}
}
record Point(int x, int y);
+124
View File
@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// A C# program for Dijkstra1's single
// source shortest path algorithm.
// The program is for adjacency matrix
// representation of the graph
namespace Day15
{
class Dijkstra1
{
// A utility function to find the
// vertex with minimum distance
// value, from the set of vertices
// not yet included in shortest
// path tree
static int V = 9;
int minDistance(int[] dist,
bool[] sptSet)
{
// Initialize min value
int min = int.MaxValue, min_index = -1;
for (int v = 0; v < V; v++)
if (sptSet[v] == false && dist[v] <= min)
{
min = dist[v];
min_index = v;
}
return min_index;
}
// A utility function to print
// the constructed distance array
void printSolution(int[] dist, int n)
{
Console.Write("Vertex Distance "
+ "from Source\n");
for (int i = 0; i < V; i++)
Console.Write(i + " \t\t " + dist[i] + "\n");
}
// Function that implements Dijkstra1's
// single source shortest path algorithm
// for a graph represented using adjacency
// matrix representation
public void dijkstra(int[,] graph, int src)
{
int[] dist = new int[V]; // The output array. dist[i]
// will hold the shortest
// distance from src to i
// sptSet[i] will true if vertex
// i is included in shortest path
// tree or shortest distance from
// src to i is finalized
bool[] sptSet = new bool[V];
// Initialize all distances as
// INFINITE and stpSet[] as false
for (int i = 0; i < V; i++)
{
dist[i] = int.MaxValue;
sptSet[i] = false;
}
// Distance of source vertex
// from itself is always 0
dist[src] = 0;
// Find shortest path for all vertices
for (int count = 0; count < V - 1; count++)
{
// Pick the minimum distance vertex
// from the set of vertices not yet
// processed. u is always equal to
// src in first iteration.
int u = minDistance(dist, sptSet);
// Mark the picked vertex as processed
sptSet[u] = true;
// Update dist value of the adjacent
// vertices of the picked vertex.
for (int v = 0; v < V; v++)
// Update dist[v] only if is not in
// sptSet, there is an edge from u
// to v, and total weight of path
// from src to v through u is smaller
// than current value of dist[v]
if (!sptSet[v] && graph[u, v] != 0 &&
dist[u] != int.MaxValue && dist[u] + graph[u, v] < dist[v])
dist[v] = dist[u] + graph[u, v];
}
// print the constructed distance array
printSolution(dist, V);
}
// Driver Code
// public static void Main()
// {
// /* Let us create the example
//graph discussed above */
// int[,] graph = new int[,] { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },
// { 4, 0, 8, 0, 0, 0, 0, 11, 0 },
// { 0, 8, 0, 7, 0, 4, 0, 0, 2 },
// { 0, 0, 7, 0, 9, 14, 0, 0, 0 },
// { 0, 0, 0, 9, 0, 10, 0, 0, 0 },
// { 0, 0, 4, 14, 10, 0, 2, 0, 0 },
// { 0, 0, 0, 0, 0, 2, 0, 1, 6 },
// { 8, 11, 0, 0, 0, 0, 1, 0, 7 },
// { 0, 0, 2, 0, 0, 0, 6, 7, 0 } };
// Dijkstra1 t = new Dijkstra1();
// t.dijkstra(graph, 0);
// }
}
}
View File
View File
+1
View File
@@ -0,0 +1 @@
EE00D40C823060