internal static Queue <int> parse_player(c_input_reader input_reader) { // Discard the 'Player X' line. input_reader.read_line(); Queue <int> player = new Queue <int>(); // Loop until we either run out of input or read an empty line. string input_line; while (input_reader.has_more_lines()) { input_line = input_reader.read_line(); if (string.IsNullOrEmpty(input_line)) { break; } // Enqueue the input line as a number. player.Enqueue(int.Parse(input_line)); } return(player); }
public void read_from_lines(c_input_reader input_reader) { input_reader.read_line(); for (int row = 0; row < k_bingo_board_side; row++) { string[] values = input_reader.read_line().Split(' ').Where(x => x.Length > 0).ToArray(); for (int column = 0; column < k_bingo_board_side; column++) { m_spaces[row, column] = new c_bingo_space(int.Parse(values[column])); } } }
public static void Part_1(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); int result = 0; while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); string[] input_line_segments = input_line.Split(" | "); string[] output_values = input_line_segments[1].Split(" "); foreach (string output_value in output_values) { int output_value_length = output_value.Length; if (output_value_length == 2 || output_value_length == 3 || output_value_length == 4 || output_value_length == 7) { result++; } } } Console.WriteLine("Result = {0}", result); }
public static c_octopus[][] parse_input(string input) { c_input_reader input_reader = new c_input_reader(input); int row = 0; List <c_octopus[]> octopi_row_list = new List <c_octopus[]>(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); List <c_octopus> octopi_list = new List <c_octopus>(); int col = 0; foreach (int initial_energy in input_line.Select(x => x - '0')) { octopi_list.Add(new c_octopus(row, col, initial_energy)); col++; } octopi_row_list.Add(octopi_list.ToArray()); row++; } return(octopi_row_list.ToArray()); }
internal static c_snailfish_number[] parse_input( string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); List <c_snailfish_number> numbers = new List <c_snailfish_number>(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); numbers.Add(new c_snailfish_number(input_line)); } if (pretty) { Console.WriteLine("input:"); foreach (c_snailfish_number number in numbers) { number.display(pretty); Console.WriteLine(); } } return(numbers.ToArray()); }
public static void Part_2(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); List <int> seat_ids = new List <int>(); while (input_reader.has_more_lines()) { c_seat seat = new c_seat(input_reader.read_line()); int seat_id = seat.get_seat_id(); seat_ids.Add(seat_id); } seat_ids.Sort(); for (int i = 0; i < seat_ids.Count; i++) { if (seat_ids[i] + 1 != seat_ids[i + 1]) { Console.WriteLine("My seat ID = {0}", seat_ids[i] + 1); return; } } }
public static Dictionary <string, c_cave> parse_input(string input) { c_input_reader input_reader = new c_input_reader(input); Dictionary <string, c_cave> caves = new Dictionary <string, c_cave>(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); string[] new_cave_names = input_line.Split("-").ToArray(); c_cave[] new_caves = new c_cave[2]; for (int i = 0; i < new_caves.Length; i++) { if (!caves.ContainsKey(new_cave_names[i])) { new_caves[i] = new c_cave(new_cave_names[i]); caves.Add(new_cave_names[i], new_caves[i]); } else { new_caves[i] = caves[new_cave_names[i]]; } } c_cave.make_neighbors(new_caves[0], new_caves[1]); } return(caves); }
public static void Part_1(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); int result = 0; while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); Stack <c_chunk> chunks = new Stack <c_chunk>(); bool line_corrupt = false; foreach (char input_char in input_line) { if (input_char == '(' || input_char == '[' || input_char == '{' || input_char == '<') { chunks.Push(new c_chunk(input_char)); } else { c_chunk chunk = chunks.Pop(); if (input_char != chunk.end_char) { int score = get_score(input_char); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine( "Expected {0}, but found {1} instead. ({2} points)", chunk.end_char, input_char, score); result += score; line_corrupt = true; break; } } } if (!line_corrupt) { Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("Line valid."); } } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(); Console.WriteLine("Result = {0}", result); Console.ResetColor(); }
public static void Part_1(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); int result = 0; List <int[]> heights_list = new List <int[]>(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); heights_list.Add(input_line.Select(x => x - '0').ToArray()); } int[][] heights = heights_list.ToArray(); for (int row = 0; row < heights.Length; row++) { for (int col = 0; col < heights[row].Length; col++) { int current_height = heights[row][col]; List <int> neighbor_heights = new List <int>(); if (row > 0) { neighbor_heights.Add(heights[row - 1][col]); } if (row < heights.Length - 1) { neighbor_heights.Add(heights[row + 1][col]); } if (col > 0) { neighbor_heights.Add(heights[row][col - 1]); } if (col < heights[row].Length - 1) { neighbor_heights.Add(heights[row][col + 1]); } if (neighbor_heights.All(neighbor_height => (current_height < neighbor_height))) { Console.WriteLine( "Low point found: heights[{0}][{1}] = {2}", row, col, current_height); result += current_height + 1; } } } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(); Console.WriteLine("Result = {0}", result); Console.ResetColor(); }
internal static void parse_input(string input, out List <c_coordinate> points, out List <c_fold> folds, out c_coordinate max) { c_input_reader input_reader = new c_input_reader(input); points = new List <c_coordinate>(); max = new c_coordinate(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); if (string.IsNullOrEmpty(input_line)) { break; } int[] parsed_input_line = input_line.Split(",").Select(x => int.Parse(x)).ToArray(); c_coordinate new_point = new c_coordinate() { X = parsed_input_line[0], Y = parsed_input_line[1] }; points.Add(new_point); max = max_coordinate(max, new_point); } folds = new List <c_fold>(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); string[] split_input_line = input_line.Split(" ").ToArray(); string[] parsed_input_line = split_input_line[2].Split("="); int fold_position = int.Parse(parsed_input_line[1]); e_orientation fold_orientation = (parsed_input_line[0] == "x") ? e_orientation.vertical : e_orientation.horizontal; folds.Add(new c_fold { position = fold_position, orientation = fold_orientation }); } }
public c_sea_floor(c_input_reader input_reader) { sea_cucumbers = new List <c_sea_cucumber>(); List <c_sea_cucumber[]> position_list = new List <c_sea_cucumber[]>(); s_coordinate position = new s_coordinate { row = 0, column = 0 }; while (input_reader.has_more_lines()) { List <c_sea_cucumber> position_row_list = new List <c_sea_cucumber>(); position.column = 0; foreach (char input_char in input_reader.read_line()) { c_sea_cucumber sea_cucumber = null; switch (input_char) { case '>': sea_cucumber = new c_sea_cucumber { position = position, velocity = k_east }; break; case 'v': sea_cucumber = new c_sea_cucumber { position = position, velocity = k_south }; break; case '.': break; default: throw new Exception("Invalid input"); } if (sea_cucumber != null) { sea_cucumbers.Add(sea_cucumber); } position_row_list.Add(sea_cucumber); position.column++; } position_list.Add(position_row_list.ToArray()); position.row++; } positions = position_list.ToArray(); }
public c_reactor_core(c_input_reader input_reader) { // Expand cubes to the corrext size and fill with 'false's. cubes = new bool[bounds.range_x][][]; for (int x = 0; x < cubes.Length; x++) { cubes[x] = new bool[bounds.range_y][]; for (int y = 0; y < cubes[x].Length; y++) { cubes[x][y] = new bool[bounds.range_z]; } } Regex input_regex = new Regex(@"^(\w+) x=(-?\d+)\.\.(-?\d+),y=(-?\d+)\.\.(-?\d+),z=(-?\d+)\.\.(-?\d+)$"); // Parse each line as a cuboid while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); Match match = input_regex.Match(input_line); bool enabled_value = match.Groups[1].Value == "on"; c_cuboid input_cuboid = new c_cuboid( new c_bounds( Int64.Parse(match.Groups[2].Value), Int64.Parse(match.Groups[3].Value)), new c_bounds( Int64.Parse(match.Groups[4].Value), Int64.Parse(match.Groups[5].Value)), new c_bounds( Int64.Parse(match.Groups[6].Value), Int64.Parse(match.Groups[7].Value))); c_cuboid valid_cuboid = input_cuboid.intersect(bounds); if (valid_cuboid != null) { // set/clear each cube one at a time in our cuboid. for (Int64 x = valid_cuboid.bounds_x.min; x <= valid_cuboid.bounds_x.max; x++) { for (Int64 y = valid_cuboid.bounds_y.min; y <= valid_cuboid.bounds_y.max; y++) { for (Int64 z = valid_cuboid.bounds_z.min; z <= valid_cuboid.bounds_z.max; z++) { cubes[x - bounds.bounds_x.min][y - bounds.bounds_y.min][z - bounds.bounds_z.min] = enabled_value; } } } } } }
internal static c_square parse_input( string input) { c_input_reader input_reader = new c_input_reader(input); string input_line = input_reader.read_line(); c_square target_area = new c_square(input_line); return(target_area); }
public c_tile(c_input_reader input_reader) { // Read the tile's ID number. string id_string = input_reader.read_line(); id_string = id_string.Substring(5, id_string.Length - 6); id = int.Parse(id_string); // Read the tile's grid. int row = 0; string input_line; while (input_reader.has_more_lines()) { input_line = input_reader.read_line(); if (string.IsNullOrEmpty(input_line)) { break; } for (int column = 0; column < input_line.Length; column++) { grid[row, column] = input_line[column] == '#'; } row++; } // Compute the tile's edge ID numbers. for (int edge_index = 0; edge_index < k_edge_traverals.Length; edge_index++) { edge_ids[edge_index] = compute_edge_id(edge_index); } }
internal static (c_image_enhancement_algorithm, c_image) parse_input( string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); c_image_enhancement_algorithm algorithm = new c_image_enhancement_algorithm(input_reader.read_line()); input_reader.read_line(); c_image image = new c_image(input_reader); return(algorithm, image); }
internal static c_player[] parse_input( string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); List <c_player> players = new List <c_player>(); while (input_reader.has_more_lines()) { players.Add(new c_player(input_reader.read_line())); } return(players.ToArray()); }
public static void Part_1(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); int[] moves = input_reader.read_line() .Split(',') .Select(move => int.Parse(move)) .ToArray(); List <c_bingo_board> boards = new List <c_bingo_board>(); while (input_reader.has_more_lines()) { c_bingo_board board = new c_bingo_board(); board.read_from_lines(input_reader); boards.Add(board); } int winning_score = 0; foreach (int move in moves) { foreach (c_bingo_board board in boards) { int score = board.check_move(move); if (score != 0) { Console.WriteLine("We have a winner!"); Console.WriteLine(); board.print(); Console.WriteLine(); Console.WriteLine("Winning Move = " + move); winning_score = score; break; } } if (winning_score != 0) { break; } } Console.WriteLine("Winning Score = " + winning_score); }
public static void Part_1(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); c_point min = new c_point(int.MaxValue, int.MaxValue); c_point max = new c_point(int.MinValue, int.MinValue); List <c_line_segment> line_segments = new List <c_line_segment>(); while (input_reader.has_more_lines()) { c_line_segment line_segment = new c_line_segment(input_reader.read_line()); min.X = Math.Min(min.X, Math.Min(line_segment.Start.X, line_segment.End.X)); min.Y = Math.Min(min.Y, Math.Min(line_segment.Start.Y, line_segment.End.Y)); max.X = Math.Max(max.X, Math.Max(line_segment.Start.X, line_segment.End.X)); max.Y = Math.Max(max.Y, Math.Max(line_segment.Start.Y, line_segment.End.Y)); if (!line_segment.diagonal()) { line_segments.Add(line_segment); } } int points_with_overlap = 0; c_point point = new c_point(); for (point.X = min.X; point.X < max.X; point.X++) { for (point.Y = min.Y; point.Y < max.Y; point.Y++) { IEnumerable <c_line_segment> line_segments_covering = line_segments.Where(line_segment => line_segment.covers(point)); int lines_covering = line_segments_covering.Count(); if (lines_covering > 1) { points_with_overlap++; } } } Console.WriteLine("Points with overlap: " + points_with_overlap); }
public c_group(c_input_reader input_reader) { while (input_reader.has_more_lines()) { string line = input_reader.read_line(); if (string.IsNullOrEmpty(line)) { break; } foreach (char character in line) { set_answer(character); } m_people++; } }
public static void Part_1(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); int highest_seat_id = 0; while (input_reader.has_more_lines()) { c_seat seat = new c_seat(input_reader.read_line()); int seat_id = seat.get_seat_id(); if (seat_id > highest_seat_id) { highest_seat_id = seat_id; } } Console.WriteLine("The highest Seat ID = {0}", highest_seat_id); }
public c_scanner(c_input_reader input_reader) { List <c_vector> beacon_list = new List <c_vector>(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); if (string.IsNullOrEmpty(input_line)) { break; } int[] input_numbers = input_line.Split(",").Select(x => int.Parse(x)).ToArray(); beacon_list.Add(new c_vector(input_numbers[0], input_numbers[1], input_numbers[2])); } scanner = new c_vector(0, 0, 0); beacons = beacon_list.ToArray(); }
public static void Day_7_Worker(string input, bool use_better_cost) { c_input_reader input_reader = new c_input_reader(input); List <int> starting_positions = input_reader.read_line().Split(',').Select(x => int.Parse(x)).ToList(); int max_position = starting_positions.Max(); int[] positions = new int[max_position + 1]; foreach (int starting_position in starting_positions) { positions[starting_position]++; } Console.WriteLine("Starting Positions = {0}", string.Join(", ", positions)); int[] costs = new int[max_position + 1]; for (int i = 0; i < positions.Length; i++) { if (use_better_cost) { costs[i] = calculate_better_cost(ref positions, i); } else { costs[i] = calculate_cost(ref positions, i); } } Console.WriteLine(); Console.WriteLine("Costs = {0}", string.Join(", ", costs)); Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Lowest Cost = {0}", costs.Min()); Console.ResetColor(); }
public static void Day_6_Worker(string input, int days) { c_input_reader input_reader = new c_input_reader(input); UInt64[] starting_ages = input_reader.read_line().Split(',').Select(x => UInt64.Parse(x)).ToArray(); UInt64[] ages = new UInt64[9]; foreach (int starting_age in starting_ages) { ages[starting_age]++; } for (int day = 1; day <= days; day++) { UInt64 spawned = ages[0]; for (int i = 0; i < ages.Length - 1; i++) { ages[i] = ages[i + 1]; } ages[8] = spawned; ages[6] += spawned; } UInt64 total_alive = 0; for (int age = 0; age <= 8; age++) { Console.WriteLine("ages[{0}] = {1} ({2})", age, ages[age], ages[age].ToString("#,#")); total_alive += ages[age]; } Console.WriteLine(); Console.WriteLine("Total Alive = {0} ({1})", total_alive, total_alive.ToString("#,#")); }
internal static c_map_node[][] parse_input( string input) { c_input_reader input_reader = new c_input_reader(input); List <c_map_node[]> map = new List <c_map_node[]>(); for (int row = 0; input_reader.has_more_lines(); row++) { string input_line = input_reader.read_line(); List <c_map_node> map_line = new List <c_map_node>(); for (int column = 0; column < input_line.Length; column++) { map_line.Add(new c_map_node(input_line[column] - '0', row, column)); } map.Add(map_line.ToArray()); } return(map.ToArray()); }
public static void Part_2(string input, bool pretty) { c_input_reader input_reader = new c_input_reader(input); int total_result = 0; while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); string[] input_line_segments = input_line.Split(" | "); string[] input_values = input_line_segments[0].Split(" "); string[] output_values = input_line_segments[1].Split(" "); c_display display = new c_display(input_values); int output_result = 0; foreach (string output_value in output_values) { c_displayed_number displayed_number = new c_displayed_number(output_value); int output_digit = display.get_digit(displayed_number); output_result = output_result * 10 + output_digit; } Console.WriteLine("Output = {0}", output_result); total_result += output_result; } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(); Console.WriteLine("Result = {0}", total_result); Console.ResetColor(); }
public c_image(c_input_reader input_reader) { List <bool[]> data_list = new List <bool[]>(); while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); bool[] data_line = new bool[input_line.Length]; for (int i = 0; i < input_line.Length; i++) { if (input_line[i] == '#') { data_line[i] = true; } } data_list.Add(data_line); } background = false; data = data_list.ToArray(); }
public c_rule_collection(c_input_reader input_reader) { Dictionary <int, (int[], string)> pending_rules = new Dictionary <int, (int[], string)>(); // Loop through lines of input to parse the rules for (string input = input_reader.read_line(); !string.IsNullOrEmpty(input); input = input_reader.read_line()) { string[] split_input = input.Split(": "); int rule_id = int.Parse(split_input[0]); string rule_definition_input = split_input[1]; if (rule_definition_input[0] == '"') { // If a basic rule is found, add it to the final list of rules rules[rule_id] = new c_basic_rule(rule_id, rule_definition_input[1]); } else { // If a complex rule is found, add it's id, sub rule ids, and definition string to a temporary collection List <int> sub_rule_ids = new List <int>(); foreach (string sub_rule_id_input in rule_definition_input.Split(" ")) { int sub_rule_id; if (int.TryParse(sub_rule_id_input, out sub_rule_id)) { sub_rule_ids.Add(sub_rule_id); } } pending_rules[rule_id] = (sub_rule_ids.ToArray(), rule_definition_input); } } // Loop as long as there are still rules in the temporary collection while (pending_rules.Count > 0) { // Check against each rule foreach (int pending_rule_id in pending_rules.Keys) { // Look for a pending rule which has all subrules in the final rule list. (can also contain itself, which won't be in the final rule list yet) if (pending_rules[pending_rule_id].Item1.All(sub_rule_id => sub_rule_id == pending_rule_id || rules.ContainsKey(sub_rule_id))) { string[] multi_rule_definitions = pending_rules[pending_rule_id].Item2.Split(" | "); c_multi_rule[] multi_rules = new c_multi_rule[multi_rule_definitions.Length]; // Build a list of multi rules from the pending rule's definition string. for (int i = 0; i < multi_rule_definitions.Length; i++) { // Part 1: Just collect the subrules from our final rule list //c_rule[] sub_rules = multi_rule_definitions[i].Split(" ").Select(x => rules?[int.Parse(x)]).ToArray(); // Part 2: Since a rule can now have itself as a subrule, just insert 'null' into the array when that happens. c_rule[] sub_rules = multi_rule_definitions[i].Split(" ").Select(x => int.Parse(x)).Select( x => rules.ContainsKey(x) ? rules[x] : null).ToArray(); multi_rules[i] = new c_multi_rule(pending_rule_id, sub_rules); } // Save the new rule as either a choice rule or a multi rule based on how many groups of multi rules there were. c_rule new_rule; if (multi_rules.Length > 1) { new_rule = new c_choice_rule(pending_rule_id, multi_rules); } else { new_rule = multi_rules[0]; } // Fill nulls with itself, since those were references to itself! new_rule.fill_null_subrules(new_rule); rules[pending_rule_id] = new_rule; // Remove this rule from the temporary list. pending_rules.Remove(pending_rule_id); break; } } } }
public c_passport(c_input_reader input_reader, bool use_enhanced_validation) { while (input_reader.has_more_lines()) { string input_line = input_reader.read_line(); if (input_line.Length == 0) { break; } string[] fields = input_line.Split(" ").ToArray(); foreach (string field in fields) { string[] parsed_field = field.Split(":").ToArray(); string field_name = parsed_field[0]; string field_value = parsed_field[1]; if (k_required_fields.ContainsKey(field_name)) { m_required_field_values[k_required_fields[field_name]] = field_value; if (use_enhanced_validation) { switch (field_name) { case "byr": validate_number_field(field_name, field_value, 1920, 2002); break; case "iyr": validate_number_field(field_name, field_value, 2010, 2020); break; case "eyr": validate_number_field(field_name, field_value, 2020, 2030); break; case "hgt": validate_height_field(field_name, field_value); break; case "hcl": validate_hair_color_field(field_name, field_value); break; case "ecl": validate_eye_color_field(field_name, field_value); break; case "pid": validate_passport_id_field(field_name, field_value); break; } } } else if (k_optional_fields.ContainsKey(field_name)) { m_optional_field_values[k_optional_fields[field_name]] = field_value; } else if (Valid) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Invalid. Unexpected field {0}", field_name); Valid = false; } } } if (Valid) { for (int i = 0; i < k_required_field_names.Length; i++) { if (String.IsNullOrEmpty(m_required_field_values[i])) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Invalid. Missing required field {0}", k_required_field_names[i]); Valid = false; break; } } } if (Valid) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Valid"); } }
static void parse_input( string input, out Dictionary <string, HashSet <Tuple <int, string> > > contains, out Dictionary <string, HashSet <string> > contained_by) { c_input_reader input_reader = new c_input_reader(input); // Given a bag as input, find out which bags it can contain. contains = new Dictionary <string, HashSet <Tuple <int, string> > >(); // Given a bag as input, find out which bags can contain it. contained_by = new Dictionary <string, HashSet <string> >(); while (input_reader.has_more_lines()) { Match whole_line_match = k_whole_line_pattern.Match(input_reader.read_line()); string container = whole_line_match.Groups[1].Value; string[] containee_inputs = whole_line_match.Groups[2].Value.Split(", "); contains.TryAdd(container, new HashSet <Tuple <int, string> >()); foreach (string containee_input in containee_inputs) { if (containee_input != "no other bags") { Match containee_match = k_single_containee_pattern.Match(containee_input); int containee_count = int.Parse(containee_match.Groups[1].Value); string containee_name = containee_match.Groups[2].Value; Tuple <int, string> containee = new Tuple <int, string>(containee_count, containee_name); contains[container].Add(containee); contained_by.TryAdd(containee_name, new HashSet <string>()); contained_by[containee_name].Add(container); } } } if (contains.Count < 100) { foreach (string container in contains.Keys) { Console.ForegroundColor = ConsoleColor.Green; Console.Write("A [{0}] bag can contain [", container); Console.ForegroundColor = ConsoleColor.Gray; Console.Write(string.Join(", ", contains[container] .Select(x => x.Item1.ToString() + " " + x.Item2) .ToList())); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("]"); Console.ResetColor(); } Console.WriteLine(); foreach (string containee in contained_by.Keys) { Console.ForegroundColor = ConsoleColor.Green; Console.Write("A [{0}] bag can be contained by [", containee); Console.ForegroundColor = ConsoleColor.Gray; Console.Write(string.Join(", ", contained_by[containee].ToList())); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("]"); Console.ResetColor(); } } }
public static void Part_2( string input, bool pretty) { Dictionary <UInt64, UInt64> memory = new Dictionary <UInt64, UInt64>(); // Has a '1' for each '1' in the current mask. The rest are '0'. UInt64 bitmask_1s = 0; // Has a '0' for each '0' in the current mask. The rest are '1'. UInt64 bitmask_0s = UInt64.MaxValue; // Has a '1' for each 'X' in the current mask. The rest are '0'. UInt64 bitmask_xs = 0; // Stores the value of each bit that was 'X' in the current mask. // Ex: 001XX0X => {1, 4, 8}, since bits 1, 4, and 8 are 'X' in the mask. UInt64[] x_bits = new UInt64[0]; c_input_reader input_reader = new c_input_reader(input); // Loop through each input line while (input_reader.has_more_lines()) { string[] input_line = input_reader.read_line().Split(" = "); // Parse a 'mask' line if (input_line[0] == "mask") { string mask_string = input_line[1]; bitmask_1s = 0; bitmask_0s = UInt64.MaxValue; bitmask_xs = 0; List <UInt64> x_bits_list = new List <UInt64>(); // Read in each char in the mask UInt64 mask_bit = 1; for (int i = mask_string.Length - 1; i >= 0; i--) { char mask_char = mask_string[i]; // Update the bitmasks as necessary if (mask_char == '1') { bitmask_1s |= mask_bit; } else if (mask_char == '0') { bitmask_0s &= ~mask_bit; } else if (mask_char == 'X') { bitmask_xs |= mask_bit; x_bits_list.Add(mask_bit); } else { throw new Exception("bad mask"); } mask_bit <<= 1; } x_bits = x_bits_list.ToArray(); } // Parse a 'mem' line else { Match match = k_mem_input_regex.Match(input_line[0]); if (!match.Success) { throw new Exception("bad mem"); } // Get the current mem location and apply the current masks. Clear out bits where the mask was 'X' as well. UInt64 mem_location = UInt64.Parse(match.Groups[1].Value); UInt64 masked_location = mem_location | bitmask_1s; // masked_location = masked_location & bitmask_0s; Instructions say to ignore '0's. masked_location = masked_location & ~bitmask_xs; UInt64 mem_value = UInt64.Parse(input_line[1]); // Loop through all 2^(x_bits.Length) permuations of the 'X' bits. int mask_permutations = 1 << x_bits.Length; for (int mask_permutation = 0; mask_permutation < mask_permutations; mask_permutation++) { // Initialize the final memory address to the masked address with 'X' bits stripped out. UInt64 final_location = masked_location; // Loop through our x_bits and set any into final_destination based on the current permutation // Ex: // x_bits = {4, 8, 32} // mask_permutation = 5 = 0b101 // So mask_permutation has the first and third bits set, // So set the first and third values in x_bits into final_location // So Insert 4 and 32 into final_location. for (int bit_index = 0; bit_index < x_bits.Length; bit_index++) { if (0 != (mask_permutation & (1 << bit_index))) { final_location |= x_bits[bit_index]; } } // Save the value to memory. memory[final_location] = mem_value; } } } // Sum all values in memory UInt64 sum_of_all_values = memory.Values.Aggregate((x, y) => x + y); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(); Console.WriteLine("Result = {0}", sum_of_all_values); Console.ResetColor(); }