Професионална програма
Loading...
+ Нов въпрос
Elena123456 avatar Elena123456 229 Точки

04. Snowwhite: Associative Arrays - More Exercise (50/100)

I need some help and for this exercise. The problem is in my sort method. I have no idea how to order the dwarfs by physics in descending order and then by total count of dwarfs with the same hat color in descending order. I was reading another solutions, but I can't understand. Can somebody please help me again.

https://softuni.bg/trainings/resources/officedocument/38560/more-exercise-technology-fundamentals-with-csharp-january-2019/2237

https://judge.softuni.bg/Contests/Practice/Index/1302#3

 

using System;
using System.Collections.Generic;
using System.Linq;

namespace Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            var hatColorWithNamesAndPhysics = new Dictionary<string, Dictionary<string, int>>();
            string input = string.Empty;
            while((input=Console.ReadLine())!="Once upon a time")
            {
                string[] inputArray = input.Split(" <:> ", StringSplitOptions.RemoveEmptyEntries).Select(x => x).ToArray();
                string name = inputArray[0];
                string hatColor = inputArray[1];
                int physics = int.Parse(inputArray[2]);

                if (hatColorWithNamesAndPhysics.ContainsKey(hatColor) == false)
                {
                    hatColorWithNamesAndPhysics[hatColor] = new Dictionary<string, int>();
                    hatColorWithNamesAndPhysics[hatColor].Add(name, physics);
                }

                else if (hatColorWithNamesAndPhysics.ContainsKey(hatColor) == true)
                {
                    bool haveDwarfWithTheSameName = false;
                    foreach (var kvp in hatColorWithNamesAndPhysics[hatColor])
                    {
                        string currentName = kvp.Key;
                        int currentPhysics = kvp.Value;
                        if (currentName == name)
                        {
                            haveDwarfWithTheSameName = true;
                            if (physics > currentPhysics)
                            {
                                hatColorWithNamesAndPhysics[hatColor][currentName] = physics;
                                break;
                            }
                        }
                    }

                    if (haveDwarfWithTheSameName == false)
                    {
                        hatColorWithNamesAndPhysics[hatColor].Add(name, physics);
                    }
                }
            }

            foreach (var kvp in hatColorWithNamesAndPhysics.OrderByDescending(x=>x.Value.Values.Max()).ThenByDescending(x=>x.Key.Count()))
            {
                string hatColor = kvp.Key;
                var namesWithPhysicsDictionary = kvp.Value;
                foreach (var kvp1 in namesWithPhysicsDictionary)
                {
                    string name = kvp1.Key;
                    int physic = kvp1.Value;
                    Console.WriteLine($"({hatColor}{name} <-> {physic}");
                }

            }
        }
    }
}

 

0
C# Fundamentals 08/11/2020 12:46:22
Axiomatik avatar Axiomatik 1371 Точки
Best Answer

Thanks to SvetoslavPetsev who has the best solution to this problem, which should be solved with objects otherwise it gets to brutal with the tripple-nested Dictionaries. The problem with a double-nested dictionary is that it groups dwarfs by their colors and not by their power, which means that a more powerful dwarf can get behind a weaker one if he finds himself in a bigger group. The filtering-constraints are also misleading in the description, which Svetoslav has shown in his code.

Best,

 

using System;
using System.Linq;
using System.Collections.Generic;

namespace Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            var hatColorWithNamesAndPhysics = new Dictionary<string, Dictionary<string, int>>();
            string input = string.Empty;
            while ((input = Console.ReadLine()) != "Once upon a time")
            {
                string[] inputArray = input.Split(" <:> ", StringSplitOptions.RemoveEmptyEntries).Select(x => x).ToArray();
                string name = inputArray[0];
                string hatColor = inputArray[1];
                int physics = int.Parse(inputArray[2]);

                if (hatColorWithNamesAndPhysics.ContainsKey(hatColor) == false)
                {
                    hatColorWithNamesAndPhysics[hatColor] = new Dictionary<string, int>();
                    hatColorWithNamesAndPhysics[hatColor].Add(name, physics);
                }

                else if (hatColorWithNamesAndPhysics.ContainsKey(hatColor) == true)
                {
                    bool haveDwarfWithTheSameName = false;
                    foreach (var kvp in hatColorWithNamesAndPhysics[hatColor])
                    {
                        string currentName = kvp.Key;
                        int currentPhysics = kvp.Value;
                        if (currentName == name)
                        {
                            haveDwarfWithTheSameName = true;
                            if (physics > currentPhysics)
                            {
                                hatColorWithNamesAndPhysics[hatColor][currentName] = physics;
                                break;
                            }
                        }
                    }

                    if (haveDwarfWithTheSameName == false)
                    {
                        hatColorWithNamesAndPhysics[hatColor].Add(name, physics);
                    }
                }
            }

            hatColorWithNamesAndPhysics = hatColorWithNamesAndPhysics
                .OrderByDescending(x => x.Value.Count())
                .ToDictionary(x => x.Key, x => x.Value);

            var finalDwarfs = new Dictionary<int, Dictionary<int, Dictionary<string, string>>>();
            int dwarfNumber = 1;
            foreach (var (color, dwarfs) in hatColorWithNamesAndPhysics)
            {
                foreach (var (name, power) in dwarfs)
                {
                    finalDwarfs[dwarfNumber] = new Dictionary<int, Dictionary<string, string>>();
                    finalDwarfs[dwarfNumber][power] = new Dictionary<string, string>();
                    finalDwarfs[dwarfNumber][power][name] = color;
                    dwarfNumber++;
                }
            }

            finalDwarfs = finalDwarfs
                .OrderByDescending(d => d.Value.Keys.Max())
                .ToDictionary(x => x.Key, x => x.Value);

            foreach (var (number, dwarf) in finalDwarfs)
            {
                foreach (var (power, nameAndColor) in dwarf)
                {
                    foreach (var (name, color) in nameAndColor)
                    {
                        Console.WriteLine($"({color}) {name} <-> {power}");

                    }
                }
            }
        }
    }
}

1
Elena123456 avatar Elena123456 229 Точки

@Axiomatik,

thank you very much for this solution. I will try my best to understand it better. :)

Best regards!

0
Axiomatik avatar Axiomatik 1371 Точки

Try the following input with your original code and this new one and the difference becomes easier to see.

All the best,

Pesho <:> Red <:> 5000

Pesho <:> Blue <:> 10000

Pesho <:> Red <:> 10000

Gosho <:> Yellow <:> 20000

Fesho <:> Blue <:> 200

Once upon a time

1
Elena123456 avatar Elena123456 229 Точки

@Axiomatik,

it means a lot that also take out of your time to help me out.  When I read your solution at work I could not wait to get home so I could tryed out.

I hope is not arrogant from me since I really apreciate you also helping me out, but I have stumbled upon a simpler solution and I love to share. The creator is @NikolayNeykov92 from this- https://softuni.bg/forum/21589/04-snowwhite-retake-exam-05-january-2018. The trick is to order against the recomendation- first  order by descending all dwarfs by hat color and than order by descending by physic. When we print, the result is exactly according the recomendation.

https://pastebin.com/rk2PXVSr - 100/100

Best regards!

Eli

 

  Dictionary<string, int> sortedDwarfs = new Dictionary<string, int>();
            foreach (var hatColor in hatColorWithNamesAndPhysics.OrderByDescending(x => x.Value.Count()))
            {
                foreach (var dwarf in hatColor.Value)
                {
                    sortedDwarfs.Add($"({hatColor.Key}{dwarf.Key} <-> ", dwarf.Value);
                }
            }

            foreach (var dwarf in sortedDwarfs.OrderByDescending(x => x.Value))
            {
                Console.WriteLine($"{dwarf.Key}{dwarf.Value}");
            }

1