summaryrefslogtreecommitdiffstats
path: root/IO/GraphFile.cs
blob: dc1d851fcaf6fa825cad12eecedfeaf3e3c3a523 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System.Text.RegularExpressions;
using Graph.Interfaces;

namespace Graph.IO
{
    public static class GraphFile
    {
        // read a graph from file using IFileReader (i.e. Dependancy injection for unit testing)
        public static Graph<double> Read(IFileReader reader)
        {
            string[] lines = reader.Lines;
            Graph<double> graph = new Graph<double>();

            foreach (string line in reader.Lines)
            {
                // split string into vertex id and the edges
                string[] parts = line.Split(" ", 2);

                // parse vertex id
                int vertex = int.Parse(parts[0]);

                // parse edges, matches pairs of number two at a time, i.e. "num num"
                Match match = Regex.Match(parts[1], @"[^ ]+ [^ ]+");
                while (match.Success)
                {
                    // for each match, split the "vertex weight" pair 
                    string[] edge = match.Value.Split(" ", 2);

                    // add edge to graph (vertex1, vertex2, weight)
                    graph.AddEdge(new Edge<double>(
                        vertex,
                        int.Parse(edge[0]),
                        double.Parse(edge[1])
                    ));

                    // iterate match
                    match = match.NextMatch();
                }
            }

            return graph;
        }

        // write a graph to file using IFileWriter (i.e. Dependancy injection for unit testing)
        public static void Print(Graph<double> graph, IFileWriter writer)
        {
            // create array of strings with a size equal to vertices
            string[] lines = new string[graph.Vertices.Count];
            
            // add each vertex to it's parents output line 
            graph.Vertices.ForEach(vertex =>
            {
                // do nothing if it has no parent
                if (vertex.Parent == null)
                    return;

                // needed due to making vertex.Parent nullable
                int parent = vertex.Parent.GetValueOrDefault();

                // for vertex & parent, create string if not already
                lines[vertex.Id] ??= $"{vertex.Id}";
                lines[parent] ??= $"{parent}";
                
                // add vertex + weight to parent's string & visa versa
                lines[parent] += $" {vertex.Id} {vertex.Key.ToString("F1")}";
                lines[vertex.Id] += $" {parent} {vertex.Key.ToString("F1")}";
            });
            // write the array of strings to file
            writer.WriteAllLines(lines);
        }
    }
}