using System.Collections.Generic;
internal class TaskSolver
public static void Main(string[] args)
TestGenerateWordsFromWord();
TestGetPreviousMaxDigital();
TestSearchQueenOrHorse();
Console.WriteLine("All Test completed!");
public static List<string> GenerateWordsFromWord(string word, List<string> wordDictionary)
var CreateableWords = new List<string>();
for(int i = 0; i < wordDictionary.Count; i++)
if(wordDictionary[i].Length < word.Length)
bool isCreateable = true;
foreach(char c in wordDictionary[i])
if(!word_copy.Contains(c))
word_copy = word_copy.Remove(word_copy.IndexOf(c),1);
CreateableWords.Add(wordDictionary[i]);
public static int MaxLengthTwoChar(string word)
Dictionary<char,int> charAmountDictionary = new Dictionary<char,int>();
charAmountDictionary = CountAllChars(charAmountDictionary, word);
if(charAmountDictionary.Count < 2)
List<char> compatibleChars = new List<char>();
int temp_maxAmount = charAmountDictionary.Values.Max();
char maxChar = charAmountDictionary.Last(x => x.Value == temp_maxAmount).Key;
charAmountDictionary.Remove(maxChar);
if(charAmountDictionary.Count() == 0)
foreach(var c in charAmountDictionary)
if(c.Value == temp_maxAmount)
compatibleChars.Add(c.Key);
if(c.Value == temp_maxAmount-1)
compatibleChars.Insert(0,c.Key);
foreach(char compC in compatibleChars)
string strAB = new string((from c in word where c == compC || c == maxChar select c).ToArray());
if(!strAB.Contains(new string (maxChar,2)) && !strAB.Contains(new string (compC,2)))
public static Dictionary<char,int> CountAllChars(Dictionary<char,int> charAmountDictionary, string word)
for(int i = 0; i < word.Length; i++)
if(!charAmountDictionary.ContainsKey(word[i]))
charAmountDictionary[word[i]] = new int();
charAmountDictionary[word[i]]++;
return charAmountDictionary;
public static long GetPreviousMaxDigital(long value)
var digits = value.ToString().ToCharArray();
int i = digits.Count()-1;
if(digits[i-1] > digits[i])
for(int j = digits.Count()-1; j > i-1; j--)
if(digits[j] < digits[i-1])
digits = SwapElements<char>(i-1,j,digits);
Array.Reverse(digits, i, digits.Count()-i);
string s = new string(digits);
public static T[] SwapElements<T>(int i1,int i2, T[] array)
var tmp_value = array[i1];
public static List<int> SearchQueenOrHorse(char[][] gridMap)
var result = FindStartPoint(gridMap);
int[] startPoint = result.Item1;
char[][] copy = new char[gridMap.Length][];
copy = CopyArray(gridMap);
return new List<int>(){HorsePathFinding(startPoint, copy), QueenPathFinding(startPoint, gridMap)};
static T[][] CopyArray<T>(T[][] array)
var lenght = array.Length;
var dest = new T[lenght][];
for (var x = 0; x < lenght; x++)
Array.Copy(inner, newer, ilen);
public static (int[],char[][]) FindStartPoint(char[][] map)
for(int y = 0; y < map.Length; y++)
for(int x = 0; x < map[y].Length; x++)
return (new int[]{x,y}, map);
return (new int[]{-1, -1}, map);
public static int QueenPathFinding(int[] startPoint, char[][] map)
List<int[]> stepWays = new List<int[]>(){new int[]{1,0}, new int[]{-1,0}, new int[]{0,1}, new int[]{0,-1}, new int[]{1,1}, new int[]{-1,1}, new int[]{1,-1}, new int[]{-1,-1}};
List<int[]> nextToCheckCells = new List<int[]>();
List<int[]> currentCellsToCheck = new List<int[]>();
int yLenght = map.Length;
int xLenght = map[0].Length;
currentCellsToCheck.Add(startPoint);
foreach(var cell in currentCellsToCheck)
foreach(var way in stepWays)
int[] checkCell = new int[]{cell[0]+way[0]*i,cell[1]+way[1]*i};
if(checkCell[0] > -1 && checkCell[1] > -1 && checkCell[0] < xLenght && checkCell[1] < yLenght && map[checkCell[1]][checkCell[0]] != 'x')
if(map[checkCell[1]][checkCell[0]] != 'c')
if(map[checkCell[1]][checkCell[0]] == 'e')
map[checkCell[1]][checkCell[0]] = 'c';
map[checkCell[1]][checkCell[0]]='x';
nextToCheckCells.Add(new int[]{checkCell[0], checkCell[1]});
if(nextToCheckCells.Count() == 0)
currentCellsToCheck = new List<int[]>(nextToCheckCells);
nextToCheckCells.Clear();
public static int HorsePathFinding(int[] startPoint, char[][] map)
List<int[]> stepWays = new List<int[]>(){new int[]{-2,-1}, new int[]{-2,1}, new int[]{2,-1}, new int[]{2,1}, new int[]{-1,-2}, new int[]{-1,2}, new int[]{1,-2}, new int[]{1,2}};
List<int[]> nextToCheckCells = new List<int[]>();
List<int[]> currentCellsToCheck = new List<int[]>();
int yLenght = map.Length;
int xLenght = map[0].Length;
currentCellsToCheck.Add(startPoint);
foreach(var cell in currentCellsToCheck)
foreach(var way in stepWays)
int[] checkCell = new int[]{cell[0]+way[0],cell[1]+way[1]};
if(checkCell[0] > -1 && checkCell[1] > -1 && checkCell[0] < xLenght && checkCell[1] < yLenght && map[checkCell[1]][checkCell[0]] != 'x')
if(map[checkCell[1]][checkCell[0]] == 'e')
nextToCheckCells.Add(new int[]{checkCell[0], checkCell[1]});
map[checkCell[1]][checkCell[0]] = 'x';
if(nextToCheckCells.Count() == 0)
currentCellsToCheck = new List<int[]>(nextToCheckCells);
nextToCheckCells.Clear();
public static long CalculateMaxCoins(int[][] mapData, int idStart, int idFinish)
Dictionary<int,List<int[]>> wayCostDictionary = new Dictionary<int,List<int[]>>();
List<int> path = new List<int>();
wayCostDictionary = SortAllWaysToDictionary(wayCostDictionary, mapData);
wayCostDictionary = RemoveDeadendsCities(wayCostDictionary, idStart, idFinish);
int maxPathLenght = FindMaxPath(path, idStart, idFinish, wayCostDictionary);
private static Dictionary<int,List<int[]>> SortAllWaysToDictionary(Dictionary<int,List<int[]>> wayCostDictionary, int[][] mapData)
for(int i = 0; i < mapData.Length; i++)
if(!wayCostDictionary.ContainsKey(data[0]))
wayCostDictionary[data[0]] = new List<int[]>();
wayCostDictionary[data[0]].Add(new int[]{data[1], data[2]});
if(!wayCostDictionary.ContainsKey(data[1]))
wayCostDictionary[data[1]] = new List<int[]>();
wayCostDictionary[data[1]].Add(new int[]{data[0], data[2]});
return wayCostDictionary;
private static Dictionary<int,List<int[]>> RemoveDeadendsCities(Dictionary<int,List<int[]>> wayCostDictionary, int idStart, int idFinish)
foreach(var (key, list) in wayCostDictionary)
if(wayCostDictionary[key].Count < 2 && key != idStart && key != idFinish)
wayCostDictionary.Remove(key);
wayCostDictionary[list.Last()[0]] = wayCostDictionary[list.Last()[0]].Where(c => c[0] != key).ToList();
}while(isDeadends == true);
return wayCostDictionary;
private static int FindMaxPath(List<int> path, int idCity, int idFinish, Dictionary<int,List<int[]>> wayCostDictionary)
List<int> finishedPath = new List<int>();
foreach(var ways in wayCostDictionary[idCity])
if(!path.Contains(ways[0]))
finishedPath = new List<int>(path);
finishedPath.Add(ways[0]);
maxPathLenght = Math.Max(maxPathLenght, FindMaxPath(path, ways[0], idFinish, wayCostDictionary));
for(int i = 0; i < finishedPath.Count()-1; i++)
int[] k = new int[]{0,0};
k = wayCostDictionary[finishedPath.ElementAt(i)].Find(x => x[0]==finishedPath.ElementAt(i+1));
currentLenght = currentLenght + k[1];
if(currentLenght > maxPathLenght)
maxPathLenght = currentLenght;
private static void TestGenerateWordsFromWord()
var wordsList = new List<string>
"кот", "ток", "око", "мимо", "гром", "ром", "мама",
"рог", "морг", "огр", "мор", "порог", "бра", "раб", "зубр"
AssertSequenceEqual( GenerateWordsFromWord("арбуз", wordsList), new []{ "бра", "зубр", "раб"} );
AssertSequenceEqual( GenerateWordsFromWord("лист", wordsList), new List<string>() );
AssertSequenceEqual( GenerateWordsFromWord("маг", wordsList), new List<string>() );
AssertSequenceEqual( GenerateWordsFromWord("погром", wordsList), new List<string>{ "гром", "мор", "морг", "огр", "порог", "рог", "ром"} );
AssertSequenceEqual( GenerateWordsFromWord("ммокоаг", wordsList), new List<string>{"око"});
private static void TestMaxLengthTwoChar()
AssertEqual(MaxLengthTwoChar("beabeeab"), 5);
AssertEqual(MaxLengthTwoChar("а"), 0);
AssertEqual(MaxLengthTwoChar("aa"), 0);
AssertEqual(MaxLengthTwoChar("ab"), 2);
AssertEqual(MaxLengthTwoChar("aabb"), 0);
AssertEqual(MaxLengthTwoChar("daabbggd"), 0);
AssertEqual(MaxLengthTwoChar("fabgcad"), 3);
AssertEqual(MaxLengthTwoChar("fabgcba"), 3);
AssertEqual(MaxLengthTwoChar("abbabcdeedk"), 2);
AssertEqual(MaxLengthTwoChar("cabbacbcdeedkkk"), 0);
AssertEqual(MaxLengthTwoChar("aag"), 0);
private static void TestGetPreviousMaxDigital()
AssertEqual(GetPreviousMaxDigital(21), 12l);
AssertEqual(GetPreviousMaxDigital(531), 513l);
AssertEqual(GetPreviousMaxDigital(1027), -1l);
AssertEqual(GetPreviousMaxDigital(2071), 2017l);
AssertEqual(GetPreviousMaxDigital(207034), 204730l);
AssertEqual(GetPreviousMaxDigital(135), -1l);
AssertEqual(GetPreviousMaxDigital(100273), 100237l);
AssertEqual(GetPreviousMaxDigital(103467), -1l);
AssertEqual(GetPreviousMaxDigital(11223322), 11223232l);
AssertEqual(GetPreviousMaxDigital(9865679), 9859766l);
AssertEqual(GetPreviousMaxDigital(789311223335), 789253333211l);
private static void TestSearchQueenOrHorse()
new[] {'s', '#', '#', '#', '#', '#'},
new[] {'#', 'x', 'x', 'x', 'x', '#'},
new[] {'#', '#', '#', '#', 'x', '#'},
new[] {'#', '#', '#', '#', 'x', '#'},
new[] {'#', '#', '#', '#', '#', 'e'},
AssertSequenceEqual(SearchQueenOrHorse(gridA), new []{3, 2});
new[] {'s', '#', '#', '#', '#', 'x'},
new[] {'#', 'x', 'x', 'x', 'x', '#'},
new[] {'#', 'x', '#', '#', 'x', '#'},
new[] {'#', '#', '#', '#', 'x', '#'},
new[] {'x', '#', '#', '#', '#', 'e'},
AssertSequenceEqual(SearchQueenOrHorse(gridB), new []{-1, 3});
new[] {'s', '#', '#', '#', '#', 'x'},
new[] {'x', 'x', 'x', 'x', 'x', 'x'},
new[] {'#', '#', '#', '#', 'x', '#'},
new[] {'#', '#', '#', 'e', 'x', '#'},
new[] {'x', '#', '#', '#', '#', '#'},
AssertSequenceEqual(SearchQueenOrHorse(gridC), new []{2, -1});
AssertSequenceEqual(SearchQueenOrHorse(gridD), new []{-1, 1});
AssertSequenceEqual(SearchQueenOrHorse(gridE), new []{1, -1});
new[] {'x', '#', '#', 'x'},
new[] {'#', 'x', 'x', '#'},
new[] {'#', 'x', '#', 'x'},
new[] {'e', 'x', 'x', 's'},
new[] {'#', 'x', 'x', '#'},
new[] {'x', '#', '#', 'x'},
AssertSequenceEqual(SearchQueenOrHorse(gridF), new []{-1, 5});
new[] {'#', '#', '#', '#'},
new[] {'#', '#', '#', '#'},
new[] {'#', 'x', '#', '#'},
new[] {'e', 'x', 'x', '#'},
new[] {'#', '#', '#', '#'},
new[] {'#', 'x', 'x', '#'},
new[] {'#', 'x', 'x', '#'},
new[] {'#', 'x', '#', 'x'},
new[] {'#', 'x', 'x', 'x'},
new[] {'#', 'x', 'x', 's'},
new[] {'#', '#', 'x', '#'},
new[] {'#', 'x', '#', 'x'},
AssertSequenceEqual(SearchQueenOrHorse(gridH), new []{5, 4});
private static void TestCalculateMaxCoins()
AssertEqual(CalculateMaxCoins(mapA, 0, 3), 11l);
AssertEqual(CalculateMaxCoins(mapB, 0, 5), -1l);
AssertEqual(CalculateMaxCoins(mapC, 0, 5), 19l);
AssertEqual(CalculateMaxCoins(mapD, 7, 0), 16l);
AssertEqual(CalculateMaxCoins(mapF, 0, 3), 9l);
AssertEqual(CalculateMaxCoins(mapG, 1, 7), 12l);
AssertEqual(CalculateMaxCoins(mapH, 1, 5), 8l);
AssertEqual(CalculateMaxCoins(mapJ, 1, 5), 133l);
private static void Assert(bool value)
throw new Exception("Assertion failed");
private static void AssertEqual(object value, object expectedValue)
if (value.Equals(expectedValue))
throw new Exception($"Assertion failed expected = {expectedValue} actual = {value}");
private static void AssertSequenceEqual<T>(IEnumerable<T> value, IEnumerable<T> expectedValue)
if (ReferenceEquals(value, expectedValue))
throw new ArgumentNullException(nameof(value));
if (expectedValue is null)
throw new ArgumentNullException(nameof(expectedValue));
var valueList = value.ToList();
var expectedValueList = expectedValue.ToList();
if (valueList.Count != expectedValueList.Count)
throw new Exception($"Assertion failed expected count = {expectedValueList.Count} actual count = {valueList.Count}");
for (var i = 0; i < valueList.Count; i++)
if (!valueList[i].Equals(expectedValueList[i]))
throw new Exception($"Assertion failed expected value at {i} = {expectedValueList[i]} actual = {valueList[i]}");