├── 1. Ошибки ├── AngryBirdsTask.cs ├── BilliardsTask.cs └── Procent.cs ├── 11. Основы ООП ├── Segment.cs └── VectorTask.cs ├── 12. Наследование ├── DiggerTask1.cs └── DiggerTask23.cs ├── 13. Целостность данных ├── AccountingModel.cs ├── Indexer.cs └── ReadOnlyVector.cs ├── 14. Структуры ├── ChartBuilder.cs ├── Generator.cs ├── GeneratorFinal.cs └── ProfilerTask.cs ├── 2. Ветвления ├── DistaceTask.cs ├── PluralizeTask.cs └── RectanglesTask.cs ├── 3. Циклы ├── DiagonalMazeTask.cs ├── DragonFractalTask.cs ├── EmptyMazeTask.cs ├── PyramidMazeTask.cs └── SnakeMazeTask.cs ├── 4. Массивы ├── HeatmapTask.cs └── HistogramTask.cs ├── 5. Коллекции, строки, файлы ├── BigramGeneratorTask.cs ├── FrequencyAnalysisTask.cs └── SentencesParserTask.cs ├── 7. Сложность алгоритмов ├── GrayscaleTask.cs ├── MedianFilterTask.cs ├── SobelFilterTask.cs └── ThresholdFilterTask.cs ├── 8. Рекурсивные алгоритмы ├── CaseAlternatorTask.cs └── PathFinderTask.cs ├── 9. Поиск и сортировка ├── AutocompleteTests.cs ├── LeftBorderTask.cs └── RightBorderTask.cs └── README.md /1. Ошибки/AngryBirdsTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AngryBirds 4 | { 5 | public static class AngryBirdsTask 6 | { 7 | public static double FindSightAngle(double v, double distance) 8 | { 9 | return Math.Asin((9.8 * distance) / (v * v)) / 2; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /1. Ошибки/BilliardsTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Billiards 4 | { 5 | public static class BilliardsTask 6 | { 7 | public static double BounceWall(double directionRadians, double wallInclinationRadians) 8 | { 9 | //TODO 10 | return (2 * wallInclinationRadians) - directionRadians; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /1. Ошибки/Procent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ConsoleApp 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | string userInput = Console.ReadLine(); 14 | double userOutput = Calculate(userInput); 15 | 16 | Console.WriteLine(userOutput); 17 | Console.ReadLine(); 18 | } 19 | 20 | public static double Calculate(string userInput) 21 | { 22 | double sum = double.Parse(userInput.Split(' ')[0]); 23 | double rate = double.Parse(userInput.Split(' ')[1]) / 100; 24 | int t = int.Parse(userInput.Split(' ')[2]); 25 | 26 | for (int i = 1; i <= t; i++) 27 | { 28 | sum += sum * rate / 12; 29 | } 30 | return sum; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /11. Основы ООП/Segment.cs: -------------------------------------------------------------------------------- 1 | using GeometryTasks; 2 | using System.Drawing; 3 | using System.Collections.Generic; 4 | 5 | namespace GeometryPainting 6 | { 7 | public static class SegmentExtensions 8 | { 9 | public static Dictionary colors = new Dictionary(); 10 | 11 | public static void SetColor(this Segment segment, Color colorValue) 12 | { 13 | if (colors.Count > 0 && colorValue != null) 14 | { 15 | if (colors.ContainsKey(segment)) 16 | { 17 | colors.Remove(segment); 18 | } 19 | colors.Add(segment, colorValue); 20 | } 21 | 22 | else if (colorValue != null) colors.Add(segment, colorValue); 23 | } 24 | 25 | public static Color GetColor(this Segment segment) 26 | { 27 | if (segment != null) 28 | { 29 | Color val; 30 | if (colors.TryGetValue(segment, out val)) return colors[segment]; 31 | } 32 | return Color.Black; 33 | } 34 | 35 | public static bool Contains(Segment segment, Color colorValue) 36 | { 37 | foreach (var key in colors.Keys) 38 | { 39 | if (Equal(key, segment)) 40 | { 41 | if (colors[key] != colorValue) return true; 42 | } 43 | return false; 44 | } 45 | return false; 46 | } 47 | 48 | public static bool Equal(Segment segment1, Segment segment2) 49 | { 50 | if (segment1.Begin != null && 51 | segment2.Begin != null && 52 | segment1.End != null && 53 | segment2.End != null) 54 | { 55 | if (segment1.Begin.X == segment2.Begin.X && 56 | segment1.Begin.Y == segment2.Begin.Y && 57 | segment1.End.X == segment2.End.X && 58 | segment1.End.Y == segment2.End.Y) return true; 59 | } 60 | return false; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /11. Основы ООП/VectorTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | 6 | namespace GeometryTasks 7 | { 8 | public class Segment 9 | { 10 | public Vector Begin; 11 | public Vector End; 12 | 13 | public static double GetLength(Vector vector) 14 | { 15 | return Geometry.GetLength(vector); 16 | } 17 | 18 | public bool Contains(Vector vector) 19 | { 20 | return Geometry.IsVectorInSegment(vector, this); 21 | } 22 | } 23 | 24 | public class Vector 25 | { 26 | public double X; 27 | public double Y; 28 | 29 | public Vector() 30 | { 31 | X = 0; 32 | Y = 0; 33 | } 34 | 35 | public Vector(double x, double y) 36 | { 37 | X = x; 38 | Y = y; 39 | } 40 | 41 | 42 | public double GetLength() 43 | { 44 | return Geometry.GetLength(this); 45 | } 46 | 47 | 48 | public Vector Add(Vector vector) 49 | { 50 | return Geometry.Add(vector, this); 51 | } 52 | 53 | 54 | public bool Belongs(Segment segment) 55 | { 56 | return Geometry.IsVectorInSegment(this, segment); 57 | } 58 | } 59 | 60 | 61 | public static class Geometry 62 | { 63 | public static double GetLength(Vector vector) 64 | { 65 | return Math.Sqrt(Math.Pow(vector.X, 2) + 66 | Math.Pow(vector.Y, 2)); 67 | } 68 | 69 | 70 | public static double GetLength(Segment segment) 71 | { 72 | return Math.Sqrt(Math.Pow(segment.End.X - 73 | segment.Begin.X, 2) + 74 | Math.Pow(segment.End.Y - 75 | segment.Begin.Y, 2)); 76 | } 77 | 78 | 79 | public static Vector Add(Vector vector1, Vector vector2) 80 | { 81 | return new Vector { 82 | X = vector1.X + vector2.X, Y = 83 | vector1.Y + vector2.Y }; 84 | } 85 | 86 | 87 | public static bool IsVectorInSegment(Vector vector, Segment segment) 88 | { 89 | var segmentLength = Geometry.GetLength(segment); 90 | var length1 = Math.Sqrt(Math.Pow(vector.X - 91 | segment.Begin.X, 2) + 92 | Math.Pow(vector.Y - 93 | segment.Begin.Y, 2)); 94 | var length2 = Math.Sqrt(Math.Pow(vector.X - 95 | segment.End.X, 2) + 96 | Math.Pow(vector.Y - 97 | segment.End.Y, 2)); 98 | return AlmostEqual((length2 + length1), segmentLength); 99 | } 100 | 101 | public static bool AlmostEqual(double a, double b) 102 | { 103 | const double epsilon = 0.1; 104 | return Math.Abs(a - b) < epsilon; 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /12. Наследование/DiggerTask1.cs: -------------------------------------------------------------------------------- 1 | // Вставьте сюда финальное содержимое файла DiggerTask.cs 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Digger 9 | { 10 | //Напишите здесь классы Player, Terrain и другие. 11 | public class Terrain : ICreature 12 | { 13 | public CreatureCommand Act(int x, int y) 14 | { 15 | return new CreatureCommand() { DeltaX = 0, DeltaY = 0 }; 16 | } 17 | 18 | public bool DeadInConflict(ICreature conflictedObject) 19 | { 20 | return true; 21 | } 22 | 23 | public int GetDrawingPriority() 24 | { 25 | return 2; 26 | } 27 | 28 | public string GetImageFileName() 29 | { 30 | return "Terrain.png"; 31 | } 32 | } 33 | 34 | 35 | public class Player : ICreature 36 | { 37 | //Координатные поля 38 | public static int X, Y = 0; 39 | public static int dX, dY = 0; 40 | 41 | public CreatureCommand Act(int x, int y) 42 | { 43 | X = x; 44 | Y = y; 45 | //Обработка нажатия клавиш присвоение значений дельтам 46 | switch (Game.KeyPressed) 47 | { 48 | case System.Windows.Forms.Keys.Left: 49 | dY = 0; 50 | dX = -1; 51 | break; 52 | case System.Windows.Forms.Keys.Up: 53 | dY = -1; 54 | dX = 0; 55 | break; 56 | case System.Windows.Forms.Keys.Right: 57 | dY = 0; 58 | dX = 1; 59 | break; 60 | case System.Windows.Forms.Keys.Down: 61 | dY = 1; 62 | dX = 0; 63 | break; 64 | default: 65 | Stay(); 66 | break; 67 | } 68 | //Запрет выхода за пределы карты 69 | if (!(x + dX >= 0 && x + dX < Game.MapWidth && 70 | y + dY >= 0 && y + dY < Game.MapHeight)) 71 | Stay(); 72 | //возвращение следующих координат отрисовки 73 | return new CreatureCommand() { DeltaX = dX, DeltaY = dY }; 74 | } 75 | 76 | public bool DeadInConflict(ICreature conflictedObject) 77 | { 78 | var neighbor = conflictedObject.ToString(); 79 | if (neighbor == "Digger.Gold") 80 | Game.Scores += 10; 81 | if (neighbor == "Digger.Sack"|| 82 | neighbor == "Digger.Monster") 83 | { 84 | 85 | return true; 86 | } 87 | return false; 88 | } 89 | 90 | public int GetDrawingPriority() 91 | { 92 | return 1; 93 | } 94 | 95 | public string GetImageFileName() 96 | { 97 | return "Digger.png"; 98 | } 99 | 100 | private static void Stay() 101 | { 102 | dX = 0; 103 | dY = 0; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /12. Наследование/DiggerTask23.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Digger 8 | { 9 | public class Terrain : ICreature 10 | { 11 | public CreatureCommand Act(int x, int y) 12 | { 13 | return new CreatureCommand() { DeltaX = 0, DeltaY = 0 }; 14 | } 15 | 16 | public bool DeadInConflict(ICreature conflictedObject) 17 | { 18 | return true; 19 | } 20 | 21 | public int GetDrawingPriority() 22 | { 23 | return 2; 24 | } 25 | 26 | public string GetImageFileName() 27 | { 28 | return "Terrain.png"; 29 | } 30 | } 31 | 32 | public class Player : ICreature 33 | { 34 | public static int X, Y = 0; 35 | public static int dX, dY = 0; 36 | 37 | public CreatureCommand Act(int x, int y) 38 | { 39 | X = x; 40 | Y = y; 41 | 42 | switch (Game.KeyPressed) 43 | { 44 | case System.Windows.Forms.Keys.Left: 45 | dY = 0; 46 | dX = -1; 47 | break; 48 | 49 | case System.Windows.Forms.Keys.Up: 50 | dY = -1; 51 | dX = 0; 52 | break; 53 | 54 | case System.Windows.Forms.Keys.Right: 55 | dY = 0; 56 | dX = 1; 57 | break; 58 | 59 | case System.Windows.Forms.Keys.Down: 60 | dY = 1; 61 | dX = 0; 62 | break; 63 | 64 | default: 65 | Stay(); 66 | break; 67 | } 68 | 69 | if (!(x + dX >= 0 && x + dX < Game.MapWidth && 70 | y + dY >= 0 && y + dY < Game.MapHeight)) 71 | Stay(); 72 | 73 | if (Game.Map[x + dX, y + dY] != null) 74 | { 75 | if (Game.Map[x + dX, y + dY].ToString() == "Digger.Sack") 76 | Stay(); 77 | } 78 | 79 | return new CreatureCommand() { DeltaX = dX, DeltaY = dY }; 80 | } 81 | 82 | public bool DeadInConflict(ICreature conflictedObject) 83 | { 84 | var neighbor = conflictedObject.ToString(); 85 | if (neighbor == "Digger.Gold") 86 | Game.Scores += 10; 87 | if (neighbor == "Digger.Sack" || 88 | neighbor == "Digger.Monster") 89 | { 90 | 91 | return true; 92 | } 93 | return false; 94 | } 95 | 96 | public int GetDrawingPriority() 97 | { 98 | return 1; 99 | } 100 | 101 | public string GetImageFileName() 102 | { 103 | return "Digger.png"; 104 | } 105 | 106 | private static void Stay() 107 | { 108 | dX = 0; 109 | dY = 0; 110 | } 111 | } 112 | 113 | 114 | public class Sack : ICreature 115 | { 116 | private int counter = 0; 117 | public static bool deadlyForPlayer = false; 118 | 119 | public CreatureCommand Act(int x, int y) 120 | { 121 | if (y < Game.MapHeight - 1) 122 | { 123 | var map = Game.Map[x, y + 1]; 124 | if (map == null || 125 | (counter > 0 && (map.ToString() == "Digger.Player" || 126 | map.ToString() == "Digger.Monster"))) 127 | { 128 | counter++; 129 | return Fall(); 130 | } 131 | } 132 | 133 | if (counter > 1) 134 | { 135 | counter = 0; 136 | return new CreatureCommand() { DeltaX = 0, DeltaY = 0, TransformTo = new Gold() }; 137 | } 138 | counter = 0; 139 | return DoNothing(); 140 | } 141 | 142 | 143 | public bool DeadInConflict(ICreature conflictedObject) 144 | { 145 | return false; 146 | } 147 | 148 | public int GetDrawingPriority() 149 | { 150 | return 5; 151 | } 152 | 153 | public string GetImageFileName() 154 | { 155 | return "Sack.png"; 156 | } 157 | 158 | private CreatureCommand Fall() 159 | { 160 | return new CreatureCommand() { DeltaX = 0, DeltaY = 1 }; 161 | } 162 | 163 | private CreatureCommand DoNothing() 164 | { 165 | return new CreatureCommand() { DeltaX = 0, DeltaY = 0 }; 166 | } 167 | } 168 | 169 | public class Gold : ICreature 170 | { 171 | public CreatureCommand Act(int x, int y) 172 | { 173 | return new CreatureCommand() { DeltaX = 0, DeltaY = 0 }; 174 | } 175 | 176 | public bool DeadInConflict(ICreature conflictedObject) 177 | { 178 | var neighbor = conflictedObject.ToString(); 179 | return (neighbor == "Digger.Player" || 180 | neighbor == "Digger.Monster"); 181 | } 182 | 183 | public int GetDrawingPriority() 184 | { 185 | return 3; 186 | } 187 | 188 | public string GetImageFileName() 189 | { 190 | return "Gold.png"; 191 | } 192 | } 193 | 194 | 195 | public class Monster : ICreature 196 | { 197 | 198 | public CreatureCommand Act(int x, int y) 199 | { 200 | int dx = 0; 201 | int dy = 0; 202 | 203 | if (IsPlayerAlive()) 204 | { 205 | if (Player.X == x) 206 | { 207 | if (Player.Y < y) dy = -1; 208 | else if (Player.Y > y) dy = 1; 209 | } 210 | 211 | else if (Player.Y == y) 212 | { 213 | if (Player.X < x) dx = -1; 214 | else if (Player.X > x) dx = 1; 215 | } 216 | else 217 | { 218 | if (Player.X < x) dx = -1; 219 | else if (Player.X > x) dx = 1; 220 | } 221 | } 222 | else return Stay(); 223 | 224 | if (!(x + dx >= 0 && x + dx < Game.MapWidth && 225 | y + dy >= 0 && y + dy < Game.MapHeight)) 226 | return Stay(); 227 | 228 | var map = Game.Map[x + dx, y + dy]; 229 | if (map != null) 230 | if (map.ToString() == "Digger.Terrain" || 231 | map.ToString() == "Digger.Sack" || 232 | map.ToString() == "Digger.Monster") 233 | return Stay(); 234 | return new CreatureCommand() { DeltaX = dx, DeltaY = dy }; 235 | } 236 | 237 | public bool DeadInConflict(ICreature conflictedObject) 238 | { 239 | var neighbor = conflictedObject.ToString(); 240 | return (neighbor == "Digger.Sack" || 241 | neighbor == "Digger.Monster"); 242 | } 243 | 244 | public int GetDrawingPriority() 245 | { 246 | return 0; 247 | } 248 | 249 | public string GetImageFileName() 250 | { 251 | return "Monster.png"; 252 | } 253 | 254 | static private CreatureCommand Stay() 255 | { 256 | 257 | return new CreatureCommand() { DeltaX = 0, DeltaY = 0 }; 258 | } 259 | 260 | 261 | static private bool IsPlayerAlive() 262 | { 263 | for (int i = 0; i < Game.MapWidth; i++) 264 | for (int j = 0; j < Game.MapHeight; j++) 265 | { 266 | var map = Game.Map[i, j]; 267 | if (map != null) 268 | { 269 | if (map.ToString() == "Digger.Player") 270 | { 271 | Player.X = i; 272 | Player.Y = j; 273 | return true; 274 | } 275 | } 276 | } 277 | return false; 278 | } 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /13. Целостность данных/AccountingModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | 8 | namespace HotelAccounting 9 | { 10 | //создайте класс AccountingModel здесь 11 | class AccountingModel : ModelBase 12 | { 13 | private double price; 14 | private int nightsCount; 15 | private double discount; 16 | private double total; 17 | 18 | public double Price 19 | { 20 | get { return price; } 21 | set 22 | { 23 | if (value >= 0) price = value; 24 | else throw new ArgumentException(); 25 | SetNewTotal(); 26 | Notify(nameof(Price)); 27 | } 28 | } 29 | 30 | public int NightsCount 31 | { 32 | get { return nightsCount; } 33 | set 34 | { 35 | if (value > 0) nightsCount = value; 36 | else throw new ArgumentException(); 37 | SetNewTotal(); 38 | Notify(nameof(NightsCount)); 39 | } 40 | } 41 | 42 | public double Discount 43 | { 44 | get { return discount; } 45 | set 46 | { 47 | discount = value; 48 | if (discount != ((-1) * Total / (Price * NightsCount) + 1) * 100) 49 | SetNewTotal(); 50 | Notify(nameof(Discount)); 51 | } 52 | } 53 | 54 | public double Total 55 | { 56 | get { return total; } 57 | set 58 | { 59 | if (value > 0) total = value; 60 | else throw new ArgumentException(); 61 | if (total != Price * NightsCount * (1 - Discount / 100)) 62 | SetNewDiscount(); 63 | Notify(nameof(Total)); 64 | } 65 | } 66 | 67 | public AccountingModel() 68 | { 69 | price = 0; 70 | nightsCount = 1; 71 | discount = 0; 72 | total = 0; 73 | } 74 | 75 | private void SetNewTotal() 76 | { 77 | Total = Price * NightsCount * (1 - Discount / 100); 78 | } 79 | 80 | private void SetNewDiscount() 81 | { 82 | //Total = Price * NightsCount * (1 - Discount / 100); 83 | Discount = ((-1) * Total / (Price * NightsCount) + 1) * 100; 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /13. Целостность данных/Indexer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace PocketGoogle 5 | { 6 | public class Indexer : IIndexer 7 | { 8 | private char[] _wordsSplitter = new char[] {' ', '.', ',', '!', '?', ':', '-', '\r', '\n'}; 9 | private Dictionary>> _words; 10 | 11 | public void Add(int id, string documentText) 12 | { 13 | var document = documentText.Split(_wordsSplitter, StringSplitOptions.RemoveEmptyEntries); 14 | foreach (var word in document) 15 | { 16 | if (!_words.ContainsKey(word)) 17 | { 18 | _words.Add(word, new Dictionary>()); 19 | _words[word].Add(id, _getWordPositions(word, documentText)); 20 | } 21 | else if (!_words[word].ContainsKey(id)) 22 | { 23 | _words[word].Add(id, _getWordPositions(word, documentText)); 24 | } 25 | } 26 | } 27 | 28 | private int[] _prefixFunction(string pattern) 29 | { 30 | var len = pattern.Length; 31 | var prefixLens = new int[len]; 32 | prefixLens[0] = 0; 33 | for (var i = 1; i < len; i++) 34 | { 35 | var j = prefixLens[i - 1]; 36 | while ((j > 0) && (pattern[i] != pattern[j])) 37 | j = prefixLens[j - 1]; 38 | if (pattern[i] == pattern[j]) 39 | j++; 40 | prefixLens[i] = j; 41 | } 42 | 43 | return prefixLens; 44 | } 45 | 46 | private List _getWordPositions(string word, string text) 47 | { 48 | var result = new List(); 49 | var sample = _prefixFunction(word); 50 | var len = word.Length; 51 | var j = 0; 52 | for (var i = 0; i < text.Length; i++) 53 | { 54 | if (j == len) 55 | j = len-1; 56 | while ((j > 0) && (text[i] != word[j])) 57 | j = sample[j - 1]; 58 | if (text[i] == word[j]) 59 | j++; 60 | if (j == len) 61 | result.Add(i-len+1); 62 | } 63 | return result; 64 | } 65 | 66 | public List GetIds(string word) 67 | { 68 | if (_words.ContainsKey(word)) return new List(_words[word].Keys); 69 | return new List(); 70 | } 71 | 72 | public List GetPositions(int id, string word) 73 | { 74 | if (_words.ContainsKey(word)) 75 | if (_words[word].ContainsKey(id)) 76 | return _words[word][id]; 77 | return new List(); 78 | } 79 | 80 | public void Remove(int id) 81 | { 82 | foreach (var word in _words.Keys) 83 | { 84 | if (_words[word].ContainsKey(id)) 85 | _words[word].Remove(id); 86 | } 87 | } 88 | 89 | public Indexer() 90 | { 91 | _words = new Dictionary>>(); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /13. Целостность данных/ReadOnlyVector.cs: -------------------------------------------------------------------------------- 1 | namespace ReadOnlyVectorTask 2 | { 3 | public class ReadOnlyVector 4 | { 5 | public readonly double X; 6 | public readonly double Y; 7 | 8 | public ReadOnlyVector(double x, double y) 9 | { 10 | X = x; 11 | Y = y; 12 | } 13 | 14 | public ReadOnlyVector Add(ReadOnlyVector other) 15 | { 16 | return new ReadOnlyVector(X + other.X, Y + other.Y); 17 | } 18 | 19 | public ReadOnlyVector WithX(double x) 20 | { 21 | return new ReadOnlyVector(x, Y); 22 | } 23 | 24 | public ReadOnlyVector WithY(double y) 25 | { 26 | return new ReadOnlyVector(X, y); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /14. Структуры/ChartBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | using System.Windows.Forms.DataVisualization.Charting; 5 | 6 | namespace Profiling 7 | { 8 | public class ChartBuilder : IChartBuilder 9 | { 10 | public Control Build(List results) 11 | { 12 | var chart = GetChartBase(results.Count + 1); 13 | var position = 1; 14 | var elementsAmount = 1; 15 | foreach (var result in results) 16 | { 17 | chart.Series["ClassResult"].Points.AddXY(position, result.ClassResult); 18 | chart.Series["StructResult"].Points.AddXY(position, result.StructResult); 19 | chart.ChartAreas["main"].AxisX.CustomLabels.Add(new CustomLabel 20 | { 21 | FromPosition = position - 0.5, 22 | ToPosition = position + 0.5, 23 | Text = elementsAmount.ToString() 24 | }); 25 | elementsAmount *= 2; 26 | position++; 27 | } 28 | chart.Legends.Add("Legend"); 29 | chart.Legends["Legend"].BorderColor = Color.Black; 30 | return chart; 31 | } 32 | 33 | private Chart GetChartBase(int axisXMax) 34 | { 35 | var chart = new Chart { Palette = ChartColorPalette.Pastel }; 36 | chart.Titles.Add("Время работы, мс"); 37 | chart.ChartAreas.Add("main"); 38 | chart.ChartAreas["main"].AxisX.Maximum = axisXMax; 39 | chart.Series.Add("ClassResult"); 40 | chart.Series["ClassResult"].ChartType = SeriesChartType.Column; 41 | chart.Series["ClassResult"].Color = Color.Green; 42 | chart.Series["ClassResult"].LegendText = "Класс"; 43 | chart.Series.Add("StructResult"); 44 | chart.Series["StructResult"].ChartType = SeriesChartType.Column; 45 | chart.Series["StructResult"].Color = Color.Blue; 46 | chart.Series["StructResult"].LegendText = "Структура"; 47 | return chart; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /14. Структуры/Generator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Profiling 8 | { 9 | class Generator 10 | { 11 | public static string GenerateDeclarations() 12 | { 13 | var builder = new StringBuilder(); 14 | foreach (var fieldCount in Constants.FieldCounts) 15 | { 16 | builder.Append( 17 | GetElementString(fieldCount, "struct S") + 18 | GetElementString(fieldCount, "class C")); 19 | } 20 | return builder.ToString(); 21 | } 22 | 23 | private static string GetElementString(int fieldsAmount, string elementName) 24 | { 25 | return "\n" + elementName + fieldsAmount + 26 | "\n{\n" + 27 | GetByteFields(fieldsAmount) + 28 | "\n}"; 29 | } 30 | 31 | private static string GetByteFields(int fieldsAmount) 32 | { 33 | var result = ""; 34 | for (var i = 0; i < fieldsAmount; i++) 35 | result += (i == 0 ? "" : " ") + "byte Value" + i + ";"; 36 | return result; 37 | } 38 | 39 | 40 | public static string GenerateArrayRunner() 41 | { 42 | var builder = new StringBuilder("public class ArrayRunner : IRunner\r\n{"); 43 | foreach (var fieldCount in Constants.FieldCounts) 44 | { 45 | var fc = fieldCount.ToString(); 46 | builder.Append( 47 | "void PC" + fc + "()\r\n" + 48 | "{\r\n" + 49 | "var array = new C" + fc + "[Constants.ArraySize];\r\n" + 50 | "for (int i = 0; i < Constants.ArraySize; i++) array[i] = new C" + fc + "();\r\n" + 51 | "}\r\n" + 52 | "void PS" + fc + "()\r\n" + 53 | "{\r\n" + 54 | "var array = new S" + fc + "[Constants.ArraySize];\r\n" + 55 | "}\r\n" 56 | ); 57 | } 58 | builder.Append(GenerateCallArrayMethod()); 59 | return builder.ToString(); 60 | } 61 | 62 | public static string GenerateCallArrayMethod() 63 | { 64 | var builder= new StringBuilder("public void Call(bool isClass, int size, int count)\r\n{"); 65 | foreach (var fieldCount in Constants.FieldCounts) 66 | { 67 | var fc = fieldCount.ToString(); 68 | builder.Append( 69 | "if (isClass && size == " + fc + ")\r\n" + 70 | "{\r\n" + 71 | "for (int i = 0; i < count; i++) PC" + fc + "();\r\n" + 72 | "return;\r\n" + 73 | "}\r\n" + 74 | "if (!isClass && size == " + fc + ")\r\n" + 75 | "{\r\n" + 76 | "for (int i = 0; i < count; i++) PS" + fc + "();\r\n" + 77 | "return;\r\n" + 78 | "}\r\n" 79 | ); 80 | } 81 | builder.Append("throw new ArgumentException();\r\n}\r\n}"); 82 | return builder.ToString(); 83 | } 84 | 85 | public static string GenerateCallRunner() 86 | { 87 | var builder = new StringBuilder("public class CallRunner : IRunner\r\n{"); 88 | FillWithMethods(builder); 89 | GenerateCallRunnerMethod(builder); 90 | return builder.ToString(); 91 | } 92 | 93 | private static void FillWithMethods(StringBuilder builder) 94 | { 95 | foreach (var fieldCount in Constants.FieldCounts) 96 | { 97 | var fc = fieldCount.ToString(); 98 | builder.Append("void PC" + fc + "(C" + fc + " o) { }\r\n" + 99 | "void PS" + fc + "(S" + fc + " o) { }"); 100 | } 101 | } 102 | 103 | private static void GenerateCallRunnerMethod(StringBuilder builder) 104 | { 105 | builder.Append("public void Call(bool isClass, int size, int count)\r\n{"); 106 | foreach (var fieldCount in Constants.FieldCounts) 107 | { 108 | var fc = fieldCount.ToString(); 109 | builder.Append( 110 | " if (isClass && size == " + fc + ")\r\n" + 111 | "{\r\n" + 112 | "var o = new C" + fc + "(); for (int i = 0; i < count; i++) PC" + fc + "(o);\r\n" + 113 | "return;\r\n" + 114 | "}\r\n" + 115 | "if (!isClass && size == " + fc + ")\r\n" + 116 | "{\r\n" + 117 | "var o = new S" + fc + "(); for (int i = 0; i < count; i++) PS" + fc + "(o);\r\n" + 118 | "return;\r\n}" 119 | ); 120 | } 121 | builder.Append("throw new ArgumentException();\r\n}\r\n}"); 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /14. Структуры/GeneratorFinal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Profiling 8 | { 9 | class Generator 10 | { 11 | public static string GenerateDeclarations() 12 | { 13 | var builder = new StringBuilder(); 14 | foreach (var fieldCount in Constants.FieldCounts) 15 | { 16 | builder.Append( 17 | GetElementString(fieldCount, "struct S") + 18 | GetElementString(fieldCount, "class C")); 19 | } 20 | return builder.ToString(); 21 | } 22 | 23 | private static string GetElementString(int fieldsAmount, string elementName) 24 | { 25 | return "\n" + elementName + fieldsAmount + 26 | "\n{\n" + 27 | GetByteFields(fieldsAmount) + 28 | "\n}"; 29 | } 30 | 31 | private static string GetByteFields(int fieldsAmount) 32 | { 33 | var result = ""; 34 | for (var i = 0; i < fieldsAmount; i++) 35 | result += (i == 0 ? "" : " ") + "byte Value" + i + ";"; 36 | return result; 37 | } 38 | 39 | 40 | 41 | public static string GenerateArrayRunner() 42 | { 43 | var builder = new StringBuilder("public class ArrayRunner : IRunner\r\n{"); 44 | foreach (var fieldCount in Constants.FieldCounts) 45 | { 46 | var fc = fieldCount.ToString(); 47 | builder.Append( 48 | "void PC" + fc + "()\r\n" + 49 | "{\r\n" + 50 | "var array = new C" + fc + "[Constants.ArraySize];\r\n" + 51 | "for (int i = 0; i < Constants.ArraySize; i++) array[i] = new C" + fc + "();\r\n" + 52 | "}\r\n" + 53 | "void PS" + fc + "()\r\n" + 54 | "{\r\n" + 55 | "var array = new S" + fc + "[Constants.ArraySize];\r\n" + 56 | "}\r\n" 57 | ); 58 | } 59 | builder.Append(GenerateCallArrayMethod()); 60 | return builder.ToString(); 61 | } 62 | 63 | public static string GenerateCallArrayMethod() 64 | { 65 | var builder= new StringBuilder("public void Call(bool isClass, int size, int count)\r\n{"); 66 | foreach (var fieldCount in Constants.FieldCounts) 67 | { 68 | var fc = fieldCount.ToString(); 69 | builder.Append( 70 | "if (isClass && size == " + fc + ")\r\n" + 71 | "{\r\n" + 72 | "for (int i = 0; i < count; i++) PC" + fc + "();\r\n" + 73 | "return;\r\n" + 74 | "}\r\n" + 75 | "if (!isClass && size == " + fc + ")\r\n" + 76 | "{\r\n" + 77 | "for (int i = 0; i < count; i++) PS" + fc + "();\r\n" + 78 | "return;\r\n" + 79 | "}\r\n" 80 | ); 81 | } 82 | builder.Append("throw new ArgumentException();\r\n}\r\n}"); 83 | return builder.ToString(); 84 | } 85 | 86 | public static string GenerateCallRunner() 87 | { 88 | var builder = new StringBuilder("public class CallRunner : IRunner\r\n{"); 89 | FillWithMethods(builder); 90 | GenerateCallRunnerMethod(builder); 91 | return builder.ToString(); 92 | } 93 | 94 | private static void FillWithMethods(StringBuilder builder) 95 | { 96 | foreach (var fieldCount in Constants.FieldCounts) 97 | { 98 | var fc = fieldCount.ToString(); 99 | builder.Append("void PC" + fc + "(C" + fc + " o) { }\r\n" + 100 | "void PS" + fc + "(S" + fc + " o) { }"); 101 | } 102 | } 103 | 104 | private static void GenerateCallRunnerMethod(StringBuilder builder) 105 | { 106 | builder.Append("public void Call(bool isClass, int size, int count)\r\n{"); 107 | foreach (var fieldCount in Constants.FieldCounts) 108 | { 109 | var fc = fieldCount.ToString(); 110 | builder.Append( 111 | " if (isClass && size == " + fc + ")\r\n" + 112 | "{\r\n" + 113 | "var o = new C" + fc + "(); for (int i = 0; i < count; i++) PC" + fc + "(o);\r\n" + 114 | "return;\r\n" + 115 | "}\r\n" + 116 | "if (!isClass && size == " + fc + ")\r\n" + 117 | "{\r\n" + 118 | "var o = new S" + fc + "(); for (int i = 0; i < count; i++) PS" + fc + "(o);\r\n" + 119 | "return;\r\n}" 120 | ); 121 | } 122 | builder.Append("throw new ArgumentException();\r\n}\r\n}"); 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /14. Структуры/ProfilerTask.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | 4 | namespace Profiling 5 | { 6 | public class ProfilerTask : IProfiler 7 | { 8 | public List Measure(IRunner runner, int repetitionsCount) 9 | { 10 | var results = new List(); 11 | foreach (var fieldCount in Constants.FieldCounts) 12 | { 13 | var cTime = GetCallTime(true, runner, repetitionsCount, fieldCount); 14 | var sTime = GetCallTime(false,runner, repetitionsCount, fieldCount); 15 | results.Add(new ExperimentResult(fieldCount, 16 | (double)cTime/repetitionsCount, 17 | (double)sTime/repetitionsCount)); 18 | } 19 | return results; 20 | } 21 | 22 | private static long GetCallTime(bool isClass,IRunner runner, int repetitionsCount, int fieldCount) 23 | { 24 | runner.Call(isClass, fieldCount, 1); 25 | var sStopwatch = Stopwatch.StartNew(); 26 | runner.Call(isClass, fieldCount, repetitionsCount); 27 | return sStopwatch.ElapsedMilliseconds; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /2. Ветвления/DistaceTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DistanceTask 4 | { 5 | public static class DistanceTask 6 | { 7 | public static double GetDistanceToSegment(double ax, double ay, double bx, double by, double x, double y) 8 | { 9 | if (ax == bx && ay == by) 10 | { 11 | return Math.Sqrt((x - ax) * (x - ax) + (y - ay) * (y - ay)); 12 | } 13 | else if (((x - ax) * (bx - ax) + (y - ay) * (by - ay)) < 0 || 14 | ((x - bx) * (ax - bx) + (y - by) * (ay - by)) < 0) 15 | { 16 | return Math.Min(Math.Sqrt((x - ax) * (x - ax) + (y - ay) * (y - ay)), 17 | Math.Sqrt((x - bx) * (x - bx) + (y - by) * (y - by))); 18 | } 19 | else 20 | { 21 | return Math.Abs((bx - ax) * (y - ay) - (by - ay) * (x - ax)) / 22 | Math.Sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay)); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2. Ветвления/PluralizeTask.cs: -------------------------------------------------------------------------------- 1 | namespace Pluralize 2 | { 3 | public static class PluralizeTask 4 | { 5 | public static string PluralizeRubles(int count) 6 | { 7 | if (count < 10 || count > 20 && count < 100) 8 | { 9 | int rem = count % 10; 10 | return (rem > 1 && rem < 5) ? "рубля" : ((rem > 4 || rem == 0) ? "рублей" : "рубль"); 11 | } 12 | else 13 | { 14 | while (true) 15 | { 16 | count %= 100; 17 | if (count < 100) break; 18 | } 19 | 20 | if (count < 10 || count > 20 && count < 100) 21 | { 22 | int rem = count % 10; 23 | return (rem > 1 && rem < 5) ? "рубля" : ((rem > 4 || rem == 0) ? "рублей" : "рубль"); 24 | } 25 | else 26 | return "рублей"; 27 | } 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /2. Ветвления/RectanglesTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Rectangles 4 | { 5 | public static class RectanglesTask 6 | { 7 | // Пересекаются ли два прямоугольника (пересечение только по границе также считается пересечением) 8 | public static bool AreIntersected(Rectangle r1, Rectangle r2) 9 | { 10 | return Math.Min(r1.Right, r2.Right) >= Math.Max(r1.Left, r2.Left) && 11 | Math.Min(r1.Bottom, r2.Bottom) >= Math.Max(r1.Top, r2.Top); 12 | } 13 | 14 | public static int IntersectionSquare(Rectangle r1, Rectangle r2) 15 | { 16 | return AreIntersected(r1, r2) ? (Math.Min(r1.Right, r2.Right) - Math.Max(r1.Left, r2.Left)) * 17 | (Math.Min(r1.Bottom, r2.Bottom) - Math.Max(r1.Top, r2.Top)) 18 | : 0; 19 | } 20 | 21 | 22 | public static int IndexOfInnerRectangle(Rectangle r1, Rectangle r2) 23 | { 24 | if (r1.Left >= r2.Left && r1.Right <= r2.Right && r1.Top >= r2.Top && r1.Bottom <= r2.Bottom) 25 | return 0; 26 | else if (r1.Left <= r2.Left && r1.Right >= r2.Right && r1.Top <= r2.Top && r1.Bottom >= r2.Bottom) 27 | return 1; 28 | else 29 | return -1; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /3. Циклы/DiagonalMazeTask.cs: -------------------------------------------------------------------------------- 1 | namespace Mazes 2 | { 3 | public static class DiagonalMazeTask 4 | { 5 | public static void MoveOut(Robot robot, int width, int height) 6 | { 7 | if (height > width) 8 | { 9 | MoveOnY(robot, width, height); 10 | } 11 | else 12 | MoveOnX(robot, width, height); 13 | } 14 | 15 | public static void MoveOnY(Robot robot, int width, int height) 16 | { 17 | while (!robot.Finished) 18 | { 19 | for (int i = 0; i < (height - 3) / (width - 3 + 1); i++) 20 | { 21 | robot.MoveTo(Direction.Down); 22 | } 23 | if (!robot.Finished) 24 | robot.MoveTo(Direction.Right); 25 | } 26 | } 27 | 28 | public static void MoveOnX(Robot robot, int width, int height) 29 | { 30 | while (!robot.Finished) 31 | { 32 | for (int i = 0; i < (width - 3) / (height - 3 + 1); i++) 33 | { 34 | robot.MoveTo(Direction.Right); 35 | } 36 | if (!robot.Finished) 37 | robot.MoveTo(Direction.Down); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /3. Циклы/DragonFractalTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | 5 | namespace Fractals 6 | { 7 | internal static class DragonFractalTask 8 | { 9 | public static double GetXCoord(double x, double y, double angle) 10 | { 11 | return (x * Math.Cos(angle) - y * Math.Sin(angle)) / Math.Sqrt(2); 12 | } 13 | 14 | public static double GetYCoord(double x, double y, double angle) 15 | { 16 | return (x * Math.Sin(angle) + y * Math.Cos(angle)) / Math.Sqrt(2); 17 | } 18 | 19 | public static void DrawDragonFractal(Pixels pixels, int iterationsCount, int seed) 20 | { 21 | var x = 1.0; 22 | var y = 0.0; 23 | var initRandom = new Random(seed); 24 | 25 | for (int i = 0; i < iterationsCount; ++i) 26 | { 27 | var oldX = x; 28 | // Transformation A 29 | if (initRandom.Next(2) == 0) 30 | { 31 | x = GetXCoord(x, y, Math.PI / 4); 32 | y = GetYCoord(oldX, y, Math.PI / 4); 33 | } 34 | // Transformation B 35 | else 36 | { 37 | x = GetXCoord(x, y, Math.PI * 3 / 4) + 1; 38 | y = GetYCoord(oldX, y, Math.PI * 3 / 4); 39 | } 40 | pixels.SetPixel(x, y); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /3. Циклы/EmptyMazeTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | 4 | namespace Mazes 5 | { 6 | public static class EmptyMazeTask 7 | { 8 | public static void MoveOut(Robot robot, int width, int height) 9 | { 10 | MoveRight(robot, width); 11 | MoveDown(robot, height); 12 | } 13 | 14 | private static void MoveRight(Robot robot, int count) 15 | { 16 | for (int i = 0; i < count - 3; i++) 17 | { 18 | robot.MoveTo(Direction.Right); 19 | } 20 | } 21 | 22 | private static void MoveDown(Robot robot, int count) 23 | { 24 | for (int i = 0; i < count - 3; i++) 25 | { 26 | robot.MoveTo(Direction.Down); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /3. Циклы/PyramidMazeTask.cs: -------------------------------------------------------------------------------- 1 | // Вставьте сюда финальное содержимое файла PyramidMazeTask.cs 2 | 3 | namespace Mazes 4 | { 5 | public static class PyramidMazeTask 6 | { 7 | public static int LeftBound = 0; 8 | public static int RightBound = 0; 9 | 10 | public static void MoveOut(Robot robot, int width, int height) 11 | { 12 | LeftBound = 0; 13 | RightBound = 0; 14 | while (robot.Y > 2) 15 | { 16 | MainCondition(robot, width); 17 | if (robot.Y == 2) 18 | break; 19 | } 20 | } 21 | 22 | public static void MainCondition(Robot robot, int width) 23 | { 24 | while (robot.X < width - 2 - RightBound) 25 | robot.MoveTo(Direction.Right); 26 | LeftBound += 2; 27 | 28 | MoveOnYTwoTimes(robot); 29 | MoveOnXMinus(robot); 30 | } 31 | 32 | public static void MoveOnXMinus(Robot robot) 33 | { 34 | while (robot.X > 1 + LeftBound) 35 | robot.MoveTo(Direction.Left); 36 | if (!robot.Finished) 37 | MoveOnYTwoTimes(robot); 38 | RightBound += 2; 39 | } 40 | 41 | public static void MoveOnYTwoTimes(Robot robot) 42 | { 43 | robot.MoveTo(Direction.Up); 44 | robot.MoveTo(Direction.Up); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /3. Циклы/SnakeMazeTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | 4 | namespace Mazes 5 | { 6 | public static class SnakeMazeTask 7 | { 8 | public static void MoveRight(Robot robot, int width, int height) 9 | { 10 | for (int i = 0; i < width - 3; i++) 11 | robot.MoveTo(Direction.Right); 12 | } 13 | 14 | public static void MoveDown(Robot robot, int width, int height) 15 | { 16 | for (int i = 0; i < 2; i++) 17 | robot.MoveTo(Direction.Down); 18 | } 19 | 20 | public static void MoveLeft(Robot robot, int width, int height) 21 | { 22 | for (int i = 0; i < width - 3; i++) 23 | robot.MoveTo(Direction.Left); 24 | } 25 | 26 | public static void MoveOut(Robot robot, int width, int height) 27 | { 28 | MoveRight(robot, width, height); 29 | MoveDown(robot, width, height); 30 | MoveLeft(robot, width, height); 31 | 32 | if (!robot.Finished) 33 | { 34 | MoveDown(robot, width, height); 35 | MoveOut(robot, width, height); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /4. Массивы/HeatmapTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | 4 | namespace Names 5 | { 6 | internal static class HeatmapTask 7 | { 8 | public static HeatmapData GetBirthsPerDateHeatmap(NameData[] names) 9 | { 10 | var minDay = 2; 11 | var maxDay = 31; 12 | var days = new string[maxDay - minDay + 1]; 13 | for (var i = 0; i < days.Length; i++) 14 | days[i] = (i + minDay).ToString(); 15 | var minMonth = 1; 16 | var maxMonth = 12; 17 | var months = new string[maxMonth]; 18 | 19 | for (var i = 0; i < months.Length; i++) 20 | months[i] = (i + minMonth).ToString(); 21 | var birthCounts = new double[days.Length, months.Length]; 22 | 23 | foreach (var name in names) 24 | { 25 | if (name.BirthDate.Day > 1) 26 | birthCounts[(name.BirthDate.Day - minDay), (name.BirthDate.Month - minMonth)]++; 27 | } 28 | 29 | return new HeatmapData("Карта интенсивностей рождаемости", birthCounts, days, months); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /4. Массивы/HistogramTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | 5 | namespace Names 6 | { 7 | internal static class HistogramTask 8 | { 9 | public static HistogramData GetBirthsPerDayHistogram(NameData[] names, string name) 10 | { 11 | var minDay = 1; 12 | var maxDay = int.MinValue; 13 | foreach (var day in names) 14 | maxDay = Math.Max(maxDay, day.BirthDate.Day); 15 | var days = new string[maxDay - minDay + 1]; 16 | 17 | for (var i = 0; i < days.Length; i++) 18 | { 19 | days[i] = (i + minDay).ToString(); 20 | } 21 | 22 | var birthCounts = new double[maxDay - minDay + 1]; 23 | 24 | foreach (var day in names) 25 | { 26 | if (day.Name == name && day.BirthDate.Day > 1) 27 | birthCounts[day.BirthDate.Day - minDay]++; 28 | } 29 | 30 | return new HistogramData(String.Format("Рождаемость людей с именем '{0}'", name), days, birthCounts); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /5. Коллекции, строки, файлы/BigramGeneratorTask.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | 5 | namespace TextAnalysis 6 | { 7 | static class BigramGeneratorTask 8 | { 9 | public static string ContinuePhraseWithBigramms 10 | (Dictionary mostFrequentNextWords, string word, int phraseWordsCount) 11 | { 12 | StringBuilder phrase = new StringBuilder(word); 13 | 14 | for (int i = 1; i < phraseWordsCount; i++) 15 | { 16 | if (!mostFrequentNextWords.ContainsKey(word)) 17 | break; 18 | word = mostFrequentNextWords[word]; 19 | phrase.Append(" " + word); 20 | } 21 | return phrase.ToString(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /5. Коллекции, строки, файлы/FrequencyAnalysisTask.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System; 3 | 4 | 5 | namespace TextAnalysis 6 | { 7 | static class FrequencyAnalysisTask 8 | { 9 | public static Dictionary> FillBigrams(List> text) 10 | { 11 | Dictionary> bigrams = new Dictionary>(); 12 | 13 | foreach (var sentence in text) 14 | { 15 | for (int i = 0; i < sentence.Count - 1; i++) 16 | { 17 | if (!bigrams.ContainsKey(sentence[i])) 18 | bigrams.Add(sentence[i], new Dictionary()); 19 | if (!bigrams[sentence[i]].ContainsKey(sentence[i + 1])) 20 | bigrams[sentence[i]].Add(sentence[i + 1], 1); 21 | else bigrams[sentence[i]][sentence[i + 1]] += 1; 22 | } 23 | } 24 | 25 | return bigrams; 26 | } 27 | 28 | public static Dictionary GetMostFrequentNextWords(List> text) 29 | { 30 | Dictionary> bigrams = FillBigrams(text); 31 | Dictionary mostFrequentBigrams = new Dictionary(); 32 | foreach (var firstWord in bigrams) 33 | { 34 | var maxValue = 0; 35 | string mostFrequentSecondWord = null; 36 | 37 | foreach (var secondWord in firstWord.Value) 38 | { 39 | if (secondWord.Value == maxValue) 40 | if (string.CompareOrdinal(mostFrequentSecondWord, secondWord.Key) > 0) 41 | mostFrequentSecondWord = secondWord.Key; 42 | if (secondWord.Value > maxValue) 43 | { 44 | mostFrequentSecondWord = secondWord.Key; 45 | maxValue = secondWord.Value; 46 | } 47 | } 48 | mostFrequentBigrams.Add(firstWord.Key, mostFrequentSecondWord); 49 | } 50 | 51 | return mostFrequentBigrams; 52 | } 53 | 54 | public static Dictionary> FillTrigrams(List> text) 55 | { 56 | Dictionary> bigrams = new Dictionary>(); 57 | 58 | foreach (var sentence in text) 59 | { 60 | for (int i = 0; i < sentence.Count - 2; i++) 61 | { 62 | if (!bigrams.ContainsKey(sentence[i] + " " + sentence[i + 1])) 63 | bigrams.Add(sentence[i] + " " + sentence[i + 1], new Dictionary()); 64 | if (!bigrams[sentence[i] + " " + sentence[i + 1]].ContainsKey(sentence[i + 2])) 65 | bigrams[sentence[i] + " " + sentence[i + 1]].Add(sentence[i + 2], 1); 66 | else bigrams[sentence[i] + " " + sentence[i + 1]][sentence[i + 2]] += 1; 67 | } 68 | } 69 | 70 | return bigrams; 71 | } 72 | 73 | public static Dictionary GetMostFrequentNextWordsTrigram(List> text) 74 | { 75 | Dictionary> bigrams = FillTrigrams(text); 76 | Dictionary mostFrequentTrigrams = new Dictionary(); 77 | 78 | foreach (var wordPair in bigrams) 79 | { 80 | var maxValue = 0; 81 | string mostFrequentThirdWord = null; 82 | 83 | foreach (var ThirdWord in wordPair.Value) 84 | { 85 | if (ThirdWord.Value == maxValue) 86 | if (string.CompareOrdinal(mostFrequentThirdWord, ThirdWord.Key) > 0) 87 | mostFrequentThirdWord = ThirdWord.Key; 88 | if (ThirdWord.Value > maxValue) 89 | { 90 | mostFrequentThirdWord = ThirdWord.Key; 91 | maxValue = ThirdWord.Value; 92 | } 93 | } 94 | mostFrequentTrigrams.Add(wordPair.Key, mostFrequentThirdWord); 95 | } 96 | return mostFrequentTrigrams; 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /5. Коллекции, строки, файлы/SentencesParserTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | 5 | 6 | namespace TextAnalysis 7 | { 8 | static class SentencesParserTask 9 | { 10 | static char[] endSimbol = new char[] { '.', '!', '?', ';', ':', '(', ')' }; 11 | 12 | public static readonly string[] StopWords = 13 | { 14 | "the", "and", "to", "a", "of", "in", "on", "at", "that", 15 | "as", "but", "with", "out", "for", "up", "one", "from", "into" 16 | }; 17 | 18 | public static List> ParseSentences(string text) 19 | { 20 | text = text.ToLower(); 21 | List> list = new List>(); 22 | string[] textSeparation = text.Split(endSimbol); 23 | 24 | foreach (var word in textSeparation) 25 | { 26 | List tempList = new List(); 27 | var textSentence = SeparateSimbol(word); 28 | 29 | string[] wrd = textSentence.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 30 | 31 | foreach (var VARIABLE in wrd) 32 | { 33 | if (BadWord(VARIABLE) && VARIABLE != "") 34 | tempList.Add(VARIABLE); 35 | } 36 | 37 | if (tempList.Count == 0) continue; 38 | else list.Add(tempList); 39 | } 40 | 41 | return list; 42 | } 43 | 44 | 45 | private static string SeparateSimbol(string word) 46 | { 47 | var textSentence = ""; 48 | 49 | foreach (var simbol in word) 50 | { 51 | if (char.IsLetter(simbol) || (simbol == '\'')) 52 | textSentence = textSentence + simbol; 53 | else textSentence = textSentence + ' '; 54 | } 55 | return textSentence; 56 | } 57 | 58 | 59 | 60 | public static bool BadWord(string sentence) 61 | { 62 | foreach (var wrd in StopWords) 63 | if (wrd == sentence) 64 | return false; 65 | return true; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /7. Сложность алгоритмов/GrayscaleTask.cs: -------------------------------------------------------------------------------- 1 | namespace Recognizer 2 | { 3 | public static class GrayscaleTask 4 | { 5 | const double RedMultiplier = 0.299; 6 | const double GreenMultiplier = 0.587; 7 | const double BlueMultiplier = 0.114; 8 | const double NumberOfShades = 255; 9 | 10 | public static double[,] ToGrayscale(Pixel[,] original) 11 | { 12 | var width = original.GetLength(0); 13 | var height = original.GetLength(1); 14 | var grayscale = new double[width, height]; 15 | for (int x = 0; x < width; x++) 16 | for (int y = 0; y < height; y++) 17 | grayscale[x, y] = (original[x, y].R * 18 | RedMultiplier + original[x, y].G * 19 | GreenMultiplier + original[x, y].B * 20 | BlueMultiplier) / NumberOfShades; 21 | return grayscale; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /7. Сложность алгоритмов/MedianFilterTask.cs: -------------------------------------------------------------------------------- 1 | // Вставьте сюда финальное содержимое файла MedianFilterTask.cs 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Recognizer 6 | { 7 | internal static class MedianFilterTask 8 | { 9 | public static double[,] MedianFilter(double[,] original) 10 | { 11 | var width = original.GetLength(0); 12 | var height = original.GetLength(1); 13 | var medianPixels = new double[width, height]; 14 | 15 | for (int x = 0; x < width; x++) 16 | for (int y = 0; y < height; y++) 17 | medianPixels[x, y] = GetMedianPixelValue(x, y, original); 18 | return medianPixels; 19 | } 20 | 21 | public static double GetMedianPixelValue(int x, int y, double[,] pixels) 22 | { 23 | var width = pixels.GetLength(0); 24 | var height = pixels.GetLength(1); 25 | var pixelValues = new List(); 26 | 27 | for (int i = 0; i < 3; i++) 28 | for (int j = 0; j < 3; j++) 29 | if (IsPixelInsideBoundaries(x - 1 + i, y - 1 + j, width, height)) 30 | pixelValues.Add(pixels[x - 1 + i, y - 1 + j]); 31 | 32 | pixelValues.Sort(); 33 | if (pixelValues.Count % 2 == 1) 34 | return pixelValues[pixelValues.Count / 2]; 35 | else 36 | return (pixelValues[(pixelValues.Count / 2) - 1] + pixelValues[pixelValues.Count / 2]) / 2; 37 | } 38 | 39 | public static bool IsPixelInsideBoundaries(int x, int y, int width, int height) 40 | { 41 | return (x > -1 && y > -1) && (x < width && y < height); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /7. Сложность алгоритмов/SobelFilterTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Recognizer 4 | { 5 | internal static class SobelFilterTask 6 | { 7 | public static double[,] SobelFilter(double[,] g, double[,] sx) 8 | { 9 | var width = g.GetLength(0); 10 | var height = g.GetLength(1); 11 | var result = new double[width, height]; 12 | var sy = TransposeMatrix(sx); 13 | var shift = sx.GetLength(0) / 2; 14 | 15 | for (int x = shift; x < width - shift; x++) 16 | for (int y = shift; y < height - shift; y++) 17 | { 18 | var gx = MultiplyPixelsByMatrix(g, sx, x, y, shift); 19 | var gy = MultiplyPixelsByMatrix(g, sy, x, y, shift); 20 | result[x, y] = Math.Sqrt(gx * gx + gy * gy); 21 | } 22 | return result; 23 | } 24 | 25 | public static double[,] TransposeMatrix(double[,] matrix) 26 | { 27 | var sideLength = matrix.GetLength(0); 28 | var transposedMatrix = new double[sideLength, sideLength]; 29 | for (int x = 0; x < sideLength; x++) 30 | for (int y = 0; y < sideLength; y++) 31 | transposedMatrix[x, y] = matrix[y, x]; 32 | return transposedMatrix; 33 | } 34 | 35 | public static double MultiplyPixelsByMatrix(double[,] pixels, double[,] matrix, int x, int y, int shift) 36 | { 37 | double result = 0; 38 | int sideLength = matrix.GetLength(0); 39 | for (int i = 0; i < sideLength; i++) 40 | for (int j = 0; j < sideLength; j++) 41 | result += matrix[i, j] * pixels[x - shift + i, y - shift + j]; 42 | return result; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /7. Сложность алгоритмов/ThresholdFilterTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Recognizer 4 | { 5 | public static class ThresholdFilterTask 6 | { 7 | public static double[,] ThresholdFilter(double[,] original, double threshold) 8 | { 9 | var width = original.GetLength(0); 10 | var height = original.GetLength(1); 11 | double actualThreshold = FindActualThreshold(original, threshold, width, height); 12 | var blackAndWhitePixels = new double[width, height]; 13 | for (int x = 0; x < width; x++) 14 | for (int y = 0; y < height; y++) 15 | blackAndWhitePixels[x, y] = (original[x, y] >= actualThreshold) ? 1.0 : 0.0; 16 | return blackAndWhitePixels; 17 | } 18 | 19 | private static double FindActualThreshold(double[,] original, double threshold, int width, int height) 20 | { 21 | var pixelsCount = width * height; 22 | var allPixels = new double[pixelsCount]; 23 | for (int i = 0; i < pixelsCount; i++) 24 | allPixels[i] = original[i % width, i / width]; 25 | Array.Sort(allPixels); 26 | 27 | var actualThreshold = 0.0; 28 | var whitePixelsCount = (int)(threshold * pixelsCount); 29 | if (whitePixelsCount == pixelsCount) actualThreshold = double.NegativeInfinity; 30 | else if (whitePixelsCount == 0) actualThreshold = double.PositiveInfinity; 31 | else actualThreshold = allPixels[Math.Max(pixelsCount - whitePixelsCount, 0)]; 32 | return actualThreshold; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /8. Рекурсивные алгоритмы/CaseAlternatorTask.cs: -------------------------------------------------------------------------------- 1 | public class CaseAlternatorTask 2 | { 3 | public static List AlternateCharCases(string lowercaseWord) 4 | { 5 | var result = new List(); 6 | AlternateCharCases(lowercaseWord.ToCharArray(), 0, result); 7 | return result; 8 | } 9 | 10 | static void AlternateCharCases(char[] word, int startIndex, List result) 11 | { 12 | if (startIndex == word.Length) 13 | { 14 | result.Add(new string(word)); 15 | return; 16 | } 17 | 18 | if (char.IsLetter(word[startIndex]) && word[startIndex] != char.ToUpper(word[startIndex])) 19 | { 20 | AlternateCharCases(word, startIndex + 1, result); 21 | word[startIndex] = char.ToUpper(word[startIndex]); 22 | } 23 | 24 | AlternateCharCases(word, startIndex + 1, result); 25 | word[startIndex] = char.ToLower(word[startIndex]); 26 | } 27 | } -------------------------------------------------------------------------------- /8. Рекурсивные алгоритмы/PathFinderTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | 6 | namespace RoutePlanning 7 | { 8 | public static class PathFinderTask 9 | { 10 | public static int[] FindBestCheckpointsOrder( 11 | Point[] checkpoints) 12 | { 13 | double shortestDistance = double.PositiveInfinity; 14 | int[] order = new int[checkpoints.Length]; 15 | int[] bestOrder = new int[checkpoints.Length]; 16 | MakePermutations(order, 1, checkpoints, ref shortestDistance, ref bestOrder); 17 | return bestOrder; 18 | } 19 | 20 | public static int[] MakePermutations(int[] order, int position, Point[] checkpoints, 21 | ref double shortestDistance, ref int[] bestOrder) 22 | { 23 | var currentOrder = new int[position]; 24 | Array.Copy(order, currentOrder, position); 25 | var pathLength = PointExtensions.GetPathLength(checkpoints, currentOrder); 26 | 27 | if (pathLength < shortestDistance) 28 | { 29 | if (position == order.Length) 30 | { 31 | shortestDistance = pathLength; 32 | bestOrder = (int[])order.Clone(); 33 | return order; 34 | } 35 | 36 | 37 | for (int i = 1; i < order.Length; i++) 38 | { 39 | var index = Array.IndexOf(order, i, 0, position); 40 | if (index != -1) 41 | continue; 42 | order[position] = i; 43 | MakePermutations(order, position + 1, checkpoints, ref shortestDistance, 44 | ref bestOrder); 45 | } 46 | } 47 | 48 | return order; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /9. Поиск и сортировка/AutocompleteTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using NUnit.Framework; 5 | 6 | 7 | namespace Autocomplete 8 | { 9 | [TestFixture] 10 | public class AutocompleteTests 11 | { 12 | [Test] 13 | public void GetCountByPrefixTest() 14 | { 15 | var phrases = new List { "a", "ab", "abc", "b" }; 16 | var prefix = "a"; 17 | var expectedResult = 3; 18 | var result = AutocompleteTask.GetCountByPrefix(phrases, prefix); 19 | Assert.AreEqual(expectedResult, result); 20 | } 21 | 22 | [Test] 23 | public void GetCountByPrefixEmptyTest() 24 | { 25 | var phrases = new List { "a", "ab", "abc", "b" }; 26 | var prefix = "c"; 27 | var expectedResult = 0; 28 | var result = AutocompleteTask.GetCountByPrefix(phrases, prefix); 29 | Assert.AreEqual(expectedResult, result); 30 | } 31 | 32 | 33 | [Test] 34 | public void GetTopByPrefixTest() 35 | { 36 | var phrases = new List { "a", "ab", "abc", "b" }; 37 | var prefix = "a"; 38 | var count = 2; 39 | var expectedResult = new[] { "a", "ab" }; 40 | var result = AutocompleteTask.GetTopByPrefix(phrases, prefix, count); 41 | Assert.AreEqual(expectedResult, result); 42 | } 43 | 44 | 45 | [Test] 46 | public void GetTopByPrefixTestLessThanCount() 47 | { 48 | var phrases = new List { "a", "ab", "abc", "b" }; 49 | var prefix = "a"; 50 | var count = 4; 51 | var expectedResult = new[] { "a", "ab", "abc" }; 52 | var result = AutocompleteTask.GetTopByPrefix(phrases, prefix, count); 53 | Assert.AreEqual(expectedResult, result); 54 | } 55 | 56 | 57 | [Test] 58 | public void GetTopByPrefixTestEmpty() 59 | { 60 | var phrases = new List { "a", "ab", "abc", "b" }; 61 | var prefix = "c"; 62 | var count = 2; 63 | var expectedResult = new string[0]; 64 | var result = AutocompleteTask.GetTopByPrefix(phrases, prefix, count); 65 | Assert.AreEqual(expectedResult, result); 66 | } 67 | } 68 | 69 | 70 | 71 | internal class AutocompleteTask 72 | { 73 | public static string FindFirstByPrefix(IReadOnlyList phrases, string prefix) 74 | { 75 | var index = LeftBorderTask.GetLeftBorderIndex(phrases, prefix, -1, phrases.Count) + 1; 76 | if (index < phrases.Count && phrases[index].StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) 77 | return phrases[index]; 78 | else 79 | return null; 80 | } 81 | 82 | 83 | public static string[] GetTopByPrefix(IReadOnlyList phrases, string prefix, int count) 84 | { 85 | int actualCount = Math.Min(GetCountByPrefix(phrases, prefix), count); 86 | int startIndex = LeftBorderTask.GetLeftBorderIndex(phrases, prefix, -1, phrases.Count) + 1; 87 | string[] result = new string[actualCount]; 88 | Array.Copy(phrases.ToArray(), startIndex, result, 0, actualCount); 89 | return result; 90 | } 91 | 92 | 93 | public static int GetCountByPrefix(IReadOnlyList phrases, string prefix) 94 | { 95 | int left = LeftBorderTask.GetLeftBorderIndex(phrases, prefix, -1, phrases.Count); 96 | int right = RightBorderTask.GetRightBorderIndex(phrases, prefix, -1, phrases.Count); 97 | return right - left - 1; 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /9. Поиск и сортировка/LeftBorderTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Autocomplete 6 | { 7 | public class LeftBorderTask 8 | { 9 | public static int GetLeftBorderIndex(IReadOnlyList phrases, string prefix, int left, int right) 10 | { 11 | if (right - left <= 1) return left; 12 | var middle = left + (right - left) / 2; 13 | return (string.Compare(prefix, phrases[middle], StringComparison.OrdinalIgnoreCase) > 0) ? 14 | GetLeftBorderIndex(phrases, prefix, middle, right): 15 | GetLeftBorderIndex(phrases, prefix, left, middle); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /9. Поиск и сортировка/RightBorderTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Autocomplete 6 | { 7 | public class RightBorderTask 8 | { 9 | public static int GetRightBorderIndex(IReadOnlyList phrases, string prefix, int left, int right) 10 | { 11 | while (right - left > 1) 12 | { 13 | var middle = left + (right - left) / 2; 14 | if (string.Compare(prefix, phrases[middle], StringComparison.OrdinalIgnoreCase) >= 0 15 | || phrases[middle].StartsWith(prefix)) 16 | left = middle; 17 | else right = middle; 18 | } 19 | return right; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ulearn-sharp1 2 | Прохождение курса "Основы программирования на примере C#"-Часть1 3 | 4 | Курс на сайте https://ulearn.me/ 5 | 6 | Весь проект задания скачивается со страницы задания. 7 | --------------------------------------------------------------------------------