using System; using System.Collections.Generic; using System.Linq; class Program { static string Overbar(string s) { return s switch { "A" => "Ā", "B" => "B̄", "C" => "C̄", "D" => "D̄", _ => s }; } static void Main() { do { string[,] map = new string[4, 4]; // Inicializace na N (not specified yet) for (int r = 0; r < 4; r++) for (int c = 0; c < 4; c++) map[r, c] = "N"; // Input for Karnaugh map cells for (int r = 0; r < 4; r++) { for (int c = 0; c < 4; c++) { Console.Clear(); map[r, c] = "K"; // Mark current cell PrintMap(map, true); Console.Write($"Zadej hodnotu pro ({r},{c}) [0 = záporná, 1 = kladná, X = nevadí]: "); string input = Console.ReadLine()!.Trim().ToUpper(); if (input != "0" && input != "1" && input != "X") input = "0"; map[r, c] = input; } } Console.Clear(); Console.WriteLine("Karnaughova mapa:"); PrintMap(map, false); Console.WriteLine("\nZjednodušený výraz:"); string result = CalculateExpression(map); Console.WriteLine(result); // Prompt to restart or exit Console.WriteLine("\nPokračovat? (Y/N nebo Escape)"); ConsoleKeyInfo keyInfo = Console.ReadKey(true); if (keyInfo.Key == ConsoleKey.N || keyInfo.Key == ConsoleKey.Escape) break; } while (true); } static void PrintMap(string[,] map, bool showInstructions) { string[] rowLabels = { "(ĀB̄)", "(ĀB)", "(AB)", "(A B̄)" }; string[] colLabels = { "(C̄D̄)", "(C̄D)", "(CD)", "(C D̄)" }; Console.Write(" "); foreach (var col in colLabels) Console.Write(col.PadRight(6)); Console.WriteLine(); for (int r = 0; r < 4; r++) { Console.Write(rowLabels[r].PadRight(8)); for (int c = 0; c < 4; c++) Console.Write(map[r, c].PadRight(6)); Console.WriteLine(); } if (showInstructions) { Console.WriteLine(); Console.WriteLine("Legenda:"); Console.WriteLine("0 = záporná hodnota (FALSE)"); Console.WriteLine("1 = kladná hodnota (TRUE)"); Console.WriteLine("X = nevadí (Don't Care) - může být 0 nebo 1"); Console.WriteLine("K = aktuální vybraná buňka"); Console.WriteLine("N = zatím nezadáno (není specifikováno)"); Console.WriteLine(); } } static string CalculateExpression(string[,] map) { int[,] binMap = new int[4, 4]; for (int r = 0; r < 4; r++) for (int c = 0; c < 4; c++) binMap[r, c] = map[r, c] == "1" ? 1 : map[r, c] == "X" ? -1 : 0; var terms = new List(); string[] rowGray = { "00", "01", "11", "10" }; string[] colGray = { "00", "01", "11", "10" }; bool[,] used = new bool[4, 4]; // Check if all cells in the group are 1 or X and group contains at least one 1 bool CheckGroup(int rStart, int cStart, int height, int width) { bool hasOne = false; for (int dr = 0; dr < height; dr++) { for (int dc = 0; dc < width; dc++) { int rr = (rStart + dr) % 4; int cc = (cStart + dc) % 4; if (binMap[rr, cc] == 0) return false; if (binMap[rr, cc] == 1) hasOne = true; } } return hasOne; } void MarkUsed(int rStart, int cStart, int height, int width) { for (int dr = 0; dr < height; dr++) for (int dc = 0; dc < width; dc++) { int rr = (rStart + dr) % 4; int cc = (cStart + dc) % 4; used[rr, cc] = true; } } string GroupToTerm(int rStart, int cStart, int height, int width) { var rowsBits = new List(); var colsBits = new List(); for (int dr = 0; dr < height; dr++) rowsBits.Add(rowGray[(rStart + dr) % 4]); for (int dc = 0; dc < width; dc++) colsBits.Add(colGray[(cStart + dc) % 4]); string term = ""; bool A_const = true; char A_val = rowsBits[0][0]; foreach (var rb in rowsBits) if (rb[0] != A_val) A_const = false; if (A_const) term += A_val == '0' ? Overbar("A") : "A"; bool B_const = true; char B_val = rowsBits[0][1]; foreach (var rb in rowsBits) if (rb[1] != B_val) B_const = false; if (B_const) term += B_val == '0' ? Overbar("B") : "B"; bool C_const = true; char C_val = colsBits[0][0]; foreach (var cb in colsBits) if (cb[0] != C_val) C_const = false; if (C_const) term += C_val == '0' ? Overbar("C") : "C"; bool D_const = true; char D_val = colsBits[0][1]; foreach (var cb in colsBits) if (cb[1] != D_val) D_const = false; if (D_const) term += D_val == '0' ? Overbar("D") : "D"; if (term == "") term = "1"; return term; } var blockSizes = new List<(int h, int w)> { (4, 4), (4, 2), (2, 4), (4, 1), (1, 4), (2, 2), (2, 1), (1, 2), (1,1) }; foreach (var (h, w) in blockSizes) { for (int r0 = 0; r0 < 4; r0++) { for (int c0 = 0; c0 < 4; c0++) { if (CheckGroup(r0, c0, h, w)) { string term = GroupToTerm(r0, c0, h, w); bool coversNew = false; for (int dr = 0; dr < h; dr++) for (int dc = 0; dc < w; dc++) { int rr = (r0 + dr) % 4; int cc = (c0 + dc) % 4; if (!used[rr, cc]) coversNew = true; } if (coversNew && !terms.Contains(term)) { terms.Add(term); MarkUsed(r0, c0, h, w); } } } } } if (terms.Count == 0) return "0"; return string.Join(" + ", terms); } }