public static IList<int> GetInvalidNearbyTicketValuesForAllFields(TicketData ticketData) { var result = new List<int>(); foreach (var nearbyTicket in ticketData.NearbyTickets) { foreach (var value in nearbyTicket.FieldValues) { var isValid = GetIsValidValueForAnyField(value, ticketData.TicketFields); if (!isValid) { result.Add(value); } } } return result; }
public static TicketData ParseInputLines(IList<string> inputLines) { var ticketFieldInputLines = new List<string>(); var yourTicketInputLine = string.Empty; var nearbyTicketInputLines = new List<string>(); bool isProcessingYourTicket = false; bool isProcessingNearbyTickets = false; foreach (var inputLine in inputLines) { if (string.IsNullOrWhiteSpace(inputLine)) continue; if (isProcessingYourTicket) { if ("nearby tickets:".Equals(inputLine)) { isProcessingYourTicket = false; isProcessingNearbyTickets = true; continue; } yourTicketInputLine = inputLine; } else if (isProcessingNearbyTickets) { nearbyTicketInputLines.Add(inputLine); } else { if ("your ticket:".Equals(inputLine)) { isProcessingYourTicket = true; continue; } ticketFieldInputLines.Add(inputLine); } } var ticketFields = ParseTicketFieldInputLines(ticketFieldInputLines); var yourTicket = ParseTicketInputLine(yourTicketInputLine); var nearbyTickets = ParseTicketInputLines(nearbyTicketInputLines); var result = new TicketData(ticketFields, yourTicket, nearbyTickets); return result; }
public static IList<Ticket> GetNearbyTicketsWithNoInvalidValues(TicketData ticketData) { var result = new List<Ticket>(); foreach (var nearbyTicket in ticketData.NearbyTickets) { bool isInvalidTicket = false; foreach (var value in nearbyTicket.FieldValues) { var isValid = GetIsValidValueForAnyField(value, ticketData.TicketFields); if (!isValid) { isInvalidTicket = true; break; } } if (!isInvalidTicket) { result.Add(nearbyTicket); } } return result; }
public static Dictionary<string, int> GetFieldIndexes(TicketData ticketData) { var result = new Dictionary<string, int>(); var validTickets = GetNearbyTicketsWithNoInvalidValues(ticketData); var indexTicketFieldCandidates = new Dictionary<int, IList<TicketField>>(); for (int fieldIndex = 0; fieldIndex < ticketData.TicketFields.Count; fieldIndex++) { var possibleTicketFields = GetTicketFieldsThatWorkForIndex( fieldIndex, validTickets, ticketData.TicketFields); indexTicketFieldCandidates[fieldIndex] = possibleTicketFields; } while (indexTicketFieldCandidates.Count > 0) { var currentCandidate = indexTicketFieldCandidates .OrderBy(kvp => kvp.Value.Count) .First(); if (currentCandidate.Value.Count != 1) { throw new Exception("Non-deterministic candidate found"); } var fieldIndex = currentCandidate.Key; var ticketField = currentCandidate.Value[0]; result[ticketField.Name] = fieldIndex; indexTicketFieldCandidates.Remove(fieldIndex); foreach (var kvp in indexTicketFieldCandidates) { kvp.Value.Remove(ticketField); } foreach (var kvp in indexTicketFieldCandidates) { if (kvp.Value.Count == 0) indexTicketFieldCandidates.Remove(kvp.Key); } } return result; }