Advertisement
isoZachary

Daily Programmer 261 Hard

Apr 20th, 2016
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.04 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. namespace DailyProgrammer261Hard
  5. {
  6.     class Program
  7.     {
  8.         static void Main(string[] args)
  9.         {
  10.             int?[,] grid = new int?[4, 4];
  11.             List<int[]> dominoes = new List<int[]>
  12.             {
  13.                 new int[] { 1, 14 },
  14.                 new int[] { 2, 8 },
  15.                 new int[] { 3, 13 },
  16.                 new int[] { 4, 15 },
  17.                 new int[] { 5, 11 },
  18.                 new int[] { 6, 9 },
  19.                 new int[] { 7, 12 },
  20.                 new int[] { 10, 16 },
  21.             };
  22.             AddDominoAndValidate(ref grid, dominoes);
  23.  
  24.             PrintGrid(grid);
  25.             Console.ReadLine();
  26.         }
  27.  
  28.         static bool AddDominoAndValidate(ref int?[,] grid, List<int[]> dominoes)
  29.         {
  30.             // Where to start?
  31.             int row = -1, col = -1;
  32.             FindFirstEmptyCell(grid, ref row, ref col);
  33.  
  34.             // Try adding each domino
  35.             bool horizontal = col != grid.GetLength(1) - 1 && !grid[row, col + 1].HasValue;
  36.             bool vertical = row != grid.GetLength(0) - 1;
  37.  
  38.             foreach (int[] domino in dominoes)
  39.             {
  40.                 List<int[]> fewerDominoes = RemoveDominoFromList(dominoes, domino);
  41.  
  42.                 // Horizontal
  43.                 if (horizontal)
  44.                 {
  45.                     // Unflipped
  46.                     PutDownDomino(ref grid, domino, false, row, col, false);
  47.                     if (VerifyGridMagic(grid))
  48.                     {
  49.                         if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
  50.                         {
  51.                             return true;
  52.                         }
  53.                     }
  54.                     PickUpDomino(ref grid, row, col, false);
  55.  
  56.                     // Flipped
  57.                     PutDownDomino(ref grid, domino, true, row, col, false);
  58.                     if (VerifyGridMagic(grid))
  59.                     {
  60.                         if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
  61.                         {
  62.                             return true;
  63.                         }
  64.                     }
  65.                     PickUpDomino(ref grid, row, col, false);
  66.                 }
  67.  
  68.                 // Vertical
  69.                 if (vertical)
  70.                 {
  71.                     // Unflipped
  72.                     PutDownDomino(ref grid, domino, false, row, col, true);
  73.                     if (VerifyGridMagic(grid))
  74.                     {
  75.                         if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
  76.                         {
  77.                             return true;
  78.                         }
  79.                     }
  80.                     PickUpDomino(ref grid, row, col, true);
  81.  
  82.                     // Flipped
  83.                     PutDownDomino(ref grid, domino, true, row, col, true);
  84.                     if (VerifyGridMagic(grid))
  85.                     {
  86.                         if (IsGridFull(grid) || AddDominoAndValidate(ref grid, fewerDominoes))
  87.                         {
  88.                             return true;
  89.                         }
  90.                     }
  91.                     PickUpDomino(ref grid, row, col, true);
  92.                 }
  93.             }
  94.  
  95.             return false;
  96.         }
  97.  
  98.         private static void FindFirstEmptyCell(int?[,] grid, ref int row, ref int col)
  99.         {
  100.             for (int r = 0; r < grid.GetLength(0); r++)
  101.             {
  102.                 for (int c = 0; c < grid.GetLength(1); c++)
  103.                 {
  104.                     if (!grid[r, c].HasValue)
  105.                     {
  106.                         row = r;
  107.                         col = c;
  108.                         return;
  109.                     }
  110.                 }
  111.             }
  112.         }
  113.  
  114.         private static List<int[]> RemoveDominoFromList(List<int[]> dominoes, int[] removed)
  115.         {
  116.             List<int[]> list = new List<int[]>();
  117.             foreach (int[] domino in dominoes)
  118.             {
  119.                 if (domino[0] != removed[0])
  120.                 {
  121.                     list.Add(domino);
  122.                 }
  123.             }
  124.             return list;
  125.         }
  126.  
  127.         private static void PutDownDomino(ref int?[,] grid, int[] domino, bool flipped, int row, int col, bool vertical)
  128.         {
  129.             //Console.WriteLine($"Placed {(flipped ? "flipped " : "")}domino [{domino[0]}, {domino[1]}] {(vertical ? "vertically" : "horizontally")} in row {row}, col {col}.");
  130.  
  131.             int domino1 = flipped ? domino[1] : domino[0];
  132.             int domino2 = flipped ? domino[0] : domino[1];
  133.  
  134.             grid[row, col] = domino1;
  135.             if (vertical)
  136.             {
  137.                 grid[row + 1, col] = domino2;
  138.             }
  139.             else
  140.             {
  141.                 grid[row, col + 1] = domino2;
  142.             }
  143.         }
  144.  
  145.         private static void PickUpDomino(ref int?[,] grid, int row, int col, bool vertical)
  146.         {
  147.             grid[row, col] = null;
  148.             if (vertical)
  149.             {
  150.                 grid[row + 1, col] = null;
  151.             }
  152.             else
  153.             {
  154.                 grid[row, col + 1] = null;
  155.             }
  156.         }
  157.  
  158.         private static bool VerifyGridMagic(int?[,] grid)
  159.         {
  160.             int n = grid.GetLength(0);
  161.             int m = (n / 2) * (n * n + 1);
  162.  
  163.             // Rows
  164.             for (int r = 0; r < n; r++)
  165.             {
  166.                 List<int?> items = new List<int?>();
  167.                 for (int c = 0; c < n; c++)
  168.                 {
  169.                     items.Add(grid[r, c]);
  170.                 }
  171.                 if (!VerifyMagic(items, m)) { return false; }
  172.             }
  173.  
  174.             // Cols
  175.             for (int c = 0; c < n; c++)
  176.             {
  177.                 List<int?> items = new List<int?>();
  178.                 for (int r = 0; r < n; r++)
  179.                 {
  180.                     items.Add(grid[r, c]);
  181.                 }
  182.                 if (!VerifyMagic(items, m)) { return false; }
  183.             }
  184.  
  185.             // Diag 1
  186.             List<int?> d1Items = new List<int?>();
  187.             for (int i = 0; i < n; i++)
  188.             {
  189.                 d1Items.Add(grid[i, i]);
  190.             }
  191.             if (!VerifyMagic(d1Items, m)) { return false; }
  192.  
  193.             // Diag 2
  194.             List<int?> d2Items = new List<int?>();
  195.             for (int i = 0; i < n; i++)
  196.             {
  197.                 d2Items.Add(grid[i, n - i - 1]);
  198.             }
  199.             if (!VerifyMagic(d2Items, m)) { return false; }
  200.  
  201.             return true;
  202.         }
  203.  
  204.         private static bool VerifyMagic(List<int?> items, int magic)
  205.         {
  206.             int sum = 0;
  207.             foreach (int? item in items)
  208.             {
  209.                 if (item.HasValue)
  210.                 {
  211.                     sum += item.Value;
  212.                 }
  213.                 else
  214.                 {
  215.                     return true;
  216.                 }
  217.             }
  218.             if (sum == magic)
  219.             {
  220.                 return true;
  221.             }
  222.             return false;
  223.         }
  224.  
  225.         private static bool IsGridFull(int?[,] grid)
  226.         {
  227.             int n = grid.GetLength(0);
  228.             for (int r = 0; r < n; r++)
  229.             {
  230.                 for (int c = 0; c < n; c++)
  231.                 {
  232.                     if (!grid[r, c].HasValue)
  233.                     {
  234.                         return false;
  235.                     }
  236.                 }
  237.             }
  238.             return true;
  239.         }
  240.  
  241.         static void PrintGrid(int?[,] grid)
  242.         {
  243.             int n = grid.GetLength(0);
  244.             for (int r = 0; r < n; r++)
  245.             {
  246.                 for (int c = 0; c < n; c++)
  247.                 {
  248.                     Console.Write(NullableIntToString(grid[r, c]));
  249.                     Console.Write(" ");
  250.                 }
  251.                 Console.Write("\r\n");
  252.             }
  253.         }
  254.  
  255.         static string NullableIntToString(int? value)
  256.         {
  257.             if (value.HasValue) return value.Value.ToString("00");
  258.             else return "__";
  259.         }
  260.     }
  261. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement