using System; using static System.Console; using System.Collections.Generic; using System.IO; using System.Linq; using Xunit; namespace AdventOfCode { public class Program { static string RootDir = Environment.GetEnvironmentVariable("HOME") + "/src/adventofcode/2020/"; static List ReadInts(string filename) { string[] lines = File.ReadAllLines(filename); return lines.Select(int.Parse).ToList(); } static int Day1Part1(List numbers) { for (var i = 0; i < numbers.Count; i++) { for (var j = i + 1; j < numbers.Count; j++) { if (numbers[i] + numbers[j] == 2020) { return numbers[i] * numbers[j]; } } } throw new ArgumentException("no pair of numbers summed to 2020"); } static int Day1Part2(List numbers) { for (var i = 0; i < numbers.Count; i++) { for (var j = i + 1; j < numbers.Count; j++) { for (var k = j + 1; k < numbers.Count; k++) { if (numbers[i] + numbers[j] + numbers[k] == 2020) { return numbers[i] * numbers[j] * numbers[k]; } } } } throw new ArgumentException("no triple of numbers summed to 2020"); } [Fact] static void Day1Test() { var emptyInput = new List(); var bogusInput = new List() { 111, 222, 333, 444, 555, 666, 777, 888, 999 }; var exampleInput = new List() { 1721, 979, 366, 299, 675, 1456 }; var testInput = ReadInts(RootDir + "day1.txt"); Assert.Throws(() => Day1Part1(emptyInput)); Assert.Throws(() => Day1Part1(bogusInput)); Assert.Equal(514579, Day1Part1(exampleInput)); Assert.Equal(355875, Day1Part1(testInput)); Assert.Throws(() => Day1Part2(emptyInput)); Assert.Throws(() => Day1Part2(bogusInput)); Assert.Equal(241861950, Day1Part2(exampleInput)); Assert.Equal(140379120, Day1Part2(testInput)); } static bool IsPasswordValid1(string spec) { string[] tokens = spec.Split(' '); string[] numbers = tokens[0].Split('-'); int min = int.Parse(numbers[0]); int max = int.Parse(numbers[1]); char required = tokens[1][0]; string password = tokens[2]; int count = 0; for (int i = 0; i < password.Length; i++) { if (password[i] == required) { count++; } } return min <= count && count <= max; } static bool IsPasswordValid2(string spec) { string[] tokens = spec.Split(' '); string[] numbers = tokens[0].Split('-'); int lowIndex = int.Parse(numbers[0]) - 1; int highIndex = int.Parse(numbers[1]) - 1; char required = tokens[1][0]; string password = tokens[2]; return (password[lowIndex] == required && password[highIndex] != required) || (password[lowIndex] != required && password[highIndex] == required); } static int Day2Part1() { return File.ReadAllLines(RootDir + "day02.txt").Count(IsPasswordValid1); } static int Day2Part2() { return File.ReadAllLines(RootDir + "day02.txt").Count(IsPasswordValid2); } [Fact] static void Day2Test() { Assert.True(IsPasswordValid1("1-3 a: abcde")); Assert.False(IsPasswordValid1("1-3 b: cdefg")); Assert.True(IsPasswordValid1("2-9 c: ccccccccc")); Assert.Equal(603, Day2Part1()); Assert.True(IsPasswordValid2("1-3 a: abcde")); Assert.False(IsPasswordValid2("1-3 b: cdefg")); Assert.False(IsPasswordValid2("2-9 c: ccccccccc")); Assert.Equal(404, Day2Part2()); } static void Main(string[] args) { Day2Test(); } } }