mirror of
https://gitlab.com/mfocko/CodeWars.git
synced 2024-11-09 11:09:07 +01:00
89 lines
2.8 KiB
C#
89 lines
2.8 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
|
||
|
public static class Kata {
|
||
|
private class Graph {
|
||
|
private struct Edge {
|
||
|
public char Through { get; set; }
|
||
|
public char To { get; set; }
|
||
|
};
|
||
|
|
||
|
public static readonly char NO_CONDITION = '\0';
|
||
|
|
||
|
private Dictionary<char, List<Edge>> edges = new Dictionary<char, List<Edge>>();
|
||
|
private HashSet<char> visited = new HashSet<char>();
|
||
|
|
||
|
private Graph addEdge(char src, char through, char dst) {
|
||
|
var newEdge = new Edge {
|
||
|
Through = through,
|
||
|
To = dst
|
||
|
};
|
||
|
|
||
|
if (edges.TryGetValue(src, out var lst)) {
|
||
|
lst.Add(newEdge);
|
||
|
} else {
|
||
|
edges.Add(src, new List<Edge>() { newEdge });
|
||
|
}
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public Graph AddDirectEdge(char src, char dst)
|
||
|
=> addEdge(src, NO_CONDITION, dst);
|
||
|
public Graph AddIndirectEdge(char src, char through, char dst)
|
||
|
=> addEdge(src, through, dst);
|
||
|
public Graph AddBiDirectEdge(char src, char dst)
|
||
|
=> AddBiIndirectEdge(src, NO_CONDITION, dst);
|
||
|
public Graph AddBiIndirectEdge(char src, char through, char dst) =>
|
||
|
addEdge(src, through, dst)
|
||
|
.addEdge(dst, through, src);
|
||
|
|
||
|
public void ResetVisited() => visited.Clear();
|
||
|
public bool BeenVisited(char vertex) => visited.Contains(vertex);
|
||
|
public void Mark(char vertex) => visited.Add(vertex);
|
||
|
public void Unmark(char vertex) => visited.Remove(vertex);
|
||
|
|
||
|
public bool HasEdge(char fromVertex, char toVertex)
|
||
|
=> edges[fromVertex].Any(e => e.To == toVertex && (e.Through == NO_CONDITION || BeenVisited(e.Through)));
|
||
|
|
||
|
public Graph AddMultipleBiDirectEdges(char fromVertex, string toVertices) {
|
||
|
foreach (var toVertex in toVertices) {
|
||
|
AddBiDirectEdge(fromVertex, toVertex);
|
||
|
}
|
||
|
return this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static Graph g = new Graph()
|
||
|
.AddMultipleBiDirectEdges('A', "BDEFH").AddMultipleBiDirectEdges('B', "CDEFGI")
|
||
|
.AddMultipleBiDirectEdges('C', "DEFH").AddMultipleBiDirectEdges('D', "EGHI")
|
||
|
.AddMultipleBiDirectEdges('E', "FGHI").AddMultipleBiDirectEdges('F', "GHI")
|
||
|
.AddMultipleBiDirectEdges('G', "H").AddMultipleBiDirectEdges('H', "I")
|
||
|
.AddBiIndirectEdge('A', 'B', 'C').AddBiIndirectEdge('A', 'D', 'G').AddBiIndirectEdge('A', 'E', 'I')
|
||
|
.AddBiIndirectEdge('B', 'E', 'H').AddBiIndirectEdge('C', 'E', 'G').AddBiIndirectEdge('C', 'F', 'I')
|
||
|
.AddBiIndirectEdge('D', 'E', 'F').AddBiIndirectEdge('G', 'H', 'I');
|
||
|
|
||
|
public static int CountPatternsFrom(char firstDot, int length) {
|
||
|
if (length <= 0 || length >= 10) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (length == 1) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int total = 0;
|
||
|
|
||
|
g.Mark(firstDot);
|
||
|
foreach (var vertex in "ABCDEFGHI") {
|
||
|
if (!g.BeenVisited(vertex) && g.HasEdge(firstDot, vertex)) {
|
||
|
total += CountPatternsFrom(vertex, length - 1);
|
||
|
}
|
||
|
}
|
||
|
g.Unmark(firstDot);
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
}
|