Advertisement
liartie

Untitled

Sep 28th, 2022
585
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.52 KB | None | 0 0
  1. using System.Text.RegularExpressions;
  2.  
  3. namespace Sort
  4. {
  5.     public class Sort
  6.     {
  7.         public static List<String> FileNames = new List<string>(); // list of all filenames to iterate through
  8.         public static string OutputFileName = "output.txt"; // default name just in case (although it would never be used)
  9.        
  10.         public static List<String> ReadFile(List<String> names) // function to read the input file and check if everything is ok with it
  11.         {
  12.             List<String> lines = new List<String>(); // list where all the lines are stored one after another
  13.             foreach (var name in names)
  14.             {
  15.                 try
  16.                 {
  17.                     foreach (string line in File.ReadLines(name))
  18.                     {
  19.                         lines.Add(line);
  20.                     }
  21.                 }
  22.                 catch (FileNotFoundException) // if file is not found
  23.                 {
  24.                     Console.WriteLine("I am so sorry to say, but I cannot find such file (" + name +
  25.                                       "). I know this might be very difficult," +
  26.                                       " but please check if you have entered the name correctly. I believe in you.");
  27.                     lines.Clear(); // returning empty so that the program can exit
  28.                     return lines;
  29.                 }
  30.             }
  31.  
  32.             return lines;
  33.         }
  34.  
  35.         public static async Task Print(bool toFile, List<String> linesArray, string fileName) // function to print the result depending on the flags specified
  36.         {
  37.             if (toFile) // if the user wants the result to be written in a file
  38.             {
  39.                 try
  40.                 {
  41.                     await File.WriteAllLinesAsync(fileName, linesArray); // trying to create the file with filename fileName and write all the lines there
  42.                 }
  43.                 catch (InvalidOperationException) // catching all the errors that might occur
  44.                 {
  45.                     Console.WriteLine("Error: the file already exists and is read-only.");
  46.                 }
  47.                 catch (PathTooLongException)
  48.                 {
  49.                     Console.WriteLine("Error: the path name may be too long.");
  50.                 }
  51.                 catch (IOException)
  52.                 {
  53.                     Console.WriteLine("Error: either the filename is invalid or the disk is full. I don't know, you tell me.");
  54.                 }
  55.             }
  56.             else // if the user wants the result to be printed out on the screen
  57.             {
  58.                 foreach (var line in linesArray)
  59.                 {
  60.                     Console.WriteLine(line);
  61.                 }
  62.             }
  63.         }
  64.        
  65.         public static bool IgnoreCase,
  66.             Reverse,
  67.             Unique,
  68.             NumericSort,
  69.             VersionSort,
  70.             FileOutput,
  71.             SymbolSort,
  72.             LengthSort; // all the flags that might be
  73.         public static List<String> SortLines(List<String> lines) // the main sorting algorithm
  74.         {
  75.             if (SymbolSort) // -s flag
  76.             {
  77.                 for(int i = 0; i < lines.Count; i++)
  78.                 {
  79.                     var line = lines[i];
  80.                     char[] characters = line.ToArray();
  81.                     Array.Sort(characters);
  82.                     lines[i] = new string(characters);
  83.                 }
  84.             }
  85.  
  86.             if (LengthSort) // -l flag
  87.             {
  88.                 List<Tuple<int, String>> linesWithSizes = new List<Tuple<int, string>>(); // array of tuples where first element is the size of a string and second is the string itself
  89.                 foreach (var line in lines)
  90.                 {
  91.                     linesWithSizes.Add(new Tuple<int, string>(line.Length, line)); // adding size and string
  92.                 }
  93.                 linesWithSizes.Sort();
  94.                 List<String> ans = new List<string>(); // the final list
  95.                 foreach (var line in linesWithSizes)
  96.                 {
  97.                     ans.Add(line.Item2); // adding sorted by size strings to the answer list
  98.                 }
  99.                 if (Reverse) ans.Reverse();
  100.                 if (Unique) ans = ans.Distinct().ToList();
  101.                 return ans;
  102.             }
  103.            
  104.             if (VersionSort) // -V flag
  105.             {
  106.                 List<Version> versions = new List<Version>();
  107.                 List<String> other = new List<string>(); // we split the initial list into two lists for it to be easier for us
  108.                 foreach (var line in lines) // adding to one of the lists depending whether it is a version or not
  109.                 {
  110.                     try
  111.                     {
  112.                         versions.Add(Version.Parse(line));
  113.                     }
  114.                     catch
  115.                     {
  116.                         other.Add(line);
  117.                     }
  118.                 }
  119.                
  120.                 versions.Sort(); // sorting the array
  121.                 if (Reverse) versions.Reverse(); // the reverse flag
  122.                 List<String> mergedList = new List<string>(); // list to merge both parts
  123.                 foreach (var version in versions)
  124.                 {
  125.                     mergedList.Add(version.ToString()); // adding version to the merged list
  126.                 }
  127.                 mergedList.AddRange(other); // adding the list of other strings
  128.                 if (Unique) mergedList = mergedList.Distinct().ToList(); // clearing the -u flag (can't clear it before they are merged)
  129.                 return mergedList;
  130.             }
  131.             if (NumericSort) // -n flag. Almost the same as the versionSort
  132.             {
  133.                 List<String> nums = new List<string>();
  134.                 List<String> other = new List<string>();
  135.                 foreach (var line in lines)
  136.                 {
  137.                     if (new Regex("^[0-9]*$").IsMatch(line)) nums.Add(line);
  138.                     else other.Add(line);
  139.                 }
  140.  
  141.                 if (Reverse) nums.Reverse();
  142.                 nums.AddRange(other);
  143.                 if (Unique) nums = nums.Distinct().ToList();
  144.                 return nums;
  145.             }
  146.  
  147.             if (IgnoreCase) // -f flag
  148.             {
  149.                 List<Tuple<String, Tuple<int, String>>> indexList = new List<Tuple<string, Tuple<int, String>>>(); // (lowercase string, (its initial position to keep track where same elements were located, initial version to later capitalize))
  150.                 int cnt = 0;
  151.                 foreach (var line in lines)
  152.                 {
  153.                     indexList.Add(new Tuple<string, Tuple<int, String>>(line.ToLower(), new Tuple<int, string>(cnt++, line)));
  154.                 }
  155.                 indexList.Sort(); // sorts. Elements that became same after .ToLower() are sorted depending on their initial position
  156.                 List<String> ans = new List<string>();
  157.                 foreach (var ansLine in indexList)
  158.                 {
  159.                     ans.Add(ansLine.Item2.Item2); // inserting initial elements into answer
  160.                 }
  161.                 if (Reverse) ans.Reverse();
  162.                 if (Unique) ans = ans.Distinct().ToList();
  163.                 return ans;
  164.             }
  165.             lines.Sort();
  166.             if (Reverse) lines.Reverse();
  167.             if (Unique) lines = lines.Distinct().ToList();
  168.            
  169.             return lines;
  170.         }
  171.  
  172.         public static void CheckFlags(string[] args)
  173.         {
  174.             for (int i = 0; i < args.Length; i++) // checking all the flags
  175.             {
  176.                 var flag = args[i];
  177.                 if (flag == "-f" || flag == "--ignore-case")
  178.                 {
  179.                     if(!(args.Contains("-V") || args.Contains("--version-sort") || args.Contains("-n") ||
  180.                          args.Contains("--numeric-sort") || args.Contains("-l") ||
  181.                          args.Contains("--length-sort"))) IgnoreCase = true; // flag can only be added if there are no conflicts
  182.                 }
  183.                 else if (flag == "-r" || flag == "--reverse") Reverse = true;
  184.                 else if (flag == "-u" || flag == "--unique") Unique = true;
  185.                 else if (flag == "-s" || flag == "--symbol-sort") SymbolSort = true;
  186.                 else if (flag == "-l" || flag == "--length-sort")
  187.                 {
  188.                     if(!(args.Contains("-V") || args.Contains("--version-sort") || args.Contains("-n")
  189.                          || args.Contains("--numeric-sort"))) LengthSort = true;  // flag can only be added if there are no conflicts
  190.                 }
  191.                
  192.  
  193.                 else if (flag == "-n" || flag == "--numeric-sort")
  194.                 {
  195.                     NumericSort = true;
  196.                     if (args.Contains("-f") || args.Contains("--ignore-case")) // conflicting flags
  197.                     {
  198.                         Console.WriteLine("I hope that you understand that asking me to sort the file both ignoring " +
  199.                                           "the case and processing only numbers basically removes the effect of the ignore case " +
  200.                                           "flag. You did it just to test me, right? I will sort that anyways though...");
  201.                         IgnoreCase = false;
  202.                     }
  203.  
  204.                     if (args.Contains("-l") || args.Contains("--length-sort")) // conflicting flags
  205.                     {
  206.                         Console.WriteLine(
  207.                             "Conflict between length and numeric sort detected. I will ignore the length sort. Sad :(");
  208.                         LengthSort = false;
  209.                     }
  210.                 }
  211.                 else if (flag == "-o" || Regex.Match(flag, @"--output=.*").Success)
  212.                 {
  213.                     FileOutput = true;
  214.                     if (flag == "-o")
  215.                     {
  216.                         try // trying to get the output file name
  217.                         {
  218.                             OutputFileName = args[i + 1];
  219.                             i++;
  220.                             if (i == args.Length - 1)
  221.                             {
  222.                                 Console.WriteLine("Hmmm... Seems like you didn't specify the output file name.");
  223.                                 return;
  224.                             }
  225.                         }
  226.                         catch (IndexOutOfRangeException)
  227.                         {
  228.                             Console.WriteLine("Hmmm... Seems like you didn't specify the output file name.");
  229.                             return;
  230.                         }
  231.                     }
  232.                     else // if it is --output=...
  233.                     {
  234.                         OutputFileName = flag.Substring(9);
  235.                         if (OutputFileName == "")
  236.                         {
  237.                             Console.WriteLine("Hmmm... Seems like you didn't specify the file name.");
  238.                             return;
  239.                         }
  240.                     }
  241.                 }
  242.                 else if (flag == "-V" || flag == "--version-sort")
  243.                 {
  244.                     VersionSort = true;
  245.                     if (args.Contains("-f") || args.Contains("--ignore-case")) // conflicting flags
  246.                     {
  247.                         Console.WriteLine("I hope that you understand that asking me to sort the file both ignoring " +
  248.                                           "the case and processing only versions basically removes the effect of the ignore case " +
  249.                                           "flag. You did it just to test me, right? I will sort that anyways though...");
  250.                         IgnoreCase = false;
  251.                     }
  252.  
  253.                     if (args.Contains("-n") || args.Contains("--numeric-sort")) // conflicting flags
  254.                     {
  255.                         Console.WriteLine(
  256.                             "Conflict between version and numeric sort flags detected. As it is stated in the Documentation, " +
  257.                             "I will ignore the numeric sort flag and proceed with version sort only.");
  258.                         NumericSort = false;
  259.                     }
  260.  
  261.                     if (args.Contains("-s") || args.Contains("--symbol-sort")) // conflicting flags
  262.                     {
  263.                         Console.WriteLine(
  264.                             "The symbol sort will leave no chance for versions. I will cancel the version sort flag for you...");
  265.                         VersionSort = false;
  266.                     }
  267.  
  268.                     if (args.Contains("-l") || args.Contains("--length-sort")) // conflicting flags
  269.                     {
  270.                         Console.WriteLine(
  271.                             "Conflict between length and version sort detected. I will ignore the length sort.");
  272.                         LengthSort = false;
  273.                     }
  274.                 }
  275.                 else
  276.                 {
  277.                     FileNames.Add(flag);
  278.                 }
  279.             }
  280.         }
  281.  
  282.         public static void Main(string[] args)
  283.         {
  284.             CheckFlags(args);
  285.            
  286.             var linesArray = ReadFile(FileNames); // reading the files
  287.             if (linesArray.Count == 0)
  288.             {
  289.                 Console.WriteLine("Unfortunately, I have nothing to read...");
  290.                 return;
  291.             }
  292.  
  293.             linesArray = SortLines(linesArray);
  294.             Print(FileOutput, linesArray, OutputFileName);
  295.         }
  296.     }
  297. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement