예제 #1
0
        public (Dictionary <string, Allergen> Allergens, Dictionary <string, int> IngredientsCount) ParseInput(string input)
        {
            Dictionary <string, Allergen> allergens        = new Dictionary <string, Allergen>();
            Dictionary <string, int>      ingredientsCount = new Dictionary <string, int>();

            foreach (var line in input.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries))
            {
                var ingredientsAndAllergens = line.Split("(contains ");
                var ingredients             = ingredientsAndAllergens[0].Split(" ", StringSplitOptions.RemoveEmptyEntries);
                var aller = ingredientsAndAllergens[1].Replace(")", "").Split(", ");

                foreach (var a in aller)
                {
                    if (allergens.ContainsKey(a))
                    {
                        allergens[a].AddIngredients(ingredients);
                    }
                    else
                    {
                        allergens[a] = new Allergen(a, ingredients);
                    }
                }

                foreach (var i in ingredients)
                {
                    if (ingredientsCount.ContainsKey(i))
                    {
                        ingredientsCount[i]++;
                    }
                    else
                    {
                        ingredientsCount[i] = 1;
                    }
                }
            }

            return(allergens, ingredientsCount);
        }
예제 #2
0
 public Ingredient(string nm)
 {
     Name   = nm;
     causes = null;
 }
예제 #3
0
        public void Part2()
        {
            List <Item> items = File.ReadAllLines("Day21Input.txt").Select(line => new Item(line)).ToList();

            Dictionary <string, List <Item> > itemsByAllergen = new Dictionary <string, List <Item> >();

            HashSet <string> allIngredients = new HashSet <string>();

            foreach (Item item in items)
            {
                foreach (string ingredient in item.Ingredients)
                {
                    allIngredients.Add(ingredient);
                }

                foreach (string allergen in item.Allergens)
                {
                    if (!itemsByAllergen.TryGetValue(allergen, out List <Item> list))
                    {
                        list = new List <Item>();
                        itemsByAllergen.Add(allergen, list);
                    }

                    list.Add(item);
                }
            }

            Dictionary <string, HashSet <string> > possibleIngredientsByAllergen = new Dictionary <string, HashSet <string> >();

            foreach (string allergen in itemsByAllergen.Keys)
            {
                string[] intersection = itemsByAllergen[allergen].Select(i => i.Ingredients).Aggregate((x, y) => x.Intersect(y).ToArray()).ToArray();
                possibleIngredientsByAllergen.Add(allergen, new HashSet <string>(intersection));
            }

            foreach (string ingredient in possibleIngredientsByAllergen.Values.SelectMany(arr => arr.Select(i => i)))
            {
                allIngredients.Remove(ingredient);
            }

            foreach (string ingredient in allIngredients /* now non-allergen ingredients */)
            {
                foreach (HashSet <string> set in possibleIngredientsByAllergen.Values)
                {
                    set.Remove(ingredient);
                }
            }

            List <Allergen> unsolvedAllergens = possibleIngredientsByAllergen.Select(kvp => new Allergen()
            {
                Name = kvp.Key, PossibleIngredients = kvp.Value
            }).ToList();
            List <Allergen> solvedAllergens = new List <Allergen>();

            while (unsolvedAllergens.Count > 0)
            {
                Allergen current = unsolvedAllergens.First(a => a.PossibleIngredients.Count == 1);
                unsolvedAllergens.Remove(current);
                solvedAllergens.Add(current);

                current.Ingredient = current.PossibleIngredients.Single();

                foreach (Allergen a in unsolvedAllergens)
                {
                    a.PossibleIngredients.Remove(current.Ingredient);
                }
            }

            string[] resultArray = solvedAllergens.OrderBy(a => a.Name).Select(a => a.Ingredient).ToArray();
            string   result      = string.Join(",", resultArray);

            Assert.Equal("ktpbgdn,pnpfjb,ndfb,rdhljms,xzfj,bfgcms,fkcmf,hdqkqhh", result);
        }