public void Test() { for (int i = 0; i < deckSize; i++) { deck.Add(i); } var lines = InputUtils.GetDayInputLines(22); for (int i = 0; i < 10000; i++) { foreach (string line in lines) { if (line.StartsWith("deal into new", StringComparison.Ordinal)) { DealIntoNewStack(); } else if (line.StartsWith("deal with increment", StringComparison.Ordinal)) { int increment = int.Parse(line.Trim().Split(' ')[3]); DealWithIncrement(increment); } else { // cut int cutValue = int.Parse(line.Trim().Split(' ')[1]); Cut(cutValue); } } Console.WriteLine(deck[0]); } }
public Day10() { var lines = InputUtils.GetDayInputLines(10); int y = 0; foreach (var line in lines) { for (int x = 0; x < line.Length; x++) { if (line[x] == '#') { _asteroids.Add(new Point(x, y)); } } y++; } // Check each asteroid pair, calculating the angle // between them. If the angles are the same, then one // blocks view of the other. foreach (Point source in _asteroids) { HashSet <double> angles = new HashSet <double>(); foreach (Point target in _asteroids) { angles.Add(new AsteroidPair(source, target).NormalizedAngle); } if (angles.Count > _max) { _max = angles.Count; _monitoringStation = source; } } }
public int Part2() { int total = 0; var lines = InputUtils.GetDayInputLines(1).Select(p => int.Parse(p)); foreach (int line in lines) { int mass = line; while (mass >= 0) { int result = mass / 3; result -= 2; if (result > 0) { total += result; } mass = result; } } return(total); }
public int Part2() { var part2 = InputUtils.GetDayInputLines(2018, 16).Skip(3097); registers = new[] { 0, 0, 0, 0 }; foreach (var line in part2) { if (String.IsNullOrEmpty(line)) { continue; } // get function int[] inputValues = new int[4]; inputValues = line.Split(' ').Select(int.Parse).ToArray(); string funcName = finalMap[inputValues[0]]; Action <int, int, int> action = funcs.First(p => p.Method.Name == funcName); action(inputValues[1], inputValues[2], inputValues[3]); } for (int i = 0; i < 4; i++) { Console.Write(registers[i] + " "); } return(registers[0]); }
public int Part2() { var lines = InputUtils.GetDayInputLines(2018, 2); int len = lines[0].Length; foreach (var line in lines) { foreach (var inner in lines) { if (line.Equals(inner)) { // don't check itself continue; } int same = 0; for (int i = 0; i < len; i++) { if (line[i] == inner[i]) { same++; } } if (same == len - 1) { Console.WriteLine(line); Console.WriteLine(inner); } } } return(0); }
public long Part1() { var input = InputUtils.GetDayInputLines(14); Nanofactory r = new Nanofactory(input); r.RunFactory(new InputOutputChemical { Amount = 1, Chemical = "FUEL" }); return(r.OreCount); }
public int Part1() { var lines = InputUtils.GetDayInputLines(1).Select(p => int.Parse(p)); int total = 0; foreach (int line in lines) { total += (line / 3) - 2; } return(total); }
public long Part2() { var lines = InputUtils.GetDayInputLines(22); var ops = lines.Select(p => Shuffler.Parse(p, bigDeckSize)); var agg = ops.Aggregate((a, b) => a.Merge(b)); var pow = agg.Power(bigRepeat); var inv = pow.Invert(); var app = inv.Apply(2020); return(app); }
public int Part1() { var lines = InputUtils.GetDayInputLines(2018, 1); int result = 0; foreach (var line in lines) { result += int.Parse(line); } return(result); }
public Day6() { inputList = InputUtils.GetDayInputLines(6); // orbits, e.g. abc)def // def orbits abc foreach (var i in inputList) { string inner = i.Split(')')[0]; string outer = i.Split(')')[1]; nodes.Add(inner); nodes.Add(outer); orbits.Add(Tuple.Create(inner, outer)); } }
public long Part2() { var input = InputUtils.GetDayInputLines(14); // a trillion ore const long oreStorage = 1_000_000_000_000; Nanofactory r = new Nanofactory(input); long fuelCount = 0; // produce lots at a time int fuelToProduce = 1000; Dictionary <string, int> tempExtra = null; long tempOreCount = 0; while (fuelToProduce >= 1) { while (r.OreCount < oreStorage) { tempExtra = new Dictionary <string, int>(r.ExtraMaterials); tempOreCount = r.OreCount; r.RunFactory(new InputOutputChemical() { Amount = fuelToProduce, Chemical = "FUEL" }); fuelCount += fuelToProduce; } // it wasn't an exact match, scale back and rerun // the reactions to produce less fuel if (fuelToProduce >= 1) { r.ExtraMaterials = new Dictionary <string, int>(tempExtra); r.OreCount = tempOreCount; fuelCount -= fuelToProduce; fuelToProduce /= 10; } } return(fuelCount); }
public Day6() { var lines = InputUtils.GetDayInputLines(2018, 6); //var lines = File.ReadAllLines("/Users/jjacoby/testing/advent2018/day6test.txt"); foreach (var line in lines) { Point p = new Point( int.Parse(line.Split(',')[0].Trim()), int.Parse(line.Split(',')[1].Trim())); points.Add(p); } minX = points.Min(p => p.X); maxX = points.Max(p => p.X); minY = points.Min(p => p.Y); maxY = points.Max(p => p.Y); }
public Day3() { var lines = InputUtils.GetDayInputLines(2018, 3); string pattern = @"#(\d+)\s@\s(\d+),(\d+):\s(\d+)x(\d+)"; Regex r = new Regex(pattern); foreach (var line in lines) { Claim claim = new Claim(); var match = r.Match(line); claim.ClaimId = int.Parse(match.Groups[1].Value); claim.UpperLeft = new Point(int.Parse(match.Groups[2].Value), int.Parse(match.Groups[3].Value)); claim.Width = int.Parse(match.Groups[4].Value); claim.Height = int.Parse(match.Groups[5].Value); claims.Add(claim); } }
public int Part2() { var lines = InputUtils.GetDayInputLines(2018, 1); int result = 0; HashSet <int> frequencies = new HashSet <int>(); while (true) { foreach (var line in lines) { result += int.Parse(line); if (frequencies.Contains(result)) { return(result); } frequencies.Add(result); } } }
public int Part1() { for (int i = 0; i < deckSize; i++) { deck.Add(i); } var lines = InputUtils.GetDayInputLines(22); foreach (string line in lines) { if (line.StartsWith("deal into new", StringComparison.Ordinal)) { DealIntoNewStack(); } else if (line.StartsWith("deal with increment", StringComparison.Ordinal)) { int increment = int.Parse(line.Trim().Split(' ')[3]); DealWithIncrement(increment); } else { // cut int cutValue = int.Parse(line.Trim().Split(' ')[1]); Cut(cutValue); } } for (int i = 0; i < deckSize; i++) { if (deck[i] == 2019) { return(i); } } return(0); }
public int Part1() { var lines = InputUtils.GetDayInputLines(2018, 10); Regex r = new Regex(@"position=<\s?(.+),\s?(.+)> velocity=<\s?(.+),\s?(.+)>"); List <Star> stars = new List <Star>(); foreach (var line in lines) { var m = r.Match(line); Star star = new Star(); star.Position = new Point(int.Parse(m.Groups[1].Value.Trim()), int.Parse(m.Groups[2].Value.Trim())); star.VelocityX = int.Parse(m.Groups[3].Value.Trim()); star.VelocityY = int.Parse(m.Groups[4].Value.Trim()); stars.Add(star); } int time = 0; while (time < 1000000) { DrawStars(stars); // apply velocity foreach (var star in stars) { star.Position.X += star.VelocityX; star.Position.Y += star.VelocityY; } time++; } return(0); }
public int Part1() { var lines = InputUtils.GetDayInputLines(2018, 17); Point spring = new Point(500, 0); List <Point> clayPoints = new List <Point>(); foreach (var line in lines) { // e.g. vertical line // x=484, y=1286..1289 // or horizontal line // y=289, x=475..560 bool vertical = line.StartsWith("x="); int firstValue = int.Parse(line.Split('=')[1].Split(',')[0]); int min = int.Parse(line.Split('=')[2].Split("..")[0]); int max = int.Parse(line.Split('=')[2].Split("..")[1]); for (int i = min; i <= max; i++) { if (vertical) { clayPoints.Add(new Point(firstValue, i)); } else { clayPoints.Add(new Point(i, firstValue)); } } } Draw(clayPoints.ToHashSet()); return(0); }
public int Part1() { var lines = InputUtils.GetDayInputLines(2018, 2); int exactlyTwo = 0; int exactlyThree = 0; foreach (var line in lines) { bool found2 = false; bool found3 = false; var chars = line.ToCharArray(); for (int i = 0; i < chars.Length; i++) { if (chars.Count(p => p.Equals(chars[i])) == 2) { if (!found2) { exactlyTwo++; found2 = true; } } if (chars.Count(p => p.Equals(chars[i])) == 3) { if (!found3) { found3 = true; exactlyThree++; } } } } return(exactlyThree * exactlyTwo); }
public long Part1() { var lines = InputUtils.GetDayInputLines(2018, 12); // line 0 is initial state string initialState = lines[0].Split(':')[1].Trim(); int initialLength = initialState.Length; List <(string input, string output)> rules = new List <(string input, string output)>(); for (int i = 2; i < lines.Count; i++) { rules.Add((lines[i].Split("=>")[0].Trim(), lines[i].Split("=>")[1].Trim())); } long generation = 0; Dictionary <int, bool> plants = new Dictionary <int, bool>(); for (int i = -25; i < initialLength + 25; i++) { plants.Add(i, false); } for (int i = 0; i < initialLength; i++) { plants[i] = initialState[i] == '#'; } while (generation < 20) { // apply rules Dictionary <int, bool> temp = new Dictionary <int, bool>(); // check each location against the pattern // should location i have a plant for (int i = -25; i < initialLength + 1000; i++) { StringBuilder sb = new StringBuilder(); for (int j = i - 2; j <= i + 2; j++) { if (plants.ContainsKey(j) && plants[j]) { sb.Append("#"); } else { sb.Append("."); } } if (rules.First(p => p.input.Equals(sb.ToString(), StringComparison.OrdinalIgnoreCase)).output == "#") { temp.Add(i, true); } else { temp.Add(i, false); } } plants = new Dictionary <int, bool>(temp); generation++; } long sum = 0; foreach (var plant in plants) { if (plant.Value) { sum += plant.Key; } } return(sum); }
public Day7() { lines = InputUtils.GetDayInputLines(2018, 7); }
public int Part1() { var lines = InputUtils.GetDayInputLines(2018, 13); // go through each line, finding '/' character for top left. // create a track based on that location // if we find a cart, add it to carts List <Track> tracks = new List <Track>(); List <Cart> carts = new List <Cart>(); int cartId = 0; for (int line = 0; line < lines.Count; line++) { for (int i = 0; i < lines[line].Length; i++) { // if it's a cart if (lines[line][i] == '<' || lines[line][i] == '>' || lines[line][i] == '^' || lines[line][i] == 'v') { Cart cart = new Cart(); cart.Location = new Point(i, line); switch (lines[line][i]) { case '>': cart.Direction = Direction.East; break; case '<': cart.Direction = Direction.West; break; case '^': cart.Direction = Direction.North; break; case 'v': cart.Direction = Direction.South; break; } cart.CartId = cartId++; carts.Add(cart); } else if (lines[line][i] == '/' && i != lines[line].Length - 1 && (lines[line][i + 1] == '-' || lines[line][i + 1] == '+')) { // top left of a track Track track = new Track(); track.TopLeft = new Point(i, line); bool foundTrack = true; // find the top right by travelling right for (int j = i + 2; j < lines[line].Length; j++) { if (lines[line][j] == ' ' || lines[line][j] == '|') { // not a line foundTrack = false; break; } if (lines[line][j] == '\\') { track.TopRight = new Point(j, line); break; } } if (track.TopRight == null) { foundTrack = false; } // find the bottom left by travelling down for (int j = line; j < lines.Count; j++) { if (lines[j][i] == '\\') { track.BottomLeft = new Point(i, j); break; } } if (track.BottomLeft == null) { foundTrack = false; } // find bottom right by travelling right from bottom left for (int j = i; j < lines[line].Length; j++) { if (foundTrack) { if (lines[track.BottomLeft.Y][j] == '/') { track.BottomRight = new Point(j, track.BottomLeft.Y); break; } } else { foundTrack = false; } } if (track.BottomRight == null) { foundTrack = false; } if (foundTrack) { tracks.Add(track); } } } } int tick = 0; bool firstCrash = true; while (true) { foreach (var cart in carts.OrderBy(p => p.Location.Y).ThenBy(p => p.Location.X)) { if (cart.IsDead) { continue; } // move cart! // move the cart one space if (cart.Direction == Direction.East) { cart.Location.X++; } else if (cart.Direction == Direction.West) { cart.Location.X--; } else if (cart.Direction == Direction.South) { cart.Location.Y++; } else if (cart.Direction == Direction.North) { cart.Location.Y--; } // if the cart is now on a corner, change its direction // to go around the corner var corner = tracks.FirstOrDefault(p => p.TopLeft.Equals(cart.Location) || p.TopRight.Equals(cart.Location) || p.BottomLeft.Equals(cart.Location) || p.BottomRight.Equals(cart.Location)); if (corner != null) { if (corner.TopLeft.Equals(cart.Location)) { // up -> right // left -> down if (cart.Direction == Direction.North) { cart.Direction = Direction.East; } if (cart.Direction == Direction.West) { cart.Direction = Direction.South; } } if (corner.TopRight.Equals(cart.Location)) { // up -> left // right -> down if (cart.Direction == Direction.North) { cart.Direction = Direction.West; } if (cart.Direction == Direction.East) { cart.Direction = Direction.South; } } if (corner.BottomLeft.Equals(cart.Location)) { // down -> right // left -> up if (cart.Direction == Direction.South) { cart.Direction = Direction.East; } if (cart.Direction == Direction.West) { cart.Direction = Direction.North; } } if (corner.BottomRight.Equals(cart.Location)) { // down -> left // right -> up if (cart.Direction == Direction.South) { cart.Direction = Direction.West; } if (cart.Direction == Direction.East) { cart.Direction = Direction.North; } } } // if the cart is at a crossing, turn it based on the tick // crossing == the cart is on two tracks, one vertical and // one horizontal. // each track is defined by its horizontal lines (TopLeft -> TopRight) // and (BottomLeft -> BottomRight) and its vertical lines // (TopLeft --> BottomLeft) and (TopRight --> BottomRight) // Each time a cart has the option to turn (by arriving at // any intersection), it turns left the first time, goes straight // the second time, turns right the third time, and then // repeats those directions starting again with left the // fourth time, straight the fifth time, and so on. // This process is independent of the particular intersection at // which the cart has arrived - that is, the cart has no per-intersection memory. if (tracks.Count(p => p.PointOnTopLine(cart.Location) || p.PointOnBottomLine(cart.Location) || p.PointOnLeftLine(cart.Location) || p.PointOnRightLine(cart.Location)) == 2) { if (cart.TurnCount % 3 == 0) { // turn left if (cart.Direction == Direction.West) { cart.Direction = Direction.South; } else if (cart.Direction == Direction.East) { cart.Direction = Direction.North; } else if (cart.Direction == Direction.North) { cart.Direction = Direction.West; } else if (cart.Direction == Direction.South) { cart.Direction = Direction.East; } } if (cart.TurnCount % 3 == 2) { // turn right if (cart.Direction == Direction.West) { cart.Direction = Direction.North; } else if (cart.Direction == Direction.East) { cart.Direction = Direction.South; } else if (cart.Direction == Direction.North) { cart.Direction = Direction.East; } else if (cart.Direction == Direction.South) { cart.Direction = Direction.West; } } cart.TurnCount++; } // check for crashes foreach (var c in carts.Where(p => !p.IsDead).Except(new[] { cart })) { if (cart.Location.Equals(c.Location)) { //crash! // part 1 - return first crash if (firstCrash) { Console.WriteLine("First crash: {0}", cart.Location); firstCrash = false; } // part 2 - find last cart standing c.IsDead = true; cart.IsDead = true; } } } if (carts.Count(p => !p.IsDead) == 1) { Console.WriteLine("Final cart location: {0}", carts.First(p => !p.IsDead).Location); return(0); } tick++; } }
public int Simulate(bool allowElfDeaths = true) { int roundsCompleted = 1; // false == wall // true == available bool[,] board = new bool[gridSize, gridSize]; List <Unit> units = new List <Unit>(); string[] lines = InputUtils.GetDayInputLines(2018, 15).ToArray(); //string[] lines = File.ReadAllLines("/Users/jjacoby/testing/advent2018/day15test.txt"); int rowIndex = 0; int columnIndex = 0; foreach (var line in lines) { columnIndex = 0; foreach (var c in line) { if (c == '#') { board[columnIndex, rowIndex] = false; } else if (c == '.') { board[columnIndex, rowIndex] = true; } else { board[columnIndex, rowIndex] = true; Unit u = new Unit(); u.UnitType = (c == 'G' ? UnitType.Goblin : UnitType.Elf); u.Location = new Point(columnIndex, rowIndex); units.Add(u); } columnIndex++; } rowIndex++; } //Console.WriteLine(DrawBoard(board, units)); while (true) { // units take turns in reading order var orderedUnits = units.OrderBy(p => p.Location.Y).ThenBy(p => p.Location.X).ToList(); foreach (var unit in orderedUnits) { if (!allowElfDeaths) { if (unit.HitPoints <= 0 && unit.UnitType == UnitType.Elf) { Console.WriteLine("part 2 failed - elf died"); return(-1); } } if (unit.HitPoints <= 0) { continue; } if (units.Count(p => p.UnitType == UnitType.Elf && p.HitPoints > 0) == 0 || units.Count(p => p.UnitType == UnitType.Goblin && p.HitPoints > 0) == 0) { //Console.WriteLine("End:"); //Console.WriteLine(DrawBoard(board, units)); //Console.WriteLine("Round {0}: no targets remaining", roundsCompleted); int totalHitPoints = units.Where(p => p.HitPoints > 0).Sum(p => p.HitPoints); //Console.WriteLine("Total hit points = {0}", totalHitPoints); //Console.WriteLine("Round * points = {0}", roundsCompleted * totalHitPoints); //Console.WriteLine("Round - 1 * points = {0}", (roundsCompleted - 1) * totalHitPoints); return((roundsCompleted - 1) * totalHitPoints); } bool didAttack = false; // first - can i attack? // find targets in range var targets = units.Where(p => p.UnitType != unit.UnitType && p.HitPoints > 0 && ((p.Location.X == unit.Location.X && Math.Abs(p.Location.Y - unit.Location.Y) == 1) || (p.Location.Y == unit.Location.Y && Math.Abs(p.Location.X - unit.Location.X) == 1))) .OrderBy(p => p.HitPoints) .ThenBy(p => p.Location.Y) .ThenBy(p => p.Location.X); if (targets.Any()) { var target = targets.First(); target.HitPoints -= unit.AttackPower; didAttack = true; } if (!didAttack) { // otherwise, move // find possible locations to move // open spots next to enemies List <Point> openSpots = new List <Point>(); for (int y = 0; y < gridSize; y++) { for (int x = 0; x < gridSize; x++) { if (board[x, y]) { // not a wall // is it next to an enemy? if (units.Any(p => p.HitPoints > 0 && p.UnitType != unit.UnitType && ((p.Location.X == x && Math.Abs(p.Location.Y - y) == 1) || (p.Location.Y == y && Math.Abs(p.Location.X - x) == 1)))) { // is there already a unit there? if (!units.Any(p => p.HitPoints > 0 && p.Location.X == x && p.Location.Y == y)) { openSpots.Add(new Point(x, y)); } } } } } // find open spots that have a clear path Dictionary <Point, int> spotDistances = new Dictionary <Point, int>(); foreach (var spot in openSpots) { // is there a path from unit.Location to spot? var distance = GetDistance(board, units, unit.Location, spot); if (distance >= 0) { spotDistances.Add(spot, distance); } } // closest spot if (!spotDistances.Any()) { // can't move continue; } var chosenSpot = spotDistances.OrderBy(p => p.Value) .ThenBy(p => p.Key.Y) .ThenBy(p => p.Key.X) .First().Key; int nextX = unit.Location.X; int nextY = unit.Location.Y; // see which adjacent spot has the shortest distance int minDistance = int.MaxValue; // x,y-1 if (board[unit.Location.X, unit.Location.Y - 1] && !units.Any(p => p.HitPoints > 0 && p.Location.X == unit.Location.X && p.Location.Y == unit.Location.Y - 1)) { int distanceFrom = GetDistance(board, units, new Point(unit.Location.X, unit.Location.Y - 1), chosenSpot); if (distanceFrom >= 0 && (distanceFrom < minDistance)) { minDistance = distanceFrom; nextX = unit.Location.X; nextY = unit.Location.Y - 1; } } // x-1,y if (board[unit.Location.X - 1, unit.Location.Y] && !units.Any(p => p.HitPoints > 0 && p.Location.X == unit.Location.X - 1 && p.Location.Y == unit.Location.Y)) { int distanceFrom = GetDistance(board, units, new Point(unit.Location.X - 1, unit.Location.Y), chosenSpot); if (distanceFrom >= 0 && (distanceFrom < minDistance)) { minDistance = distanceFrom; nextX = unit.Location.X - 1; nextY = unit.Location.Y; } } // x+1,y if (board[unit.Location.X + 1, unit.Location.Y] && !units.Any(p => p.HitPoints > 0 && p.Location.X == unit.Location.X + 1 && p.Location.Y == unit.Location.Y)) { int distanceFrom = GetDistance(board, units, new Point(unit.Location.X + 1, unit.Location.Y), chosenSpot); if (distanceFrom >= 0 && (distanceFrom < minDistance)) { minDistance = distanceFrom; nextX = unit.Location.X + 1; nextY = unit.Location.Y; } } // x,y+1 if (board[unit.Location.X, unit.Location.Y + 1] && !units.Any(p => p.HitPoints > 0 && p.Location.X == unit.Location.X && p.Location.Y == unit.Location.Y + 1)) { int distanceFrom = GetDistance(board, units, new Point(unit.Location.X, unit.Location.Y + 1), chosenSpot); if (distanceFrom >= 0 && (distanceFrom < minDistance)) { minDistance = distanceFrom; nextX = unit.Location.X; nextY = unit.Location.Y + 1; } } unit.Location.X = nextX; unit.Location.Y = nextY; // now, can i attack again? var newTargets = units.Where(p => p.UnitType != unit.UnitType && p.HitPoints > 0 && ((p.Location.X == unit.Location.X && Math.Abs(p.Location.Y - unit.Location.Y) == 1) || (p.Location.Y == unit.Location.Y && Math.Abs(p.Location.X - unit.Location.X) == 1))) .OrderBy(p => p.HitPoints) .ThenBy(p => p.Location.Y) .ThenBy(p => p.Location.X); if (newTargets.Any()) { var target = newTargets.First(); target.HitPoints -= unit.AttackPower; } } } //Console.WriteLine(roundsCompleted); //Console.WriteLine(DrawBoard(board, units)); roundsCompleted++; } //return 0; }
public Day3() { var input = InputUtils.GetDayInputLines(3); string wire1 = input[0]; string wire2 = input[1]; char[,] grid = new char[50000, 50000]; grid[20000, 20000] = 'o'; // port List <string> w1list = wire1.Split(',').ToList(); List <string> w2list = wire2.Split(',').ToList(); Dictionary <Point, int> xDistance = new Dictionary <Point, int>(); int currentX = 20000; int currentY = 20000; int wire1Length = 0; foreach (string w in w1list) { int newX = currentX; int newY = currentY; char direction = w[0]; int length = int.Parse(w.Substring(1)); switch (direction) { case 'U': newY = currentY + length; for (int y = currentY + 1; y <= newY; y++) { //Console.WriteLine("{0}, {1}", currentX, y); grid[currentX, y] = '1'; Point p = new Point(currentX, y); if (!xDistance.ContainsKey(p)) { xDistance.Add(p, wire1Length + y - currentY); } } break; case 'D': newY = currentY - length; for (int y = currentY - 1; y >= newY; y--) { //Console.WriteLine("{0}, {1}", currentX, y); grid[currentX, y] = '1'; Point p = new Point(currentX, y); if (!xDistance.ContainsKey(p)) { xDistance.Add(p, wire1Length + currentY - y); } } break; case 'L': newX = currentX - length; for (int x = currentX - 1; x >= newX; x--) { //Console.WriteLine("{0}, {1}", x, currentY); grid[x, currentY] = '1'; Point p = new Point(x, currentY); if (!xDistance.ContainsKey(p)) { xDistance.Add(p, wire1Length + currentX - x); } } break; case 'R': newX = currentX + length; for (int x = currentX + 1; x <= newX; x++) { //Console.WriteLine("{0}, {1}", x, currentY); grid[x, currentY] = '1'; Point p = new Point(x, currentY); if (!xDistance.ContainsKey(p)) { xDistance.Add(p, wire1Length + x - currentX); } } break; default: break; } wire1Length += length; currentX = newX; currentY = newY; } currentX = 20000; currentY = 20000; int wire2Length = 0; foreach (string w in w2list) { int newX = currentX; int newY = currentY; char direction = w[0]; int length = int.Parse(w.Substring(1)); switch (direction) { case 'U': newY = currentY + length; for (int y = currentY + 1; y <= newY; y++) { if (grid[currentX, y] == '1') { grid[currentX, y] = 'X'; int distance = Point.CalculateManhattanDistance(new Point(currentX, y), new Point(20000, 20000)); distances.Add(distance); if (xDistance.ContainsKey(new Point(currentX, y))) { wireLengths.Add(wire2Length + y - currentY + xDistance[new Point(currentX, y)]); } } else { grid[currentX, y] = '2'; } } break; case 'D': newY = currentY - length; for (int y = currentY - 1; y >= newY; y--) { if (grid[currentX, y] == '1') { grid[currentX, y] = 'X'; int distance = Point.CalculateManhattanDistance(new Point(currentX, y), new Point(20000, 20000)); distances.Add(distance); if (xDistance.ContainsKey(new Point(currentX, y))) { wireLengths.Add(wire2Length + currentY - y + xDistance[new Point(currentX, y)]); } } else { grid[currentX, y] = '2'; } } break; case 'L': newX = currentX - length; for (int x = currentX - 1; x >= newX; x--) { if (grid[x, currentY] == '1') { grid[x, currentY] = 'X'; int distance = Point.CalculateManhattanDistance(new Point(x, currentY), new Point(20000, 20000)); distances.Add(distance); if (xDistance.ContainsKey(new Point(x, currentY))) { wireLengths.Add(wire2Length + currentX - x + xDistance[new Point(x, currentY)]); } } else { grid[x, currentY] = '2'; } } break; case 'R': newX = currentX + length; for (int x = currentX + 1; x <= newX; x++) { if (grid[x, currentY] == '1') { int distance = Point.CalculateManhattanDistance(new Point(x, currentY), new Point(20000, 20000)); distances.Add(distance); if (xDistance.ContainsKey(new Point(x, currentY))) { wireLengths.Add(wire2Length + x - currentX + xDistance[new Point(x, currentY)]); } grid[x, currentY] = 'X'; } else { grid[x, currentY] = '2'; } } break; default: break; } wire2Length += length; currentX = newX; currentY = newY; } }
public Day4() { var lines = InputUtils.GetDayInputLines(2018, 4); List <GuardEvent> events = new List <GuardEvent>(); Regex r = new Regex(@"\[(.+)\](.+)"); foreach (var line in lines) { var match = r.Match(line); GuardEvent ge = new GuardEvent(); ge.EventTime = DateTime.Parse(match.Groups[1].Value); string actionString = match.Groups[2].Value; if (actionString.Contains("begins")) { // e.g. // Guard #1783 begins shift ge.Action = GuardAction.StartShift; ge.GuardId = int.Parse(actionString.Split('#')[1].Substring(0, 4).Trim()); } else if (actionString.Contains("wakes")) { ge.Action = GuardAction.WakeUp; } else if (actionString.Contains("falls")) { ge.Action = GuardAction.FallAsleep; } events.Add(ge); } var orderedEvents = events.OrderBy(p => p.EventTime); int lastGuardId = 0; foreach (var oe in orderedEvents) { if (oe.GuardId == 0) { oe.GuardId = lastGuardId; } else { lastGuardId = oe.GuardId; } } // find the guard that has the most minutes // asleep, and what minute he spends asleep the most often // check each pair of events // shift start -> sleep: add awake minutes // sleep -> wake: add sleep minutes // wake -> sleep: add awake minutes // wake up -> shift start: add awake minutes // sleep -> shift start: add sleep minutes var eventsList = orderedEvents.ToList(); for (int i = 0; i < eventsList.Count - 1; i++) { if (!guardStatuses.ContainsKey(eventsList[i].GuardId)) { guardStatuses.Add(eventsList[i].GuardId, new Dictionary <int, int>()); } var e = eventsList[i]; var eNext = eventsList[i + 1]; if (e.Action == GuardAction.FallAsleep) { for (int m = e.EventTime.Minute; m < eNext.EventTime.Minute; m++) { if (guardStatuses[e.GuardId].ContainsKey(m)) { guardStatuses[e.GuardId][m]++; } else { guardStatuses[e.GuardId].Add(m, 1); } } } } }
public Day16() { registers = new int[4]; // read input var lines = InputUtils.GetDayInputLines(2018, 16); List <Operation> operations = new List <Operation>(); for (int i = 0; i < lines.Count; i += 4) { var set = lines.Skip(i).Take(4).ToList(); if (!set[0].StartsWith("Before")) { break; } Operation o = new Operation(); int[] beforeRegs = new int[4]; int[] inputInstructions = new int[4]; int[] afterRegs = new int[4]; o.BeforeRegisters = set[0].Substring(9, 10).Split(',').Select(int.Parse).ToArray(); o.InputInstructions = set[1].Split(' ').Select(int.Parse).ToArray(); o.AfterRegisters = set[2].Substring(9, 10).Split(',').Select(int.Parse).ToArray(); operations.Add(o); } funcs.Add(addr); funcs.Add(addi); funcs.Add(mulr); funcs.Add(muli); funcs.Add(banr); funcs.Add(bani); funcs.Add(borr); funcs.Add(bori); funcs.Add(setr); funcs.Add(seti); funcs.Add(gtir); funcs.Add(gtri); funcs.Add(gtrr); funcs.Add(eqir); funcs.Add(eqri); funcs.Add(eqrr); Dictionary <int, HashSet <string> > possibleMap = new Dictionary <int, HashSet <string> >(); for (int i = 0; i < 16; i++) { possibleMap.Add(i, new HashSet <string>()); } foreach (var op in operations) { int count = 0; foreach (var f in funcs) { for (int i = 0; i < 4; i++) { registers[i] = op.BeforeRegisters[i]; } f(op.InputInstructions[1], op.InputInstructions[2], op.InputInstructions[3]); if (registers.SequenceEqual(op.AfterRegisters)) { count++; // possible match possibleMap[op.InputInstructions[0]].Add(f.Method.Name); } } if (count >= 3) { behavesLikeThreeOrMore++; } } while (finalMap.Count < 16) { foreach (var kvp in possibleMap) { if (!finalMap.ContainsKey(kvp.Key)) { if (kvp.Value.Count == 1) { // add to final string str = kvp.Value.First(); finalMap.Add(kvp.Key, str); foreach (var k2 in possibleMap) { k2.Value.Remove(str); } } } } } }
public Day20() { var lines = InputUtils.GetDayInputLines(20); // hard-coded rows that the portals are on // in my input ¯\_(ツ)_/¯ for (int i = 0; i < lines[2].Length; i++) { if (lines[2][i] == '.') { // portal Portal p = new Portal(); p.Name = lines[0][i].ToString() + lines[1][i].ToString(); p.Location = new Point(i, 1); p.OutputLocation = new Point(i, 2); portals.Add(p); } } int y = 26; for (int i = 0; i < lines[y].Length; i++) { if (lines[y][i] == '.' && char.IsLetter(lines[y + 1][i])) { // portal Portal p = new Portal(); p.Name = lines[y + 1][i].ToString() + lines[y + 2][i].ToString(); p.Location = new Point(i, y + 1); p.OutputLocation = new Point(i, y); portals.Add(p); } } y = 80; for (int i = 0; i < lines[y].Length; i++) { if (lines[y][i] == '.' && char.IsLetter(lines[y - 1][i])) { // portal Portal p = new Portal(); p.Name = lines[y - 2][i].ToString() + lines[y - 1][i].ToString(); p.Location = new Point(i, y - 1); p.OutputLocation = new Point(i, y); portals.Add(p); } } y = 104; for (int i = 0; i < lines[y].Length; i++) { if (lines[y][i] == '.' && char.IsLetter(lines[y + 1][i])) { // portal Portal p = new Portal(); p.Name = lines[y + 1][i].ToString() + lines[y + 2][i].ToString(); p.Location = new Point(i, y + 1); p.OutputLocation = new Point(i, y); portals.Add(p); } } for (int i = 0; i < lines.Count; i++) { if (char.IsLetter(lines[i][0])) { Portal p = new Portal(); p.Name = lines[i][0].ToString() + lines[i][1].ToString(); p.Location = new Point(1, i); p.OutputLocation = new Point(2, i); portals.Add(p); } int len = lines[i].Length; if (char.IsLetter(lines[i][len - 1])) { Portal p = new Portal(); p.Name = lines[i][len - 2].ToString() + lines[i][len - 1].ToString(); p.Location = new Point(len - 2, i); p.OutputLocation = new Point(len - 3, i); portals.Add(p); } len = 29; if (char.IsLetter(lines[i][len - 1])) { Portal p = new Portal(); p.Name = lines[i][len - 2].ToString() + lines[i][len - 1].ToString(); p.Location = new Point(len - 2, i); p.OutputLocation = new Point(len - 3, i); portals.Add(p); } int s = 78; if (char.IsLetter(lines[i][s])) { Portal p = new Portal(); p.Name = lines[i][s].ToString() + lines[i][s + 1].ToString(); p.Location = new Point(s + 1, i); p.OutputLocation = new Point(s + 2, i); portals.Add(p); } } for (int yy = 0; yy < lines.Count; yy++) { for (int x = 0; x < lines[yy].Length; x++) { Point p = new Point(x, yy); grid[p] = lines[yy][x]; } } }
public int Part2() { var lines = InputUtils.GetDayInputLines(24); Dictionary <Point, char> originalGrid = new Dictionary <Point, char>(); Dictionary <int, Dictionary <Point, char> > tempLevels = new Dictionary <int, Dictionary <Point, char> >(); for (int y = 0; y < lines.Count; y++) { for (int x = 0; x < lines[y].Length; x++) { originalGrid[new Point(x, y)] = lines[y][x]; } } levels.Add(0, originalGrid); for (int i = 1; i < 500; i++) { Dictionary <Point, char> level = new Dictionary <Point, char>(); for (int y = 0; y < lines.Count; y++) { for (int x = 0; x < lines[y].Length; x++) { level[new Point(x, y)] = '.'; } } levels.Add(i, level); } for (int i = -1; i > -500; i--) { Dictionary <Point, char> level = new Dictionary <Point, char>(); for (int y = 0; y < lines.Count; y++) { for (int x = 0; x < lines[y].Length; x++) { level[new Point(x, y)] = '.'; } } levels.Add(i, level); } int minute = 0; tempLevels = new Dictionary <int, Dictionary <Point, char> >(levels); while (true) { for (int levelIndex = -498; levelIndex < 499; levelIndex++) { Dictionary <Point, char> grid = levels[levelIndex]; Dictionary <Point, char> tempGrid = new Dictionary <Point, char>(); for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { Point p = new Point(x, y); List <char> neighbors = new List <char>(); // if a point is on the edge, get from the next level if (x == 0) { // left // higher level location 1,2 neighbors.Add(levels[levelIndex + 1][new Point(1, 2)]); } if (y == 0) { // top neighbors.Add(levels[levelIndex + 1][new Point(2, 1)]); } if (x == 4) { // right neighbors.Add(levels[levelIndex + 1][new Point(3, 2)]); } if (y == 4) { // bottom neighbors.Add(levels[levelIndex + 1][new Point(2, 3)]); } // inner neighbours if (x == 2 && y == 1) { // add the top row of the next level for (int xx = 0; xx < 5; xx++) { neighbors.Add(levels[levelIndex - 1][new Point(xx, 0)]); } } if (x == 2 && y == 3) { // add the bottom row of the next level for (int xx = 0; xx < 5; xx++) { neighbors.Add(levels[levelIndex - 1][new Point(xx, 4)]); } } if (x == 1 && y == 2) { // add the left column of the next level for (int yy = 0; yy < 5; yy++) { neighbors.Add(levels[levelIndex - 1][new Point(0, yy)]); } } if (x == 3 && y == 2) { // add the right column of the next level for (int yy = 0; yy < 5; yy++) { neighbors.Add(levels[levelIndex - 1][new Point(4, yy)]); } } // regular points Point left = new Point(x - 1, y); Point right = new Point(x + 1, y); Point up = new Point(x, y - 1); Point down = new Point(x, y + 1); int isLeft = grid.ContainsKey(left) && grid[left] == '#' ? 1 : 0; int isRight = grid.ContainsKey(right) && grid[right] == '#' ? 1 : 0; int isUp = grid.ContainsKey(up) && grid[up] == '#' ? 1 : 0; int isDown = grid.ContainsKey(down) && grid[down] == '#' ? 1 : 0; int bugCount = neighbors.Count(p => p == '#'); if (x == 2 && y == 2) { // nothing } else { bugCount += isLeft + isRight + isUp + isDown; } char c = grid[p]; // if it's a bug if (c == '#') { // A bug dies (becoming an empty space) unless there is exactly one bug adjacent to it. if (bugCount == 1) { tempGrid[p] = '#'; } else { tempGrid[p] = '.'; } } else { // An empty space becomes infested with a bug if exactly one or two bugs are adjacent to it. if ((bugCount == 1) || (bugCount == 2)) { tempGrid[p] = '#'; } else { tempGrid[p] = '.'; } } } } tempLevels[levelIndex] = tempGrid; } levels = new Dictionary <int, Dictionary <Point, char> >(tempLevels); minute++; if (minute == 200) { // count bugs int cnt = 0; foreach (var l in levels) { for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { if (l.Value[new Point(x, y)] == '#') { cnt++; } } } } return(cnt); } } }
public int Part1() { var lines = InputUtils.GetDayInputLines(24); Dictionary <Point, char> grid = new Dictionary <Point, char>(); for (int y = 0; y < lines.Count; y++) { for (int x = 0; x < lines[y].Length; x++) { grid[new Point(x, y)] = lines[y][x]; } } HashSet <int> diversityRatings = new HashSet <int>(); int originalRating = CalculateRating(grid); diversityRatings.Add(originalRating); int minute = 0; while (true) { Dictionary <Point, char> tempGrid = new Dictionary <Point, char>(); for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { Point p = new Point(x, y); Point left = new Point(x - 1, y); Point right = new Point(x + 1, y); Point up = new Point(x, y - 1); Point down = new Point(x, y + 1); int isLeft = grid.ContainsKey(left) && grid[left] == '#' ? 1 : 0; int isRight = grid.ContainsKey(right) && grid[right] == '#' ? 1 : 0; int isUp = grid.ContainsKey(up) && grid[up] == '#' ? 1 : 0; int isDown = grid.ContainsKey(down) && grid[down] == '#' ? 1 : 0; int bugCount = isLeft + isRight + isUp + isDown; char c = grid[p]; // if it's a bug if (c == '#') { // A bug dies (becoming an empty space) unless there is exactly one bug adjacent to it. if (bugCount == 1) { tempGrid[p] = '#'; } else { tempGrid[p] = '.'; } } else { // An empty space becomes infested with a bug if exactly one or two bugs are adjacent to it. if ((bugCount == 1) || (bugCount == 2)) { tempGrid[p] = '#'; } else { tempGrid[p] = '.'; } } } } int rating = CalculateRating(tempGrid); if (diversityRatings.Contains(rating)) { return(rating); } diversityRatings.Add(rating); grid = new Dictionary <Point, char>(tempGrid); minute++; } }