Guest User

Largest Cube Stack Height Algorithm

a guest
Nov 17th, 2013
416
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.87 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6.  
  7. namespace CubeAlgorithm
  8. {
  9.     class Program
  10.     {
  11.         static void Main(string[] args)
  12.         {
  13.             var pairs = ParseInputFile();
  14.             if (pairs.Count == 0)
  15.             {
  16.                 Console.WriteLine("There are no input pairs.");
  17.                 Console.ReadKey();
  18.                 return;
  19.             }
  20.  
  21.             //they need to be ordered
  22.             pairs = pairs.OrderByDescending(c => c.Item1).ThenByDescending(c => c.Item2).ToList();
  23.  
  24.             List<List<Tuple<int, int>>> lists = new List<List<Tuple<int, int>>>();
  25.  
  26.             //each pair needs to be touched only once
  27.             foreach (var pair in pairs)
  28.             {
  29.                 //find the list with highest segment
  30.                 int maxLength = 0;
  31.                 int maxHeight = 0;
  32.                 int listIndex = -1;
  33.                 for (int j = 0; j < lists.Count; j++)
  34.                 {
  35.                     var heightLength = Find(lists[j], pair);
  36.  
  37.                     if (heightLength.Item1 > maxHeight)
  38.                     {
  39.                         maxHeight = heightLength.Item1;
  40.                         maxLength = heightLength.Item2;
  41.                         listIndex = j;
  42.                     }
  43.                 }
  44.  
  45.                 if (listIndex == -1)
  46.                 {
  47.                     //this pair can't fit anywhere, new list is made
  48.                     List<Tuple<int, int>> list = new List<Tuple<int, int>>();
  49.                     list.Add(pair);
  50.                     lists.Add(list);
  51.                 }
  52.                 else if (maxLength < lists[listIndex].Count)
  53.                 {
  54.                     //this item fits somewhere in the middle of an existing list
  55.                     //a new list is made as a copy of the current up to the point where it can't fit
  56.                     List<Tuple<int, int>> list = new List<Tuple<int, int>>();
  57.                     for (int i = 0; i < maxLength; i++)
  58.                     {
  59.                         list.Add(lists[listIndex][i]);
  60.                     }
  61.                     list.Add(pair);
  62.                     lists.Add(list);
  63.                 }
  64.                 else
  65.                 {
  66.                     //this item fits at the end (maxlength is the size of the current list)
  67.                     lists[listIndex].Add(pair);
  68.                 }
  69.             }
  70.  
  71.             //writing all lists and finding the first highest one in the same loop (to save precious nanoseconds)
  72.             Console.WriteLine("Lists:");
  73.             int max = 0;
  74.             int maxIndex = -1;
  75.             for (int j = 0; j < lists.Count; j++)
  76.             {
  77.                 int height = 0;
  78.                 for (int i = 0; i < lists[j].Count; i++)
  79.                 {
  80.                     height += lists[j][i].Item1;
  81.                 }
  82.  
  83.                 if (height > max)
  84.                 {
  85.                     max = height;
  86.                     maxIndex = j;
  87.                 }
  88.  
  89.                 Display(lists[j]);
  90.                 Console.WriteLine();
  91.             }
  92.  
  93.             Console.WriteLine();
  94.             Console.WriteLine("Maximum height list, with a height of {0}:", max);
  95.             if (maxIndex != -1)
  96.                 Display(lists[maxIndex]); //the list with maximum height
  97.             Console.ReadKey();
  98.         }
  99.  
  100.         //finds the maximum height and the position for the item to stack on the list
  101.         static Tuple<int, int> Find(List<Tuple<int, int>> list, Tuple<int, int> item)
  102.         {
  103.             //Could be transformed into a binary search for larger problems,
  104.             //the it would be O(N log N) on the worst case i guess, but with n <= 100 it doesn't really matter
  105.             //I estimate normal search worst case to be O(N^2)
  106.             int currentHeight = 0;
  107.             int currentLength = 0;
  108.             for (int i = 0; i < list.Count; i++)
  109.             {
  110.                 if (!CanStack(list[i], item))
  111.                     break;
  112.  
  113.                 currentHeight += list[i].Item1;
  114.                 currentLength = i + 1;
  115.             }
  116.             return new Tuple<int,int>(currentHeight, currentLength);
  117.         }
  118.  
  119.         static bool CanStack(Tuple<int, int> below, Tuple<int, int> above)
  120.         {
  121.             return below.Item1 >= above.Item1 && below.Item2 >= above.Item2;
  122.         }
  123.  
  124.         static void Display(List<Tuple<int, int>> results)
  125.         {
  126.             foreach (var item in results)
  127.                 Console.Write(item + " ");
  128.         }
  129.  
  130.         static List<Tuple<int, int>> ParseInputFile()
  131.         {
  132.             List<Tuple<int, int>> cubes = new List<Tuple<int, int>>();
  133.  
  134.             FileInfo file = new FileInfo("Input.txt");
  135.             using (StreamReader sr = new StreamReader(file.OpenRead()))
  136.             {
  137.                 if (!sr.EndOfStream)
  138.                     sr.ReadLine(); //the first, unnecessary line: number of pairs...
  139.                 while (!sr.EndOfStream)
  140.                 {
  141.                     string line = sr.ReadLine().TrimEnd(' ');
  142.                     if (string.IsNullOrWhiteSpace(line))
  143.                         continue;
  144.  
  145.                     string[] parts = line.Split(' ');
  146.                     if (parts.Length != 2)
  147.                         throw new Exception(String.Format("Parse error at line '{0}'", line));
  148.  
  149.                     int first = 0;
  150.                     int second = 0;
  151.                     if (!int.TryParse(parts[0], out first))
  152.                         throw new Exception(String.Format("Parse error at line '{0}'", line));
  153.  
  154.                     if (!int.TryParse(parts[1], out second))
  155.                         throw new Exception(String.Format("Parse error at line '{0}'", line));
  156.  
  157.                     cubes.Add(new Tuple<int, int>(first, second));
  158.                 }
  159.             }
  160.  
  161.             return cubes;
  162.         }
  163.     }
  164. }
Advertisement
Add Comment
Please, Sign In to add comment