Skip to main content
Rollback to Revision 4
Source Link
Heslacher
  • 51k
  • 5
  • 83
  • 177

Updated Code, based on suggestions of J_H.

Changes:

  1. Removed try catch block for IndexOutOfRange exceptions. Exceptions are now prevented, instead of being caught. J_H suggested "padding" the array, which would probably be more effective, since I could get rid of the checks, but I didn't want to do this due to the way the code integrates into the rest of the program. - massive performance increase, 5000*6000 array with distThreshold = 10 and countThreshold = 3 is now processed in ~24 seconds
  2. Dictionary is now initiated only once, instance of it is passed into the dupeCount function and then cleared - noticeable performance increase as well, the same array as in point 1. is now processed in ~20 seconds
using System;
using System.Collections.Generic;
using System.Linq;

namespace ArrayCorrection
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("test");
            testArr();
        }

        public static int[][] correctedArray(int distThreshold, int countThreshold, int[][] arr)
        {
            int[][] newArray = arrCopy(arr);
            //dictionary initialized here now, instance is passed into the dupeCount function and cleared after use
            Dictionary<int, int> colorCounts = new Dictionary<int, int>();
            for (int j = 0; j < arr.Length; j++)
            {
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int[] dcfac = dupeCountForAutoCorrect(i, j, distThreshold, countThreshold, arr, colorCounts);
                    colorCounts.Clear();
                    int dupeCount = dcfac[0];
                    int replacementIndex = dcfac[1];
                    if (dupeCount <= countThreshold)
                    {
                        newArray[j][i] = replacementIndex;
                    }
                }
            }
            return newArray;
        }

        private static int[] dupeCountForAutoCorrect(int x, int y, int distThreshold, int countThreshold, int[][] arr, Dictionary<int, int> colorCounts)
        {
            int testedIndex = arr[y][x];
            int[] result = new int[2];

            for (int j = y - distThreshold; j <= y + distThreshold; j++)
            {
                for (int i = x - distThreshold; i <= x + distThreshold; i++)
                {
                    //the conditions were changed to never throw exceptions, try catch removed
                    if (!(i == x && j == y) && i > 0 && j > 0 && i < arr[0].Length && j < arr.Length)
                    {
                        int currentIndex = arr[j][i];
                        if (currentIndex == testedIndex) result[0]++;
                        if (result[0] > countThreshold) return result;
                        if (colorCounts.TryGetValue(currentIndex, out int value))
                        {
                            value++;
                            colorCounts[currentIndex] = value;
                        }
                        else
                        {
                            colorCounts.Add(currentIndex, 1);
                        }

                    }
                }
            }
            //returns the index with highest count. I don't understand this at all, ripped from Stack Overflow
            result[1] = colorCounts.Aggregate((xx, yy) => xx.Value > yy.Value ? xx : yy).Key;
            return result;
        }

        public static void testArr()
        {
            int maxIndex = 5;

            int arrWidth = 5000;
            int arrHeight = 6000;

            int distThreshold = 10;
            int countThreshold = 3;

            int[][] originalArray = new int[arrHeight][];
            Random rnd = new Random();
            for (int j = 0; j < arrHeight; j++)
            {
                int[] r = new int[arrWidth];
                for (int i = 0; i < arrWidth; i++)
                {
                    int rndn = rnd.Next(maxIndex + 1); ;
                    r[i] = rndn;
                }
                originalArray[j] = r;
            }
            DateTime nao = DateTime.Now;
            int[][] newArr = correctedArray(distThreshold, countThreshold, originalArray);
            Console.WriteLine((DateTime.Now - nao).TotalSeconds.ToString() + "seconds");

            //string origArrString = arrToString(originalArray);
            //string newArrString = arrToString(newArr);
            //Console.Write(origArrString + System.Environment.NewLine + newArrString);
        }
        public static string arrToString(int[][] arr)
        {
            string result = "";
            for (int j = 0; j < arr.Length; j++)
            {
                result += "[";
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int val = arr[j][i];
                    result += val + (i == arr[0].Length - 1 ? "]" + System.Environment.NewLine : ", ");
                }
            }
            return result;
        }

        public static int[][] arrCopy(int[][] arr)
        {
            int[][] result = new int[arr.Length][];
            for (int j = 0; j < arr.Length; j++)
            {
                result[j] = new int[arr[0].Length];
                for (int i = 0; i < arr[0].Length; i++)
                {
                    result[j][i] = arr[j][i];
                }
            }
            return result;
        }

    }
}

Updated Code, based on suggestions of J_H.

Changes:

  1. Removed try catch block for IndexOutOfRange exceptions. Exceptions are now prevented, instead of being caught. J_H suggested "padding" the array, which would probably be more effective, since I could get rid of the checks, but I didn't want to do this due to the way the code integrates into the rest of the program. - massive performance increase, 5000*6000 array with distThreshold = 10 and countThreshold = 3 is now processed in ~24 seconds
  2. Dictionary is now initiated only once, instance of it is passed into the dupeCount function and then cleared - noticeable performance increase as well, the same array as in point 1. is now processed in ~20 seconds
using System;
using System.Collections.Generic;
using System.Linq;

namespace ArrayCorrection
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("test");
            testArr();
        }

        public static int[][] correctedArray(int distThreshold, int countThreshold, int[][] arr)
        {
            int[][] newArray = arrCopy(arr);
            //dictionary initialized here now, instance is passed into the dupeCount function and cleared after use
            Dictionary<int, int> colorCounts = new Dictionary<int, int>();
            for (int j = 0; j < arr.Length; j++)
            {
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int[] dcfac = dupeCountForAutoCorrect(i, j, distThreshold, countThreshold, arr, colorCounts);
                    colorCounts.Clear();
                    int dupeCount = dcfac[0];
                    int replacementIndex = dcfac[1];
                    if (dupeCount <= countThreshold)
                    {
                        newArray[j][i] = replacementIndex;
                    }
                }
            }
            return newArray;
        }

        private static int[] dupeCountForAutoCorrect(int x, int y, int distThreshold, int countThreshold, int[][] arr, Dictionary<int, int> colorCounts)
        {
            int testedIndex = arr[y][x];
            int[] result = new int[2];

            for (int j = y - distThreshold; j <= y + distThreshold; j++)
            {
                for (int i = x - distThreshold; i <= x + distThreshold; i++)
                {
                    //the conditions were changed to never throw exceptions, try catch removed
                    if (!(i == x && j == y) && i > 0 && j > 0 && i < arr[0].Length && j < arr.Length)
                    {
                        int currentIndex = arr[j][i];
                        if (currentIndex == testedIndex) result[0]++;
                        if (result[0] > countThreshold) return result;
                        if (colorCounts.TryGetValue(currentIndex, out int value))
                        {
                            value++;
                            colorCounts[currentIndex] = value;
                        }
                        else
                        {
                            colorCounts.Add(currentIndex, 1);
                        }

                    }
                }
            }
            //returns the index with highest count. I don't understand this at all, ripped from Stack Overflow
            result[1] = colorCounts.Aggregate((xx, yy) => xx.Value > yy.Value ? xx : yy).Key;
            return result;
        }

        public static void testArr()
        {
            int maxIndex = 5;

            int arrWidth = 5000;
            int arrHeight = 6000;

            int distThreshold = 10;
            int countThreshold = 3;

            int[][] originalArray = new int[arrHeight][];
            Random rnd = new Random();
            for (int j = 0; j < arrHeight; j++)
            {
                int[] r = new int[arrWidth];
                for (int i = 0; i < arrWidth; i++)
                {
                    int rndn = rnd.Next(maxIndex + 1); ;
                    r[i] = rndn;
                }
                originalArray[j] = r;
            }
            DateTime nao = DateTime.Now;
            int[][] newArr = correctedArray(distThreshold, countThreshold, originalArray);
            Console.WriteLine((DateTime.Now - nao).TotalSeconds.ToString() + "seconds");

            //string origArrString = arrToString(originalArray);
            //string newArrString = arrToString(newArr);
            //Console.Write(origArrString + System.Environment.NewLine + newArrString);
        }
        public static string arrToString(int[][] arr)
        {
            string result = "";
            for (int j = 0; j < arr.Length; j++)
            {
                result += "[";
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int val = arr[j][i];
                    result += val + (i == arr[0].Length - 1 ? "]" + System.Environment.NewLine : ", ");
                }
            }
            return result;
        }

        public static int[][] arrCopy(int[][] arr)
        {
            int[][] result = new int[arr.Length][];
            for (int j = 0; j < arr.Length; j++)
            {
                result[j] = new int[arr[0].Length];
                for (int i = 0; i < arr[0].Length; i++)
                {
                    result[j][i] = arr[j][i];
                }
            }
            return result;
        }

    }
}
added 4960 characters in body
Source Link
andrewb
  • 113
  • 4

Updated Code, based on suggestions of J_H.

Changes:

  1. Removed try catch block for IndexOutOfRange exceptions. Exceptions are now prevented, instead of being caught. J_H suggested "padding" the array, which would probably be more effective, since I could get rid of the checks, but I didn't want to do this due to the way the code integrates into the rest of the program. - massive performance increase, 5000*6000 array with distThreshold = 10 and countThreshold = 3 is now processed in ~24 seconds
  2. Dictionary is now initiated only once, instance of it is passed into the dupeCount function and then cleared - noticeable performance increase as well, the same array as in point 1. is now processed in ~20 seconds
using System;
using System.Collections.Generic;
using System.Linq;

namespace ArrayCorrection
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("test");
            testArr();
        }

        public static int[][] correctedArray(int distThreshold, int countThreshold, int[][] arr)
        {
            int[][] newArray = arrCopy(arr);
            //dictionary initialized here now, instance is passed into the dupeCount function and cleared after use
            Dictionary<int, int> colorCounts = new Dictionary<int, int>();
            for (int j = 0; j < arr.Length; j++)
            {
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int[] dcfac = dupeCountForAutoCorrect(i, j, distThreshold, countThreshold, arr, colorCounts);
                    colorCounts.Clear();
                    int dupeCount = dcfac[0];
                    int replacementIndex = dcfac[1];
                    if (dupeCount <= countThreshold)
                    {
                        newArray[j][i] = replacementIndex;
                    }
                }
            }
            return newArray;
        }

        private static int[] dupeCountForAutoCorrect(int x, int y, int distThreshold, int countThreshold, int[][] arr, Dictionary<int, int> colorCounts)
        {
            int testedIndex = arr[y][x];
            int[] result = new int[2];

            for (int j = y - distThreshold; j <= y + distThreshold; j++)
            {
                for (int i = x - distThreshold; i <= x + distThreshold; i++)
                {
                    //the conditions were changed to never throw exceptions, try catch removed
                    if (!(i == x && j == y) && i > 0 && j > 0 && i < arr[0].Length && j < arr.Length)
                    {
                        int currentIndex = arr[j][i];
                        if (currentIndex == testedIndex) result[0]++;
                        if (result[0] > countThreshold) return result;
                        if (colorCounts.TryGetValue(currentIndex, out int value))
                        {
                            value++;
                            colorCounts[currentIndex] = value;
                        }
                        else
                        {
                            colorCounts.Add(currentIndex, 1);
                        }

                    }
                }
            }
            //returns the index with highest count. I don't understand this at all, ripped from Stack Overflow
            result[1] = colorCounts.Aggregate((xx, yy) => xx.Value > yy.Value ? xx : yy).Key;
            return result;
        }

        public static void testArr()
        {
            int maxIndex = 5;

            int arrWidth = 5000;
            int arrHeight = 6000;

            int distThreshold = 10;
            int countThreshold = 3;

            int[][] originalArray = new int[arrHeight][];
            Random rnd = new Random();
            for (int j = 0; j < arrHeight; j++)
            {
                int[] r = new int[arrWidth];
                for (int i = 0; i < arrWidth; i++)
                {
                    int rndn = rnd.Next(maxIndex + 1); ;
                    r[i] = rndn;
                }
                originalArray[j] = r;
            }
            DateTime nao = DateTime.Now;
            int[][] newArr = correctedArray(distThreshold, countThreshold, originalArray);
            Console.WriteLine((DateTime.Now - nao).TotalSeconds.ToString() + "seconds");

            //string origArrString = arrToString(originalArray);
            //string newArrString = arrToString(newArr);
            //Console.Write(origArrString + System.Environment.NewLine + newArrString);
        }
        public static string arrToString(int[][] arr)
        {
            string result = "";
            for (int j = 0; j < arr.Length; j++)
            {
                result += "[";
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int val = arr[j][i];
                    result += val + (i == arr[0].Length - 1 ? "]" + System.Environment.NewLine : ", ");
                }
            }
            return result;
        }

        public static int[][] arrCopy(int[][] arr)
        {
            int[][] result = new int[arr.Length][];
            for (int j = 0; j < arr.Length; j++)
            {
                result[j] = new int[arr[0].Length];
                for (int i = 0; i < arr[0].Length; i++)
                {
                    result[j][i] = arr[j][i];
                }
            }
            return result;
        }

    }
}

Updated Code, based on suggestions of J_H.

Changes:

  1. Removed try catch block for IndexOutOfRange exceptions. Exceptions are now prevented, instead of being caught. J_H suggested "padding" the array, which would probably be more effective, since I could get rid of the checks, but I didn't want to do this due to the way the code integrates into the rest of the program. - massive performance increase, 5000*6000 array with distThreshold = 10 and countThreshold = 3 is now processed in ~24 seconds
  2. Dictionary is now initiated only once, instance of it is passed into the dupeCount function and then cleared - noticeable performance increase as well, the same array as in point 1. is now processed in ~20 seconds
using System;
using System.Collections.Generic;
using System.Linq;

namespace ArrayCorrection
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("test");
            testArr();
        }

        public static int[][] correctedArray(int distThreshold, int countThreshold, int[][] arr)
        {
            int[][] newArray = arrCopy(arr);
            //dictionary initialized here now, instance is passed into the dupeCount function and cleared after use
            Dictionary<int, int> colorCounts = new Dictionary<int, int>();
            for (int j = 0; j < arr.Length; j++)
            {
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int[] dcfac = dupeCountForAutoCorrect(i, j, distThreshold, countThreshold, arr, colorCounts);
                    colorCounts.Clear();
                    int dupeCount = dcfac[0];
                    int replacementIndex = dcfac[1];
                    if (dupeCount <= countThreshold)
                    {
                        newArray[j][i] = replacementIndex;
                    }
                }
            }
            return newArray;
        }

        private static int[] dupeCountForAutoCorrect(int x, int y, int distThreshold, int countThreshold, int[][] arr, Dictionary<int, int> colorCounts)
        {
            int testedIndex = arr[y][x];
            int[] result = new int[2];

            for (int j = y - distThreshold; j <= y + distThreshold; j++)
            {
                for (int i = x - distThreshold; i <= x + distThreshold; i++)
                {
                    //the conditions were changed to never throw exceptions, try catch removed
                    if (!(i == x && j == y) && i > 0 && j > 0 && i < arr[0].Length && j < arr.Length)
                    {
                        int currentIndex = arr[j][i];
                        if (currentIndex == testedIndex) result[0]++;
                        if (result[0] > countThreshold) return result;
                        if (colorCounts.TryGetValue(currentIndex, out int value))
                        {
                            value++;
                            colorCounts[currentIndex] = value;
                        }
                        else
                        {
                            colorCounts.Add(currentIndex, 1);
                        }

                    }
                }
            }
            //returns the index with highest count. I don't understand this at all, ripped from Stack Overflow
            result[1] = colorCounts.Aggregate((xx, yy) => xx.Value > yy.Value ? xx : yy).Key;
            return result;
        }

        public static void testArr()
        {
            int maxIndex = 5;

            int arrWidth = 5000;
            int arrHeight = 6000;

            int distThreshold = 10;
            int countThreshold = 3;

            int[][] originalArray = new int[arrHeight][];
            Random rnd = new Random();
            for (int j = 0; j < arrHeight; j++)
            {
                int[] r = new int[arrWidth];
                for (int i = 0; i < arrWidth; i++)
                {
                    int rndn = rnd.Next(maxIndex + 1); ;
                    r[i] = rndn;
                }
                originalArray[j] = r;
            }
            DateTime nao = DateTime.Now;
            int[][] newArr = correctedArray(distThreshold, countThreshold, originalArray);
            Console.WriteLine((DateTime.Now - nao).TotalSeconds.ToString() + "seconds");

            //string origArrString = arrToString(originalArray);
            //string newArrString = arrToString(newArr);
            //Console.Write(origArrString + System.Environment.NewLine + newArrString);
        }
        public static string arrToString(int[][] arr)
        {
            string result = "";
            for (int j = 0; j < arr.Length; j++)
            {
                result += "[";
                for (int i = 0; i < arr[0].Length; i++)
                {
                    int val = arr[j][i];
                    result += val + (i == arr[0].Length - 1 ? "]" + System.Environment.NewLine : ", ");
                }
            }
            return result;
        }

        public static int[][] arrCopy(int[][] arr)
        {
            int[][] result = new int[arr.Length][];
            for (int j = 0; j < arr.Length; j++)
            {
                result[j] = new int[arr[0].Length];
                for (int i = 0; i < arr[0].Length; i++)
                {
                    result[j][i] = arr[j][i];
                }
            }
            return result;
        }

    }
}
edited tags
Link
Peter Csala
  • 10.8k
  • 1
  • 16
  • 36
added 361 characters in body
Source Link
andrewb
  • 113
  • 4
Loading
added 8 characters in body
Source Link
Peter Csala
  • 10.8k
  • 1
  • 16
  • 36
Loading
Source Link
andrewb
  • 113
  • 4
Loading