Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- namespace DailyProgrammer261Hard
- {
- class Program
- {
- static void Main(string[] args)
- {
- int?[,] grid = new int?[4, 4];
- List<int[]> dominoes = new List<int[]>
- {
- new int[] { 1, 14 },
- new int[] { 2, 8 },
- new int[] { 3, 13 },
- new int[] { 4, 15 },
- new int[] { 5, 11 },
- new int[] { 6, 9 },
- new int[] { 7, 12 },
- new int[] { 10, 16 },
- };
- AddDominoAndValidate(ref grid, dominoes);
- PrintGrid(grid);
- Console.ReadLine();
- }
- static bool AddDominoAndValidate(ref int?[,] grid, List<int[]> dominoes)
- {
- // Where to start?
- int row = -1, col = -1;
- FindFirstEmptyCell(grid, ref row, ref col);
- // Try adding each domino
- bool horizontal = col != grid.GetLength(1) - 1 && !grid[row, col + 1].HasValue;
- bool vertical = row != grid.GetLength(0) - 1;
- foreach (int[] domino in dominoes)
- {
- List<int[]> fewerDominoes = RemoveDominoFromList(dominoes, domino);
- // Horizontal
- if (horizontal)
- {
- // Unflipped
- PutDownDomino(ref grid, domino, false, row, col, false);
- if (VerifyGridMagic(grid))
- {
- if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
- {
- return true;
- }
- }
- PickUpDomino(ref grid, row, col, false);
- // Flipped
- PutDownDomino(ref grid, domino, true, row, col, false);
- if (VerifyGridMagic(grid))
- {
- if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
- {
- return true;
- }
- }
- PickUpDomino(ref grid, row, col, false);
- }
- // Vertical
- if (vertical)
- {
- // Unflipped
- PutDownDomino(ref grid, domino, false, row, col, true);
- if (VerifyGridMagic(grid))
- {
- if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
- {
- return true;
- }
- }
- PickUpDomino(ref grid, row, col, true);
- // Flipped
- PutDownDomino(ref grid, domino, true, row, col, true);
- if (VerifyGridMagic(grid))
- {
- if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
- {
- return true;
- }
- }
- PickUpDomino(ref grid, row, col, true);
- }
- }
- return false;
- }
- private static void FindFirstEmptyCell(int?[,] grid, ref int row, ref int col)
- {
- for (int r = 0; r < grid.GetLength(0); r++)
- {
- for (int c = 0; c < grid.GetLength(1); c++)
- {
- if (!grid[r, c].HasValue)
- {
- row = r;
- col = c;
- return;
- }
- }
- }
- }
- private static List<int[]> RemoveDominoFromList(List<int[]> dominoes, int[] removed)
- {
- List<int[]> list = new List<int[]>();
- foreach (int[] domino in dominoes)
- {
- if (domino[0] != removed[0])
- {
- list.Add(domino);
- }
- }
- return list;
- }
- private static void PutDownDomino(ref int?[,] grid, int[] domino, bool flipped, int row, int col, bool vertical)
- {
- //Console.WriteLine($"Placed {(flipped ? "flipped " : "")}domino [{domino[0]}, {domino[1]}] {(vertical ? "vertically" : "horizontally")} in row {row}, col {col}.");
- int domino1 = flipped ? domino[1] : domino[0];
- int domino2 = flipped ? domino[0] : domino[1];
- grid[row, col] = domino1;
- if (vertical)
- {
- grid[row + 1, col] = domino2;
- }
- else
- {
- grid[row, col + 1] = domino2;
- }
- }
- private static void PickUpDomino(ref int?[,] grid, int row, int col, bool vertical)
- {
- grid[row, col] = null;
- if (vertical)
- {
- grid[row + 1, col] = null;
- }
- else
- {
- grid[row, col + 1] = null;
- }
- }
- private static bool VerifyGridMagic(int?[,] grid)
- {
- int n = grid.GetLength(0);
- int m = (n / 2) * (n * n + 1);
- // Rows
- for (int r = 0; r < n; r++)
- {
- List<int?> items = new List<int?>();
- for (int c = 0; c < n; c++)
- {
- items.Add(grid[r, c]);
- }
- if (!VerifyMagic(items, m)) { return false; }
- }
- // Cols
- for (int c = 0; c < n; c++)
- {
- List<int?> items = new List<int?>();
- for (int r = 0; r < n; r++)
- {
- items.Add(grid[r, c]);
- }
- if (!VerifyMagic(items, m)) { return false; }
- }
- // Diag 1
- List<int?> d1Items = new List<int?>();
- for (int i = 0; i < n; i++)
- {
- d1Items.Add(grid[i, i]);
- }
- if (!VerifyMagic(d1Items, m)) { return false; }
- // Diag 2
- List<int?> d2Items = new List<int?>();
- for (int i = 0; i < n; i++)
- {
- d2Items.Add(grid[i, n - i - 1]);
- }
- if (!VerifyMagic(d2Items, m)) { return false; }
- return true;
- }
- private static bool VerifyMagic(List<int?> items, int magic)
- {
- int sum = 0;
- foreach (int? item in items)
- {
- if (item.HasValue)
- {
- sum += item.Value;
- }
- else
- {
- return true;
- }
- }
- if (sum == magic)
- {
- return true;
- }
- return false;
- }
- private static bool IsGridFull(int?[,] grid)
- {
- int n = grid.GetLength(0);
- for (int r = 0; r < n; r++)
- {
- for (int c = 0; c < n; c++)
- {
- if (!grid[r, c].HasValue)
- {
- return false;
- }
- }
- }
- return true;
- }
- static void PrintGrid(int?[,] grid)
- {
- int n = grid.GetLength(0);
- for (int r = 0; r < n; r++)
- {
- for (int c = 0; c < n; c++)
- {
- Console.Write(NullableIntToString(grid[r, c]));
- Console.Write(" ");
- }
- Console.Write("\r\n");
- }
- }
- static string NullableIntToString(int? value)
- {
- if (value.HasValue) return value.Value.ToString("00");
- else return "__";
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement