using System;
using System.IO;
namespace AOCD9
{
public class Points
{
public int PointValue { get; set; }
public int CoordX { get; set; }
public int CoordY { get; set; }
public Points(int pointValue, int coordX, int coordY)
{
PointValue = pointValue;
CoordX = coordX;
CoordY = coordY;
}
public Points(int coordX, int coordY)
{
CoordX = coordX;
CoordY = coordY;
}
public override string ToString()
{
return $"Point Coord:{CoordX},{CoordY}";
}
}
public class Program
{
static int ROW = 5;
static int COL = 10;
// Initialize direction vectors
static int[] dRow = { 0, 1, 0, -1 };
static int[] dCol = { -1, 0, 1, 0 };
static bool[,] vis = new bool[ROW, COL];
public static void Main()
{
var stringArray = ConvertInputToStringArray("sample.txt");
var matrix = SetMatrix(stringArray);
PrintMatrix(matrix);
var lowPoints = GetLowPoints(matrix);
var risk = GetRiskLevel(lowPoints);
Console.WriteLine($"The risk level is: {risk}");
// end of part 1 -----
var falseMatrix = SetMatrixOfFalse(); //set false matrix for DFS
//for (int row = 0; row < 5; row++)
//{
// for (int col = 0; col < 10; col++)
// {
// Console.Write(falseMatrix[row,col]+" ");
// }
// Console.WriteLine();
//} //print false matrix check
var basinPoints = new List<int>();
foreach (var item in lowPoints)
{
//how can I check here all the basin points with DFS method???
}
DFS(lowPoints[0], matrix, vis);
}
private static bool[,] SetMatrixOfFalse()
{
bool[,] vis = new bool[ROW, COL];
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
vis[i, j] = false;
}
}
return vis;
}
public static string[] ConvertInputToStringArray(string input)
{
return File.ReadAllLines(input);
}
public static int[,] SetMatrix(string[] input)
{
int[,] result = new int[input.GetLength(0), input[0].Length];
for (int row = 0; row < input.GetLength(0); row++)
{
for (int col = 0; col < input[0].Length; col++)
{
result[row, col] = int.Parse(input[row][col].ToString());
}
}
return result;
}
public static void PrintMatrix(int[,] matrix)
{
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(1); col++)
{
Console.Write(matrix[row, col]);
}
Console.WriteLine();
}
}
public static bool CheckLowPoint(int[,] matrix, Points point)
{
var up = point.CoordX - 1;
var down = point.CoordX + 1;
var left = point.CoordY - 1;
var right = point.CoordY + 1;
if (point.CoordX == 0) up = 1; //reset up in case of border value
if (point.CoordY == 0) left = 1; //reset left in case of border value
if (point.CoordY == matrix.GetLength(1) - 1) right = matrix.GetLength(1) - 2; //reset right border
if (point.CoordX == matrix.GetLength(0) - 1) down = matrix.GetLength(0) - 2; //reset down border
if (matrix[point.CoordX, point.CoordY] < matrix[up, point.CoordY] &&
matrix[point.CoordX, point.CoordY] < matrix[down, point.CoordY] &&
matrix[point.CoordX, point.CoordY] < matrix[point.CoordX, left] &&
matrix[point.CoordX, point.CoordY] < matrix[point.CoordX, right]
)
return true;
else return false;
}
public static List<Points> GetLowPoints(int[,] matrix)
{
List<Points> list = new List<Points>();
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(1); col++)
{
Points point = new Points(matrix[row, col], row, col);
if (CheckLowPoint(matrix, point)) list.Add(new Points(matrix[row, col], row, col));
}
}
return list;
}
public static int GetRiskLevel(List<Points> list)
{
int result = 0;
foreach (var item in list)
{
result += item.PointValue + 1;
}
return result;
}
static bool isValidCell(bool[,] vis, Points point)
{
// If cell is out of bounds
if (point.CoordX < 0 || point.CoordY< 0 ||
point.CoordX >= ROW || point.CoordY >= COL)
return false;
// If the cell is already visited
if (vis[point.CoordX, point.CoordY])
return false;
// Otherwise, it can be visited
return true;
}
// Function to perform DFS
// Traversal on the matrix grid[]
static void DFS(Points point,
int[,] matrix, bool[,] vis)
{
// Initialize a stack of points and
// push the starting cell into it
Stack<Points> st = new Stack<Points>();
st.Push(new Points(point.CoordX, point.CoordY));
var pointDFS = new List<Points>();
// Iterate until the
// stack is not empty
while (st.Count > 0)
{
// Pop the top point
Points curr = (Points)st.Peek();
st.Pop();
point.CoordX = curr.CoordX;
point.CoordY = curr.CoordY;
// Check if the current popped
// cell is a valid cell or not
if (!isValidCell(vis, point))
continue;
// Mark the current
// cell as visited
vis[point.CoordX, point.CoordY] = true;
// Print the element at
// the current top cell ((if a condition is true))
Console.Write(matrix[point.CoordX, point.CoordY] + " ");
Console.WriteLine(point);
//oltre a stampare gli elementi di matrix
//potrei verificare se è un basin point
//pointDFS.Add(new Points(point.CoordX, point.CoordY));
// Push all the adjacent cells
for (int i = 0; i < 4; i++)
{
int adjx = point.CoordX + dRow[i];
int adjy = point.CoordY + dCol[i];
st.Push(new Points(adjx, adjy));
}
}
}
}
}