+ Нов въпрос
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;
{
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>();
}

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)
{
}
}
}

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
08/11/2020 12:46:22
Axiomatik 1371 Точки

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>();
}

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 = 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 229 Точки

@Axiomatik,

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

Best regards!

0
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 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)
{