Advertisement
yahorrr

Untitled

Apr 14th, 2022
759
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.34 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3.  
  4. namespace Gcd
  5. {
  6.     /// <summary>
  7.     /// Provide methods with integers.
  8.     /// </summary>
  9.     public static class IntegerExtensions
  10.     {
  11.         /// <summary>
  12.         /// Calculates GCD of two integers from [-int.MaxValue;int.MaxValue] by the Euclidean algorithm.
  13.         /// </summary>
  14.         /// <param name="a">First integer.</param>
  15.         /// <param name="b">Second integer.</param>
  16.         /// <returns>The GCD value.</returns>
  17.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  18.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or two numbers are int.MinValue.</exception>
  19.         public static int GetGcdByEuclidean(int a, int b)
  20.         {
  21.             if (a == int.MinValue)
  22.             {
  23.                 throw new ArgumentOutOfRangeException(nameof(a), "Argument a out of range");
  24.             }
  25.  
  26.             if (b == int.MinValue)
  27.             {
  28.                 throw new ArgumentOutOfRangeException(nameof(b), "Argument b out of range");
  29.             }
  30.  
  31.             a = Math.Abs(a);
  32.             b = Math.Abs(b);
  33.  
  34.             if (a == 0 && b == 0)
  35.             {
  36.                 throw new ArgumentException("Argument's can't be 0 at the same time", nameof(a));
  37.             }
  38.  
  39.             while (a != 0 && b != 0)
  40.             {
  41.                 if (a > b)
  42.                 {
  43.                     a = a % b;
  44.                 }
  45.                 else
  46.                 {
  47.                     b = b % a;
  48.                 }
  49.             }
  50.  
  51.             return a + b;
  52.         }
  53.  
  54.         /// <summary>
  55.         /// Calculates GCD of three integers from [-int.MaxValue;int.MaxValue] by the Euclidean algorithm.
  56.         /// </summary>
  57.         /// <param name="a">First integer.</param>
  58.         /// <param name="b">Second integer.</param>
  59.         /// <param name="c">Third integer.</param>
  60.         /// <returns>The GCD value.</returns>
  61.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  62.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>
  63.         public static int GetGcdByEuclidean(int a, int b, int c)
  64.         {
  65.             if (a == int.MinValue)
  66.             {
  67.                 throw new ArgumentOutOfRangeException(nameof(a), "Argument a out of range");
  68.             }
  69.  
  70.             if (b == int.MinValue)
  71.             {
  72.                 throw new ArgumentOutOfRangeException(nameof(b), "Argument b out of range");
  73.             }
  74.  
  75.             if (c == int.MinValue)
  76.             {
  77.                 throw new ArgumentOutOfRangeException(nameof(c), "Argument c out of range");
  78.             }
  79.  
  80.             if (a == 0 && b == 0 && c == 0)
  81.             {
  82.                 throw new ArgumentException("Argument's can't be 0 at the same time", nameof(a));
  83.             }
  84.  
  85.             a = Math.Abs(a);
  86.             b = Math.Abs(b);
  87.             c = Math.Abs(c);
  88.  
  89.             while (a != 0 && b != 0)
  90.             {
  91.                 if (a > b)
  92.                 {
  93.                     a = a % b;
  94.                 }
  95.                 else
  96.                 {
  97.                     b = b % a;
  98.                 }
  99.             }
  100.  
  101.             int n = a + b;
  102.  
  103.             while (n != 0 && c != 0)
  104.             {
  105.                 if (n > c)
  106.                 {
  107.                     n = n % c;
  108.                 }
  109.                 else
  110.                 {
  111.                     c = c % n;
  112.                 }
  113.             }
  114.  
  115.             return c + n;
  116.         }
  117.  
  118.         /// <summary>
  119.         /// Calculates the GCD of integers from [-int.MaxValue;int.MaxValue] by the Euclidean algorithm.
  120.         /// </summary>
  121.         /// <param name="a">First integer.</param>
  122.         /// <param name="b">Second integer.</param>
  123.         /// <param name="other">Other integers.</param>
  124.         /// <returns>The GCD value.</returns>
  125.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  126.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>      
  127.         public static int GetGcdByEuclidean(int a, int b, params int[] other)
  128.         {
  129.             if (a == int.MinValue || b == int.MinValue || IsMinValue(other))
  130.             {
  131.                 throw new ArgumentOutOfRangeException(nameof(a), "Argument a out of range");
  132.             }
  133.  
  134.             if (a == 0 && b == 0 && AllZeros(other))
  135.             {
  136.                 throw new ArgumentException("Argument's can't be 0 at the same time", nameof(a));
  137.             }
  138.  
  139.             a = Math.Abs(a);
  140.             b = Math.Abs(b);
  141.             AbsArray(other);
  142.  
  143.             while (a != 0 && b != 0)
  144.             {
  145.                 if (a > b)
  146.                 {
  147.                     a = a % b;
  148.                 }
  149.                 else
  150.                 {
  151.                     b = b % a;
  152.                 }
  153.             }
  154.  
  155.             int gcd = a + b;
  156.  
  157.             for (int i = 0; i < other.Length; i++)
  158.             {
  159.                 while (gcd != 0 && other[i] != 0)
  160.                 {
  161.                     if (gcd > other[i])
  162.                     {
  163.                         gcd = gcd % other[i];
  164.                     }
  165.                     else
  166.                     {
  167.                         other[i] = other[i] % gcd;
  168.                     }
  169.                 }
  170.  
  171.                 gcd = gcd + other[i];
  172.             }
  173.  
  174.             return gcd;
  175.         }
  176.  
  177.         public static bool AllZeros(int[] array)
  178.         {
  179.             if (array == null)
  180.             {
  181.                 throw new ArgumentNullException(nameof(array));
  182.             }
  183.  
  184.             for (int i = 0; i < array.Length; i++)
  185.             {
  186.                 if (array[i] != 0)
  187.                 {
  188.                     return false;
  189.                 }
  190.             }
  191.  
  192.             return true;
  193.         }
  194.  
  195.         public static bool IsMinValue(int[] array)
  196.         {
  197.             if (array == null)
  198.             {
  199.                 throw new ArgumentNullException(nameof(array));
  200.             }
  201.  
  202.             for (int i = 0; i < array.Length; i++)
  203.             {
  204.                 if (array[i] == int.MinValue)
  205.                 {
  206.                     return true;
  207.                 }
  208.             }
  209.  
  210.             return false;
  211.         }
  212.  
  213.         public static void AbsArray(int[] array)
  214.         {
  215.             if (array == null)
  216.             {
  217.                 throw new ArgumentNullException(nameof(array));
  218.             }
  219.  
  220.             for (int i = 0; i < array.Length; i++)
  221.             {
  222.                 array[i] = Math.Abs(array[i]);
  223.             }
  224.         }
  225.  
  226.         /// <summary>
  227.         /// Calculates GCD of two integers [-int.MaxValue;int.MaxValue] by the Stein algorithm.
  228.         /// </summary>
  229.         /// <param name="a">First integer.</param>
  230.         /// <param name="b">Second integer.</param>
  231.         /// <returns>The GCD value.</returns>
  232.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  233.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or two numbers are int.MinValue.</exception>
  234.         public static int GetGcdByStein(int a, int b)
  235.         {
  236.             if (a == int.MinValue)
  237.             {
  238.                 throw new ArgumentOutOfRangeException(nameof(a), "Argument a out of range");
  239.             }
  240.  
  241.             if (b == int.MinValue)
  242.             {
  243.                 throw new ArgumentOutOfRangeException(nameof(b), "Argument b out of range");
  244.             }
  245.  
  246.             if (a == 0 && b == 0)
  247.             {
  248.                 throw new ArgumentException("Argument's can't be 0 at the same time", nameof(a));
  249.             }
  250.  
  251.             a = Math.Abs(a);
  252.             b = Math.Abs(b);
  253.  
  254.             if (a == 0)
  255.             {
  256.                 return b;
  257.             }
  258.             else if (b == 0)
  259.             {
  260.                 return a;
  261.             }
  262.             else if (a == b)
  263.             {
  264.                 return a;
  265.             }
  266.             else if (a % 2 == 0 && b % 2 == 0)
  267.             {
  268.                 return 2 * GetGcdByStein(a / 2, b / 2);
  269.             }
  270.             else if (a % 2 == 0 && b % 2 != 0)
  271.             {
  272.                 return GetGcdByStein(a / 2, b);
  273.             }
  274.             else if (a % 2 != 0 && b % 2 == 0)
  275.             {
  276.                 return GetGcdByStein(a, b / 2);
  277.             }
  278.             else if (a > b)
  279.             {
  280.                 return GetGcdByStein((a - b) / 2, b);
  281.             }
  282.             else
  283.             {
  284.                 return GetGcdByStein((b - a) / 2, a);
  285.             }
  286.         }
  287.  
  288.         /// <summary>
  289.         /// Calculates GCD of three integers [-int.MaxValue;int.MaxValue] by the Stein algorithm.
  290.         /// </summary>
  291.         /// <param name="a">First integer.</param>
  292.         /// <param name="b">Second integer.</param>
  293.         /// <param name="c">Third integer.</param>
  294.         /// <returns>The GCD value.</returns>
  295.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  296.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>
  297.         public static int GetGcdByStein(int a, int b, int c)
  298.         {
  299.             if (a == int.MinValue)
  300.             {
  301.                 throw new ArgumentOutOfRangeException(nameof(a), "Argument a out of range");
  302.             }
  303.  
  304.             if (b == int.MinValue)
  305.             {
  306.                 throw new ArgumentOutOfRangeException(nameof(b), "Argument b out of range");
  307.             }
  308.  
  309.             if (c == int.MinValue)
  310.             {
  311.                 throw new ArgumentOutOfRangeException(nameof(c), "Argument c out of range");
  312.             }
  313.  
  314.             if (a == 0 && b == 0 && c == 0)
  315.             {
  316.                 throw new ArgumentException("Argument's can't be 0 at the same time", nameof(a));
  317.             }
  318.  
  319.             a = Math.Abs(a);
  320.             b = Math.Abs(b);
  321.             c = Math.Abs(c);
  322.  
  323.             if (a == 0)
  324.             {
  325.                 return GetGcdByStein(b, c);
  326.             }
  327.             else if (b == 0)
  328.             {
  329.                 return GetGcdByStein(a, c);
  330.             }
  331.             else if (a == b)
  332.             {
  333.                 return GetGcdByStein(a, c);
  334.             }
  335.             else if (a % 2 == 0 && b % 2 == 0)
  336.             {
  337.                 return GetGcdByStein(2 * GetGcdByStein(a / 2, b / 2), c);
  338.             }
  339.             else if (a % 2 == 0 && b % 2 != 0)
  340.             {
  341.                 return GetGcdByStein(GetGcdByStein(a / 2, b), c);
  342.             }
  343.             else if (a % 2 != 0 && b % 2 == 0)
  344.             {
  345.                 return GetGcdByStein(GetGcdByStein(a, b / 2), c);
  346.             }
  347.             else if (a > b)
  348.             {
  349.                 return GetGcdByStein(GetGcdByStein((a - b) / 2, b), c);
  350.             }
  351.             else
  352.             {
  353.                 return GetGcdByStein(GetGcdByStein((b - a) / 2, a), c);
  354.             }
  355.         }
  356.  
  357.         /// <summary>
  358.         /// Calculates the GCD of integers [-int.MaxValue;int.MaxValue] by the Stein algorithm.
  359.         /// </summary>
  360.         /// <param name="a">First integer.</param>
  361.         /// <param name="b">Second integer.</param>
  362.         /// <param name="other">Other integers.</param>
  363.         /// <returns>The GCD value.</returns>
  364.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  365.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>
  366.         public static int GetGcdByStein(int a, int b, params int[] other)
  367.         {
  368.             if (a == int.MinValue || b == int.MinValue || IsMinValue(other))
  369.             {
  370.                 throw new ArgumentOutOfRangeException(nameof(a), "Argument a out of range");
  371.             }
  372.  
  373.             if (a == 0 && b == 0 && AllZeros(other))
  374.             {
  375.                 throw new ArgumentException("Argument's can't be 0 at the same time", nameof(a));
  376.             }
  377.  
  378.             a = Math.Abs(a);
  379.             b = Math.Abs(b);
  380.             AbsArray(other);
  381.  
  382.             int gcd = 1;
  383.  
  384.             if (!AllZeros(other))
  385.             {
  386.                 gcd = other[0];
  387.                 for (int i = 0; i < other.Length - 1; i++)
  388.                 {
  389.                     gcd = GetGcdByStein(gcd, other[i + 1]);
  390.                 }
  391.             }          
  392.  
  393.             if (a == 0)
  394.             {
  395.                 return GetGcdByStein(b, gcd);
  396.             }
  397.             else if (b == 0)
  398.             {
  399.                 return GetGcdByStein(a, gcd);
  400.             }
  401.             else if (a == b)
  402.             {
  403.                 return GetGcdByStein(a, gcd);
  404.             }
  405.             else if (a % 2 == 0 && b % 2 == 0)
  406.             {
  407.                 return GetGcdByStein(2 * GetGcdByStein(a / 2, b / 2), gcd);
  408.             }
  409.             else if (a % 2 == 0 && b % 2 != 0)
  410.             {
  411.                 return GetGcdByStein(GetGcdByStein(a / 2, b), gcd);
  412.             }
  413.             else if (a % 2 != 0 && b % 2 == 0)
  414.             {
  415.                 return GetGcdByStein(GetGcdByStein(a, b / 2), gcd);
  416.             }
  417.             else if (a > b)
  418.             {
  419.                 return GetGcdByStein(GetGcdByStein((a - b) / 2, b), gcd);
  420.             }
  421.             else
  422.             {
  423.                 return GetGcdByStein(GetGcdByStein((b - a) / 2, a), gcd);
  424.             }
  425.         }
  426.  
  427.         /// <summary>
  428.         /// Calculates GCD of two integers from [-int.MaxValue;int.MaxValue] by the Euclidean algorithm with elapsed time.
  429.         /// </summary>
  430.         /// <param name="elapsedTicks">Method execution time in ticks.</param>
  431.         /// <param name="a">First integer.</param>
  432.         /// <param name="b">Second integer.</param>
  433.         /// <returns>The GCD value.</returns>
  434.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  435.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or two numbers are int.MinValue.</exception>
  436.         public static int GetGcdByEuclidean(out long elapsedTicks, int a, int b)
  437.         {
  438.             var timer = new Stopwatch();
  439.             timer.Start();
  440.             int result = GetGcdByEuclidean(a, b);
  441.             timer.Stop();
  442.             elapsedTicks = timer.ElapsedTicks;
  443.  
  444.             return result;
  445.         }
  446.  
  447.         /// <summary>
  448.         /// Calculates GCD of three integers from [-int.MaxValue;int.MaxValue] by the Euclidean algorithm with elapsed time.
  449.         /// </summary>
  450.         /// <param name="elapsedTicks">Method execution time in ticks.</param>
  451.         /// <param name="a">First integer.</param>
  452.         /// <param name="b">Second integer.</param>
  453.         /// <param name="c">Third integer.</param>
  454.         /// <returns>The GCD value.</returns>
  455.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  456.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>
  457.         public static int GetGcdByEuclidean(out long elapsedTicks, int a, int b, int c)
  458.         {
  459.             var timer = new Stopwatch();
  460.             timer.Start();
  461.             int result = GetGcdByEuclidean(a, b, c);
  462.             timer.Stop();
  463.             elapsedTicks = timer.ElapsedTicks;
  464.  
  465.             return result;
  466.         }
  467.  
  468.         /// <summary>
  469.         /// Calculates the GCD of integers from [-int.MaxValue;int.MaxValue] by the Euclidean algorithm with elapsed time.
  470.         /// </summary>
  471.         /// <param name="elapsedTicks">Method execution time in Ticks.</param>
  472.         /// <param name="a">First integer.</param>
  473.         /// <param name="b">Second integer.</param>
  474.         /// <param name="other">Other integers.</param>
  475.         /// <returns>The GCD value.</returns>
  476.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  477.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>
  478.         public static int GetGcdByEuclidean(out long elapsedTicks, int a, int b, params int[] other)
  479.         {
  480.             var timer = new Stopwatch();
  481.             timer.Start();
  482.             int result = GetGcdByEuclidean(a, b, other);
  483.             timer.Stop();
  484.             elapsedTicks = timer.ElapsedTicks;
  485.  
  486.             return result;
  487.         }
  488.  
  489.         /// <summary>
  490.         /// Calculates GCD of two integers from [-int.MaxValue;int.MaxValue] by the Stein algorithm with elapsed time.
  491.         /// </summary>
  492.         /// <param name="elapsedTicks">Method execution time in ticks.</param>
  493.         /// <param name="a">First integer.</param>
  494.         /// <param name="b">Second integer.</param>
  495.         /// <returns>The GCD value.</returns>
  496.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  497.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or two numbers are int.MinValue.</exception>
  498.         public static int GetGcdByStein(out long elapsedTicks, int a, int b)
  499.         {
  500.             var timer = new Stopwatch();
  501.             timer.Start();
  502.             int result = GetGcdByStein(a, b);
  503.             timer.Stop();
  504.             elapsedTicks = timer.ElapsedTicks;
  505.  
  506.             return result;
  507.         }
  508.  
  509.         /// <summary>
  510.         /// Calculates GCD of three integers from [-int.MaxValue;int.MaxValue] by the Stein algorithm with elapsed time.
  511.         /// </summary>
  512.         /// <param name="elapsedTicks">Method execution time in ticks.</param>
  513.         /// <param name="a">First integer.</param>
  514.         /// <param name="b">Second integer.</param>
  515.         /// <param name="c">Third integer.</param>
  516.         /// <returns>The GCD value.</returns>
  517.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  518.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>
  519.         public static int GetGcdByStein(out long elapsedTicks, int a, int b, int c)
  520.         {
  521.             var timer = new Stopwatch();
  522.             timer.Start();
  523.             int result = GetGcdByStein(a, b, c);
  524.             timer.Stop();
  525.             elapsedTicks = timer.ElapsedTicks;
  526.  
  527.             return result;
  528.         }
  529.  
  530.         /// <summary>
  531.         /// Calculates the GCD of integers from [-int.MaxValue;int.MaxValue] by the Stein algorithm with elapsed time.
  532.         /// </summary>
  533.         /// <param name="elapsedTicks">Method execution time in Ticks.</param>
  534.         /// <param name="a">First integer.</param>
  535.         /// <param name="b">Second integer.</param>
  536.         /// <param name="other">Other integers.</param>
  537.         /// <returns>The GCD value.</returns>
  538.         /// <exception cref="ArgumentException">Thrown when all numbers are 0 at the same time.</exception>
  539.         /// <exception cref="ArgumentOutOfRangeException">Thrown when one or more numbers are int.MinValue.</exception>
  540.         public static int GetGcdByStein(out long elapsedTicks, int a, int b, params int[] other)
  541.         {
  542.             var timer = new Stopwatch();
  543.             timer.Start();
  544.             int result = GetGcdByStein(a, b, other);
  545.             timer.Stop();
  546.             elapsedTicks = timer.ElapsedTicks;
  547.  
  548.             return result;
  549.         }
  550.     }
  551. }
  552.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement