C# 带素数检验的三角形中的最大路径和

C# 带素数检验的三角形中的最大路径和,c#,algorithm,primes,C#,Algorithm,Primes,我被赋予这个算法任务: 您将在下面输入一个三角形,您需要根据下面给定的规则找到数字的最大和 您将从顶部开始,向下移动到相邻的数字,如下图所示 您只能向下和斜向行走 您只能遍历非素数 1 8 4 2 6 9 8 5 9 3 正如你所看到的,这有几个符合非素数规则的路径;1>8>6>9, 1>4>6>9, 1>4>9>9 1 + 8 + 6 + 9 = 24. 正如你看到的,1,8,6,9都不是素数,遍历这些得到最大和 根据以上规则,以下输入的最大和是多少?这

我被赋予这个算法任务:

您将在下面输入一个三角形,您需要根据下面给定的规则找到数字的最大和

  • 您将从顶部开始,向下移动到相邻的数字,如下图所示
  • 您只能向下和斜向行走
  • 您只能遍历非素数

         1
        8 4
      2  6  9
     8  5  9  3
    
  • 正如你所看到的,这有几个符合非素数规则的路径;1>8>6>9, 1>4>6>9, 1>4>9>9 1 + 8 + 6 + 9 = 24. 正如你看到的,1,8,6,9都不是素数,遍历这些得到最大和

    根据以上规则,以下输入的最大和是多少?这意味着请将此金字塔作为实现的输入(作为文件或代码中的常量),并使用它进行求解

                                      215
                                   193 124
                                 117 237 442
                               218 935 347 235
                             320 804 522 417 345
                           229 601 723 835 133 124
                         248 202 277 433 207 263 257
                       359 464 504 528 516 716 871 182
                     461 441 426 656 863 560 380 171 923
                   381 348 573 533 447 632 387 176 975 449
                 223 711 445 645 245 543 931 532 937 541 444
               330 131 333 928 377 733 017 778 839 168 197 197
            131 171 522 137 217 224 291 413 528 520 227 229 928
          223 626 034 683 839 053 627 310 713 999 629 817 410 121
        924 622 911 233 325 139 721 218 253 223 107 233 230 124 233
    
    请注意,这里每个节点只有两个子节点(最下面的子节点除外)。例如,您可以从215走到124(因为193是素数),然后从124走到237或442。你不能从124转到117,因为它不是124的直系子女

    我知道有不同的方法可以解决这个问题

    • 蛮力法

    • 动态规划法

    由于其效率,我使用了动态规划方法:

    using System;
    
    class Program
    {
        static void Main(string[] args)
        {
    
    
            //get input
            var input = GetInput();
    
            string[] arrayOfRowsByNewlines = input.Split('\n');
    
            var tableHolder = FlattenTheTriangleIntoTable(arrayOfRowsByNewlines);
    
            var result = WalkThroughTheNode(arrayOfRowsByNewlines, tableHolder);
    
            Console.WriteLine($"The Maximum Total Sum Of Non-Prime Numbers From Top To Bottom Is:  {result[0,0]}");
    
            Console.ReadKey();
        }
    
        private static string GetInput()
        {
    
                const string input = @"   215
                                       193 124
                                      117 237 442
                                    218 935 347 235
                                  320 804 522 417 345
                                229 601 723 835 133 124
                              248 202 277 433 207 263 257
                            359 464 504 528 516 716 871 182
                          461 441 426 656 863 560 380 171 923
                         381 348 573 533 447 632 387 176 975 449
                       223 711 445 645 245 543 931 532 937 541 444
                     330 131 333 928 377 733 017 778 839 168 197 197
                    131 171 522 137 217 224 291 413 528 520 227 229 928
                  223 626 034 683 839 053 627 310 713 999 629 817 410 121
                924 622 911 233 325 139 721 218 253 223 107 233 230 124 233";
            return input;
        }
    
        private static int[,] WalkThroughTheNode(string[] arrayOfRowsByNewlines, int[,] tableHolder)
        {
            // walking through the non-prime node
            for (int i = arrayOfRowsByNewlines.Length - 2; i >= 0; i--)
            {
                for (int j = 0; j < arrayOfRowsByNewlines.Length; j++)
                {
                    //only sum through the non-prime node
                    if ((!IsPrime(tableHolder[i, j])))
                    {
                        tableHolder[i, j] = Math.Max(tableHolder[i, j] + tableHolder[i + 1, j],
                            tableHolder[i, j] + tableHolder[i + 1, j + 1]);
                    }
                }
            }
            return tableHolder;
        }
    
        private static int[,] FlattenTheTriangleIntoTable(string[] arrayOfRowsByNewlines)
        {
            int[,] tableHolder = new int[arrayOfRowsByNewlines.Length, arrayOfRowsByNewlines.Length + 1];
    
            for (int row = 0; row < arrayOfRowsByNewlines.Length; row++)
            {
                var eachCharactersInRow = arrayOfRowsByNewlines[row].Trim().Split(' ');
    
                for (int column = 0; column < eachCharactersInRow.Length; column++)
                {
                    int number;
                    int.TryParse(eachCharactersInRow[column], out number);
                    tableHolder[row, column] = number;
                }
            }
            return tableHolder;
        }
    
        public static bool IsPrime(int number)
        {
            // Test whether the parameter is a prime number.
            if ((number & 1) == 0)
            {
                if (number == 2)
                {
                    return true;
                }
                return false;
            }
    
            for (int i = 3; (i * i) <= number; i += 2)
            {
                if ((number % i) == 0)
                {
                    return false;
                }
            }
            return number != 1;
        }
    
    
    
    
    }
    
    使用系统;
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    //获取输入
    var input=GetInput();
    字符串[]arrayOfRowsByNewlines=input.Split('\n');
    var tableHolder=将三角形展平到表格中(按换行排列);
    var结果=穿行模式(按换行、表格夹排列);
    WriteLine($“从上到下的非素数的最大总和是:{result[0,0]}”);
    Console.ReadKey();
    }
    私有静态字符串GetInput()
    {
    常量字符串输入=@“215
    193 124
    117 237 442
    218 935 347 235
    320 804 522 417 345
    229 601 723 835 133 124
    248 202 277 433 207 263 257
    359 464 504 528 516 716 871 182
    461 441 426 656 863 560 380 171 923
    381 348 573 533 447 632 387 176 975 449
    223 711 445 645 245 543 931 532 937 541 444
    330 131 333 928 377 733 017 778 839 168 197 197
    131 171 522 137 217 224 291 413 528 520 227 229 928
    223 626 034 683 839 053 627 310 713 999 629 817 410 121
    924 622 911 233 325 139 721 218 253 223 107 233 230 124 233";
    返回输入;
    }
    私有静态int[,]遍历模式(字符串[]ArrayOfRowByNewlines,int[,]tableHolder)
    {
    //遍历非素数节点
    对于(int i=ArrayOfRowByNewlines.Length-2;i>=0;i--)
    {
    for(int j=0;j对于(int i=3;(i*i)素数检查不是很有效,但对于如此小的数字来说,这并不重要。您的动态规划方法很好,但素数的逻辑中存在错误。您只检查父节点是否为素数。因此,如果两个子节点都为素数,则父节点永远不能成为有效路径的一部分,但您仍然会在上提升较大的路径两个素数中的e+父值(如果父值不是素数)。如何修复它:

  • 在最低级别:如果一个数字是素数,则将其设置为-1

  • 在下一个级别上:如果数字为素数或两个子项都小于0,则将其设置为-1,否则按前面的方法取数字+子项的最大值

  • 如果顶部节点的值为-1,则没有到底部的有效路径,否则它是不带素数的最大路径之和

  • 这对我有用

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    internal static class Program
    {
        /// <summary>
        /// </summary>
        public static Dictionary<int, bool> PrimeCache = new Dictionary<int, bool>();
    
        private static void Main(string[] args)
        {
            var result = GetInput()
                .TransformInputToArray()
                .TransformTo2Darray()
                .ResetAllPrimeNumbers()
                .WalkThroughTheNode();
    
            Console.WriteLine($"The Maximum Total Sum Of Non-Prime Numbers From Top To Bottom Is:  {result}");
            Console.ReadKey();
        }
    
        /// <summary>
        ///     Prepare input
        /// </summary>
        /// <returns></returns>
        private static string GetInput()
        {
            const string input = @" 215
                                       193 124
                                      117 237 442
                                    218 935 347 235
                                  320 804 522 417 345
                                229 601 723 835 133 124
                              248 202 277 433 207 263 257
                            359 464 504 528 516 716 871 182
                          461 441 426 656 863 560 380 171 923
                         381 348 573 533 447 632 387 176 975 449
                       223 711 445 645 245 543 931 532 937 541 444
                     330 131 333 928 377 733 017 778 839 168 197 197
                    131 171 522 137 217 224 291 413 528 520 227 229 928
                  223 626 034 683 839 053 627 310 713 999 629 817 410 121
                924 622 911 233 325 139 721 218 253 223 107 233 230 124 233";
            return input;
        }
    
        /// <summary>
        ///     Transform the input to array
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private static string[] TransformInputToArray(this string input)
        {
            return input.Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
        }
    
        /// <summary>
        ///     Transform the array to 2D array
        /// </summary>
        /// <param name="arrayOfRowsByNewlines"></param>
        /// <returns></returns>
        private static int[,] TransformTo2Darray(this string[] arrayOfRowsByNewlines)
        {
            var tableHolder = new int[arrayOfRowsByNewlines.Length, arrayOfRowsByNewlines.Length + 1];
    
            for (var row = 0; row < arrayOfRowsByNewlines.Length; row++)
            {
                var eachCharactersInRow = arrayOfRowsByNewlines[row].ExtractNumber();
    
                for (var column = 0; column < eachCharactersInRow.Length; column++)
                    tableHolder[row, column] = eachCharactersInRow[column];
            }
            return tableHolder;
        }
    
        /// <summary>
        ///     Extract Number from the row
        /// </summary>
        /// <param name="rows"></param>
        /// <returns></returns>
        private static int[] ExtractNumber(this string rows)
        {
            return
                Regex
                    .Matches(rows, "[0-9]+")
                    .Cast<Match>()
                    .Select(m => int.Parse(m.Value)).ToArray();
        }
    
        /// <summary>
        ///     Reset all the prime number to zero
        /// </summary>
        /// <param name="tableHolder"></param>
        /// <returns></returns>
        private static int[,] ResetAllPrimeNumbers(this int[,] tableHolder)
        {
            var length = tableHolder.GetLength(0);
            for (var i = 0; i < length; i++)
            {
                for (var j = 0; j < length; j++)
                {
                    if (tableHolder[i, j] == 0) continue;
                    if (IsPrime(tableHolder[i, j]))
                        tableHolder[i, j] = 0;
                }
            }
            return tableHolder;
        }
    
        /// <summary>
        ///     Walk through all the non prime
        /// </summary>
        /// <param name="tableHolder"></param>
        /// <returns></returns>
        private static int WalkThroughTheNode(this int[,] tableHolder)
        {
            var tempresult = tableHolder;
            var length = tableHolder.GetLength(0);
    
            // walking through the non-prime node
    
            for (var i = length - 2; i >= 0; i--)
            {
                for (var j = 0; j < length; j++)
                {
                    var c = tempresult[i, j];
                    var a = tempresult[i + 1, j];
                    var b = tempresult[i + 1, j + 1];
                    if ((!IsPrime(c) && !IsPrime(a)) || (!IsPrime(c) && !IsPrime(b)))
                        tableHolder[i, j] = c + Math.Max(a, b);
                }
            }
            return tableHolder[0, 0];
        }
    
        /// <summary>
        ///     prime number check
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static bool IsPrime(this int number)
        {
            // Test whether the parameter is a prime number.
            if (PrimeCache.ContainsKey(number))
            {
                bool value;
                PrimeCache.TryGetValue(number, out value);
                return value;
            }
            if ((number & 1) == 0)
            {
                if (number == 2)
                {
                    if (!PrimeCache.ContainsKey(number)) PrimeCache.Add(number, true);
                    return true;
                }
                if (!PrimeCache.ContainsKey(number)) PrimeCache.Add(number, false);
                return false;
            }
    
            for (var i = 3; i*i <= number; i += 2)
            {
                if (number%i == 0)
                {
                    if (!PrimeCache.ContainsKey(number)) PrimeCache.Add(number, false);
                    return false;
                }
            }
            var check = number != 1;
            if (!PrimeCache.ContainsKey(number)) PrimeCache.Add(number, check);
            return check;
        }
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用System.Linq;
    使用System.Text.RegularExpressions;
    内部静态类程序
    {
    /// 
    /// 
    公共静态字典PrimeCache=新字典();
    私有静态void Main(字符串[]args)
    {
    var result=GetInput()
    .roarray()
    .TransformTo2Darray()
    .ResetAllPrimeNumbers()
    .WalkThroughTheNode();
    WriteLine($“从上到下的非素数的最大总和是:{result}”);
    Console.ReadKey();
    }
    /// 
    ///准备输入
    /// 
    /// 
    私有静态字符串GetInput()
    {
    常量字符串输入=@“215
    
    // Creating 2 dimensional array with the input triangle
    int[][] data = Files.lines(Paths.get("E:\\Personal\\triangle2.txt"))
            .map(s -> stream(s.trim().split("\\s+")).mapToInt(Integer::parseInt).toArray()).toArray(int[][]::new);
    
    int[][] originalData = Files.lines(Paths.get("E:\\Personal\\triangle2.txt"))
            .map(s -> stream(s.trim().split("\\s+")).mapToInt(Integer::parseInt).toArray()).toArray(int[][]::new);
    
    /*
     * Below would be code flow if we didnt had to consider skipping the
     * prime numbers.
     * for (int lengthIndex = data.length - 1; lengthIndex >  0; lengthIndex--)
     *   for (int i = 0; i < data[lengthIndex].length - 1;  i++)
     *       data[lengthIndex - 1][i] += Math.max(data[lengthIndex][i],data[lengthIndex][i + 1]);
     */
    
    // Using the bottom-up approach starting from the lowermost node to upwards
    for (int lengthIndex = data.length - 1; lengthIndex > 0; lengthIndex--)
        for (int i = 0; i < data[lengthIndex].length - 1; i++) {
            System.out.println("lenghtindex is" + lengthIndex);
            if(!checkPrimeOnOriginalArray(data[lengthIndex - 1][i]) || (lengthIndex == 1)) {
                System.out.println("gettign here");
                data[lengthIndex - 1][i] += Math.max(
                        data[lengthIndex][i],data[lengthIndex][i + 1]);
                System.out.println("-->"+data[lengthIndex - 1][i]);
            }
            else {
                data[lengthIndex - 1][i] = 0;
            }
        }
    
    //data[lengthIndex - 1][i] += Math.max(
    //      checkPrimeOnOriginalArray(originalData[lengthIndex][i]) ? 0 : data[lengthIndex][i],
    //      checkPrimeOnOriginalArray(originalData[lengthIndex][i + 1]) ? 0 : data[lengthIndex][i + 1]);
    
    System.out.println("Maximum Sum Of Path Is : "+data[0][0]);
    
    for (int lenIndex = data.length - 1; lenIndex > 0; lenIndex--) {
            for (int i = 0; i < data[lenIndex].length - 1; i++) {
                System.out.println("---------------------");
                System.out.println("lenIndex is : " + lenIndex);
                if (!isPrimeNum(data[lenIndex - 1][i]) || (lenIndex == 1)) {
                    if (lenIndex == data.length - 1) {
                        data[lenIndex - 1][i] += Math.max(isPrimeNum(data[lenIndex][i]) ? 0 : data[lenIndex][i],
                                isPrimeNum(data[lenIndex][i + 1]) ? 0 : data[lenIndex][i + 1]);
    
                        System.out.println("data[lenIndex][i] : " + data[lenIndex][i]+ " data[lenIndex][i + 1] :"+ data[lenIndex][i + 1]);
                        System.out.println("Number select for Sum #" + Math.max(isPrimeNum(data[lenIndex][i]) ? 0 : data[lenIndex][i],
                                isPrimeNum(data[lenIndex][i + 1]) ? 0 : data[lenIndex][i + 1]));
                    } else {
                        data[lenIndex - 1][i] += Math.max(data[lenIndex][i], data[lenIndex][i + 1]);
                        System.out.println("data[lenIndex][i] : " + data[lenIndex][i]+ " data[lenIndex][i + 1] :"+ data[lenIndex][i + 1]);
                        System.out.println("Number select for Sum #" + Math.max(data[lenIndex][i], data[lenIndex][i + 1]));
                    }
                    System.out.println("Afrer Sum #" + data[lenIndex - 1][i]);
                } else {
                    System.out.println("Prime Number - Skiping : " + data[lenIndex - 1][i]);
                    data[lenIndex - 1][i] = 0;
                }
            }