public override object Part2() { V2 pos = V2.Zero; V2 waypoint = new V2(10, -1); foreach (var line in lines) { char action = line[0]; int amount = int.Parse(line.Substring(1)); double rad = 0; switch (action) { case 'F': pos += waypoint * amount; break; case 'N': waypoint += V2.Up * amount; break; case 'S': waypoint += V2.Down * amount; break; case 'E': waypoint += V2.Right * amount; break; case 'W': waypoint += V2.Left * amount; break; case 'L': rad = -amount * Math.PI / 180; waypoint = new V2(waypoint.x * (int)Math.Cos(rad) - waypoint.y * (int)Math.Sin(rad), waypoint.x * (int)Math.Sin(rad) + waypoint.y * (int)Math.Cos(rad)); break; case 'R': rad = amount * Math.PI / 180; waypoint = new V2(waypoint.x * (int)Math.Cos(rad) - waypoint.y * (int)Math.Sin(rad), waypoint.x * (int)Math.Sin(rad) + waypoint.y * (int)Math.Cos(rad)); break; default: throw new Exception("Unhandled char" + line); } } return(Math.Abs(pos.x) + Math.Abs(pos.y)); }
int FindPath(Dictionary <V2, Node> map) { Heap <Node> open = new(map.Count); V2 target = map.Last().Value.v; open.Add(map[V2.Zero]); map[V2.Zero].totalRisk = 0; int visitCount = 0; while (open.Count > 0) { Node next = open.RemoveFirst(); next.visited = true; visitCount++; foreach (var dir in V2.Directions) { if (map.TryGetValue(next.v + dir, out Node opt)) { if (!opt.visited) { int thisRisk = next.totalRisk + opt.risk; if (thisRisk < opt.totalRisk) { opt.totalRisk = thisRisk; if (!open.Contains(opt)) { open.Add(opt); } else { open.UpdateItem(opt); } } if (opt.v == target) { return(opt.totalRisk); } } } } } return(-1); }
public override object Part2() { for (int i = 0; i < 100; i++) { List <V2> list = blackTiles.ToList(); int listLen = list.Count; for (int j = 0; j < listLen; j++) { V2 tile = list[j]; V2[] dirs = EvenTile(tile) ? evenDirs : oddDirs; foreach (V2 dir in dirs) { list.Add(tile + dir); } } HashSet <V2> newTiles = new HashSet <V2>(); HashSet <V2> toCheck = new HashSet <V2>(list); foreach (V2 tile in toCheck) { int count = 0; if (EvenTile(tile)) { count = evenDirs.Count(dir => blackTiles.Contains(tile + dir)); } else { count = oddDirs.Count(dir => blackTiles.Contains(tile + dir)); } if (blackTiles.Contains(tile) && count > 0 && count <= 2) { newTiles.Add(tile); } else if (!blackTiles.Contains(tile) && count == 2) { newTiles.Add(tile); } } blackTiles = new HashSet <V2>(newTiles); } return(blackTiles.Count); }
int FindOverlaps(bool diagonals) { Dictionary <V2, int> map = new(); Regex r = new Regex(@"(\d+)"); foreach (var line in lines) { var matches = r.Matches(line); V2 v1 = new V2(int.Parse(matches[0].Value), int.Parse(matches[1].Value)); V2 v2 = new V2(int.Parse(matches[2].Value), int.Parse(matches[3].Value)); if (diagonals || v1.x == v2.x || v1.y == v2.y) { V2 dir = new V2(Math.Sign(v2.x - v1.x), Math.Sign(v2.y - v1.y)); V2 target = v1; while (target != v2) { if (!map.ContainsKey(target)) { map.Add(target, 0); } map[target]++; target += dir; } if (!map.ContainsKey(v2)) { map.Add(v2, 0); } map[v2]++; } } return(map.Values.Count(x => x > 1)); }
int getSlope(V2 slope) { int len = lines[0].Length; var pos = new V2(0, 0); int trees = 0; while (pos.y < lines.Length) { if (map[pos]) { trees++; } pos += slope; if (pos.x >= len) { pos.x -= len; } } return(trees); }
public override object Part1() { V2 v = new V2(); for (int i = 0; i < lines.Length; i++) { string[] temp = lines[i].Split(' '); if (temp[0] == "forward") { v += V2.Right * int.Parse(temp[1]); } if (temp[0] == "up") { v += V2.Up * int.Parse(temp[1]); } if (temp[0] == "down") { v += V2.Down * int.Parse(temp[1]); } } return(v.x * v.y); }
public Node(V2 v, int risk) { this.v = v; this.risk = risk; }
public override string Part1() { var input = File.ReadAllLines("Input/24.txt").Select(line => line.ToCharArray()).ToArray(); var map = new Dictionary <V2, char>(); var newMap = new Dictionary <V2, char>(); var states = new HashSet <string>(); for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { map[new V2(x, y)] = input[y][x]; } } states.Add(GetMapString(map)); while (true) { for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { var pos = new V2(x, y); int count = 0; foreach (var dir in V2.Directions) { if (map.TryGetValue(pos + dir, out char c)) { if (c == '#') { count++; } } } newMap[pos] = (count == 1 || map[pos] == '.' && count == 2) ? '#' : '.'; } } string state = GetMapString(newMap); if (states.Contains(state)) { long value = 0; foreach (var kv in newMap) { if (kv.Value == '#') { value += (long)Math.Pow(2, kv.Key.y * 5 + kv.Key.x); } } return(value.ToString()); } else { states.Add(state); } foreach (var key in map.Keys.ToList()) { map[key] = newMap[key]; } } }
bool EvenTile(V2 tile) => tile.y % 2 == 0;
public override string Part1() { // Get map var lines = File.ReadAllLines("Input/20.txt"); for (int y = 0; y < lines.Length; y++) { var chars = lines[y].ToCharArray(); for (int x = 0; x < chars.Length; x++) { if (chars[x] == '.' || chars[x] >= 'A' && chars[x] <= 'Z') { nodes.Add(new Node() { pos = new V2(x, y), c = chars[x] }); } } } foreach (var node in nodes) { // Get list of neighbours List <Node> neighbours = new List <Node>(); foreach (var dir in V2.Directions) { Node neighbour = nodes.Find(n => n.pos == node.pos + dir); if (neighbour != null) { neighbours.Add(neighbour); } } node.neighbours = neighbours.ToArray(); // Get list of portals if (node.c >= 'A' && node.c <= 'Z') { bool start = false; char other = 'x'; V2 otherDir = V2.Zero; Node exitNode = null; foreach (var neighbour in neighbours) { if (neighbour.c == '.') { start = true; exitNode = neighbour; } else { other = neighbour.c; otherDir = neighbour.pos - node.pos; } } if (start) { node.exit = exitNode; node.name = (otherDir == V2.Up || otherDir == V2.Left) ? other.ToString() + node.c : node.c.ToString() + other; if (node.pos.x == 1 || node.pos.x == lines[0].Length - 2) { node.outSide = true; } else if (node.pos.y == 1 || node.pos.y == lines.Length - 2) { node.outSide = true; } } } } startNode = nodes.Find(n => n.name == "AA").exit; // Connect portals foreach (var node in nodes) { if (node.name != null) { Node other = nodes.Find(n => n.name == node.name && n != node); if (other != null) { node.other = other; } } } int steps = FindPath(startNode); return(steps.ToString()); }