204 lines
4.9 KiB
C#
204 lines
4.9 KiB
C#
// See https://aka.ms/new-console-template for more information
|
|
using System.Collections;
|
|
|
|
var exampleData = new LoadedData("example-input.txt");
|
|
var puzzleData = new LoadedData("puzzle-input.txt");
|
|
|
|
exampleData.Print();
|
|
|
|
Console.WriteLine(String.Format("Part01, visibility: Example({0}), Puzzle({1})", exampleData.VisibleCount, puzzleData.VisibleCount));
|
|
|
|
Console.WriteLine(String.Format("Part01, Scenic Score: Example({0}), Puzzle({1})", exampleData.ScenicScore, puzzleData.ScenicScore));
|
|
|
|
class LoadedData
|
|
{
|
|
public List<List<int>> TreeData { get; } = new List<List<int>>();
|
|
|
|
public void Print()
|
|
{
|
|
string toPrint = "";
|
|
for (int j = 0; j < TreeData.Count; j++)
|
|
{
|
|
for (int i = 0; i < TreeData[j].Count; i++)
|
|
{
|
|
toPrint += TreeData[j][i];
|
|
}
|
|
toPrint += "\n";
|
|
}
|
|
|
|
Console.WriteLine(toPrint);
|
|
}
|
|
|
|
public LoadedData(string fileName)
|
|
{
|
|
TreeData = new List<List<int>>();
|
|
|
|
using (StreamReader reader = System.IO.File.OpenText(fileName))
|
|
{
|
|
while (!reader.EndOfStream)
|
|
{
|
|
string? line = reader.ReadLine();
|
|
if (line == null)
|
|
{
|
|
throw new InvalidDataException();
|
|
}
|
|
|
|
List<int> list = new List<int>();
|
|
foreach (char c in line)
|
|
{
|
|
list.Add((int)(c - '0'));
|
|
}
|
|
|
|
TreeData.Add(list);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int VisibleCount
|
|
{
|
|
get
|
|
{
|
|
int visible = 0;
|
|
|
|
// Check the inside
|
|
for (int j = 1; j < TreeData.Count-1; j++)
|
|
{
|
|
for (int i = 1; i < TreeData[0].Count-1; i++)
|
|
{
|
|
if (IsVisible(i,j)) { visible++; }
|
|
}
|
|
}
|
|
|
|
// Add the top row and bottom row
|
|
visible += TreeData[0].Count * 2;
|
|
|
|
// Add the two sides
|
|
visible += (TreeData.Count-2)*2;
|
|
return visible;
|
|
}
|
|
}
|
|
|
|
private bool IsVisible(int i, int j)
|
|
{
|
|
int baseHeight = TreeData[j][i];
|
|
|
|
bool visUp = true, visRight = true, visLeft = true, visDown = true;
|
|
|
|
// Up
|
|
for (int y = 0, x=i; y < j; y++)
|
|
{
|
|
if (baseHeight <= TreeData[y][x])
|
|
{
|
|
visUp = false;
|
|
break;
|
|
}
|
|
}
|
|
if (visUp) return true;
|
|
|
|
// Right
|
|
for (int x = i+1, y=j; x < TreeData[i].Count; x++)
|
|
{
|
|
if (baseHeight <= TreeData[y][x])
|
|
{
|
|
visRight = false;
|
|
break;
|
|
}
|
|
}
|
|
if (visRight) return true;
|
|
|
|
// Left
|
|
for (int x = 0, y = j; x < i; x++)
|
|
{
|
|
if (baseHeight <= TreeData[y][x])
|
|
{
|
|
visLeft = false;
|
|
break;
|
|
}
|
|
}
|
|
if (visLeft) return true;
|
|
|
|
// Down
|
|
for (int y = j+1, x = i; y < TreeData.Count; y++)
|
|
{
|
|
if (baseHeight <= TreeData[y][x])
|
|
{
|
|
visDown = false;
|
|
break;
|
|
}
|
|
}
|
|
if (visDown) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
public int ScenicScore
|
|
{
|
|
get
|
|
{
|
|
int result = 0;
|
|
for (int j = 1; j < TreeData.Count - 1; j++)
|
|
{
|
|
for (int i = 1; i < TreeData[0].Count - 1; i++)
|
|
{
|
|
result = Int32.Max(result, GetScenicScore(i, j));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
private int GetScenicScore(int i, int j)
|
|
{
|
|
int baseHeight = TreeData[j][i];
|
|
int viewUp=0, viewDown=0, viewLeft=0, viewRight=0;
|
|
|
|
// Up
|
|
for (int y = j-1, x = i; y >= 0; y--)
|
|
{
|
|
viewUp++;
|
|
if (TreeData[y][x] >= baseHeight)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Right
|
|
for (int x = i + 1, y = j; x < TreeData[i].Count; x++)
|
|
{
|
|
viewRight++;
|
|
if (TreeData[y][x] >= baseHeight)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Left
|
|
for (int x = i-1, y = j; x >= 0; x--)
|
|
{
|
|
viewLeft++;
|
|
if (TreeData[y][x] >= baseHeight)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Down
|
|
for (int y = j + 1, x = i; y < TreeData.Count; y++)
|
|
{
|
|
viewDown++;
|
|
if (TreeData[y][x] >= baseHeight)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return viewUp * viewDown * viewLeft * viewRight;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|