omp/Configurator.cs
2025-04-13 23:05:53 +03:00

139 lines
3.6 KiB
C#

namespace omp
{
class UndergroundException : Exception;
public interface IConfigurator
{
Type PointType { get; }
public int XSize { get; }
public int YSize { get; }
public int ZCoordinate { get; }
public List<Point> Stations { get; }
}
public class Configurator : IConfigurator
{
public Type PointType { get; }
public int XSize { get; }
public int YSize { get; }
public int ZCoordinate { get; }
public List<Point> Stations { get; } = [];
public Configurator(string[] args)
{
List<string> lines = ReadAllLines(args);
bool hasZ = CheckHasZ(lines[1]);
if (hasZ)
{
PointType = typeof(Point3D);
}
else
{
PointType = typeof(Point2D);
}
(XSize, YSize) = ParseSize(lines[0]);
ZCoordinate = ParseZCoord(lines[1], hasZ);
ParseStations(lines, hasZ);
}
private static List<string> ReadAllLines(string[] args)
{
List<string> lines;
if (args.Length == 0)
{
Console.WriteLine("Input parameters:");
lines = [];
string? line;
while ((line = Console.ReadLine()) != null && line != "")
{
lines.Add(line);
}
}
else if (args.Length == 1)
{
lines = new(File.ReadAllLines(args[0]));
}
else
{
throw new ArgumentException("You must either provide path to parameters file as an only cli argument, or insert it into STDIN");
}
return lines;
}
private static bool CheckHasZ(string line)
{
return line.Split(' ').Length == 1; // line contains a single number, z coordinate
}
private static (int, int) ParseSize(string line)
{
string[] size_parts = line.Split(' ', 2);
int xSize = int.Parse(size_parts[0]);
int ySize = int.Parse(size_parts[1]);
return (xSize, ySize);
}
private int ParseZCoord(string line, bool hasZ)
{
int zCoordinate;
if (hasZ)
{
zCoordinate = int.Parse(line);
if (ZCoordinate < 0)
{
throw new UndergroundException();
}
}
else
{
zCoordinate = -1;
}
return zCoordinate;
}
private void ParseStations(IReadOnlyList<string> lines, bool hasZ)
{
if (hasZ) Parse3DStations(lines);
else Parse2DStations(lines);
}
private void Parse2DStations(IReadOnlyList<string> lines)
{
for (int i = 1; i < lines.Count; ++i)
{
string[] point_parts = lines[i].Split(' ', 2);
int x = int.Parse(point_parts[0]);
int y = int.Parse(point_parts[1]);
Stations.Add(new Point2D(x, y));
}
}
private void Parse3DStations(IReadOnlyList<string> lines)
{
for (int i = 2; i < lines.Count; ++i)
{
string[] point_parts = lines[i].Split(' ', 3);
int x = int.Parse(point_parts[0]);
int y = int.Parse(point_parts[1]);
int z = int.Parse(point_parts[2]);
Stations.Add(new Point3D(x, y, z));
}
}
}
}