I'm working with the task of finding the path that gives the maximum sum in a triangle.
The one condition I have is having to switch by even and odd numbers for every row.
So in my example I have to go: 55 - 94 - 95 - 72 ... so I change between odd and even numbers. I found this code that uses dynamic programming to find the path with the largest sum. I also know how to check for even or odd number but I don't know how to use it in this algorithm. Can somebody help with this?
public static void Main (string[] args)
{
int[,] list = new int[18,19];
string input = @"55
94 48
95 30 96
77 72 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 72 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93";
var charArray = input.Split ('\n');
for (int i=0; i < charArray.Length; i++) {
var numArr = charArray[i].Trim().Split(' ');
for (int j = 0; j<numArr.Length; j++)
{
int number = Convert.ToInt32 (numArr[j]);
list [i, j] = number;
}
}
for (int i = 16; i >= 0; i--) {
for (int j = 0; j < 18; j++) {
list[i,j] = Math.Max(list[i, j] + list[i+1, j], list[i,j] + list[i+1, j+1]);
}
}
Console.WriteLine (string.Format("Maximum total: {0}", list [0, 0]));
}
}
I have adopted a different approach for your problem.
First I have defined the triangle structure in which - excluding Root and second level, all right hand side children represent also the neighbour left child - excluding the last element on that level.
The traversing of the triangle is pretty simple per se. Once we check for the highest value on that level - we keep track of its parent in order to traverse only trough that path.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp8
{
/// <summary>
/// The Node class
/// </summary>
public class Node
{
public int Level { get; set; }
public List<int> Parents { get; set; }
public int Element { get; set; }
}
/// <summary>
/// The Triangle class Representation
/// </summary>
public class Triangle
{
/// <summary>
/// The triangle root
/// </summary>
public int Root { get; set; }
/// <summary>
/// The Node per each level of depth
/// </summary>
public List<List<Node>> LevelNodes { get; set; }
/// <summary>
/// Build the triangle structure
/// </summary>
public void BuildTriangle()
{
List<Node> nodeLevelList = new List<Node>();
bool carryOn = true;
//****************************************************
//Create Root and second level
Console.WriteLine("Add Tree Root");
Root = Convert.ToInt32(Console.ReadLine());
LevelNodes = new List<List<Node>>();
//set the first node to have the root has parent
Node myNode = new Node
{
Parents = new List<int> { Root }
};
Console.WriteLine("Add Left Child");
myNode.Element = Convert.ToInt32(Console.ReadLine());
myNode.Level = 2;
//add the node
nodeLevelList.Add(myNode);
myNode = new Node
{
Parents = new List<int> { Root }
};
Console.WriteLine("Add Right Child");
myNode.Element = Convert.ToInt32(Console.ReadLine());
myNode.Level = 2;
//add the node
nodeLevelList.Add(myNode);
LevelNodes.Add(nodeLevelList);
//****************************************************
Console.Clear();
//****************************************************
// Build the rest of the triangle data structure
while (carryOn)
{
nodeLevelList = new List<Node>();
//take all the nodes on last level entered
var nodes = LevelNodes.Last().ToList();
bool firstElement = true;
foreach (var node in nodes)
{
myNode = new Node();
if (firstElement)
{
Console.WriteLine("Add Left Child for parent : {0}", node.Element);
myNode.Element = Convert.ToInt32(Console.ReadLine());
myNode.Parents = new List<int> { node.Element };
myNode.Level = node.Level + 1;
//add the node
nodeLevelList.Add(myNode);
firstElement = false;
}
else
{
var temp = nodeLevelList.Last();
temp.Parents.Add(node.Element);
}
//re-initialise node
myNode = new Node();
Console.WriteLine("Add Right Child for parent : {0}", node.Element);
myNode.Element = Convert.ToInt32(Console.ReadLine());
myNode.Parents = new List<int> { node.Element };
myNode.Level = node.Level + 1;
//add the node
nodeLevelList.Add(myNode);
}
LevelNodes.Add(nodeLevelList);
Console.Clear();
Console.WriteLine("Do you wish to continue adding elements ? Y or N");
carryOn = Console.ReadLine()?.ToLower() == "y";
}
}
public int GetLargetPathSum()
{
int result = Root;
int selectedValue = Root;
Node nodeSelected = new Node();
foreach (List<Node> levelNode in LevelNodes)
{
int maxValue = 0;
foreach (Node node in levelNode.Where(x=> x.Parents.Contains(selectedValue)).Select(x=> x).ToList())
{
if (node.Element > maxValue)
{
maxValue = node.Element;
nodeSelected = node;
}
}
result += maxValue;
selectedValue = maxValue;
}
return result;
}
}
public class Program
{
static void Main(string[] args)
{
Triangle triangle = new Triangle();
triangle.BuildTriangle();
Console.WriteLine(triangle.GetLargetPathSum());
Console.ReadLine();
}
}
}
Hmmm, quick and dirty. Took your code and simply added it. There are easier ways to do this!
static void Main(string[] args)
{
int[,] list = new int[18, 19];
string input = @"55
94 48
95 30 96
77 72 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 72 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93";
var charArray = input.Split('\n');
int[] lineArray = new int[18];
int highestNumber = 0;
bool even = false;
bool noHigehestNumberFound = true;
for (int i = 0; i < 18; i++)
{
while (noHigehestNumberFound)
{
//get highest number of a line
highestNumber = Convert.ToInt32(charArray[i].Split(' ').Max());
if (even != true)
{
// check odd/even with modulo
// if it isn't odd, replace the highest even number with 0
if (highestNumber % 2 == 1)
{
noHigehestNumberFound = false;
even = true;
}
else
{
StringBuilder builder = new StringBuilder(charArray[i]);
builder.Replace(highestNumber.ToString(), "0");
charArray[i] = builder.ToString();
}
}
else if (even == true)
{
// check odd/even with modulo
// if it isn't even, replace the highest even number with 0
if (highestNumber % 2 == 0)
{
noHigehestNumberFound = false;
even = false;
}
else
{
StringBuilder builder = new StringBuilder(charArray[i]);
builder.Replace(highestNumber.ToString(), "0");
charArray[i] = builder.ToString();
}
}
}
lineArray[i] = highestNumber;
noHigehestNumberFound = true;
}
int count = 0;
foreach (var item in lineArray)
{
count += item;
}
Console.WriteLine(count);
Console.ReadKey();
}
With a result of 1383 .
You can use this -
var rows = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim());
int sum = int.Parse(rows.First());
bool isFirstOdd = (sum & 1) == 1;
var path = from r in rows.Skip(1)
let ints = r.Split(' ').Select(x => int.Parse(x)).ToArray()
let isEvenElements = (ints.Length & 1) == 0
let eligibleElements = ints.Where(x => (x & 1) == (isEvenElements && isFirstOdd ? 0 : 1))
let b = eligibleElements.Max()
select b;
sum += path.Sum();
Console.WriteLine(sum);
This solution is based on assumption that your series will continue as - 55 - 94 - 95 - 72 - 97 - 68...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.