Skip to content

Instantly share code, notes, and snippets.

@dandohotaru
Last active January 25, 2018 22:39
Show Gist options
  • Save dandohotaru/579b922c77b2818d3e3f1ff5c468cae8 to your computer and use it in GitHub Desktop.
Save dandohotaru/579b922c77b2818d3e3f1ff5c468cae8 to your computer and use it in GitHub Desktop.
// Same as initial recursive attempt but playing around with graph creation
void Main()
{
var trip = new
{
Origin = "CMB",
Destination = "DEL",
};
var data = new List<Segment>()
{
new Segment { Name = "01", Origin = "CMB", Destination = "MAA", Flight = "123"},
new Segment { Name = "02", Origin = "MAA", Destination = "DEL", Flight = "543"},
new Segment { Name = "03", Origin = "MAA", Destination = "DEL", Flight = "320"},
new Segment { Name = "04", Origin = "CMB", Destination = "BOM", Flight = "644"},
new Segment { Name = "05", Origin = "BOM", Destination = "DEL", Flight = "233"},
new Segment { Name = "06", Origin = "CMB", Destination = "KMG", Flight = "233"},
new Segment { Name = "07", Origin = "KMG", Destination = "PEK", Flight = "233"},
new Segment { Name = "08", Origin = "PEK", Destination = "DEL", Flight = "233"},
//new Segment { Name = "10", Origin = "KMG", Destination = "DEL", Flight = "233"},
//new Segment { Name = "11", Origin = "CMB", Destination = "DEL", Flight = "111"},
};
data.Dump("Segments");
var graph = new Analyzer(data).Graph();
graph.Dump("Graph");
var itineraries = graph.Traverse(p=>p.Children);
itineraries.Dump("Itineraries");
var query = from itinerary in itineraries
let first = itinerary.First()
let last = itinerary.Last()
where 1 == 1
&& trip.Origin == first.Origin
&& trip.Destination == last.Destination
group itinerary by first.Flight into groupings
select groupings
.SelectMany(p => p)
.Distinct();
query.Dump("Results");
}
public class Analyzer
{
public Analyzer(IEnumerable<Segment> segments)
{
Segments = segments;
}
protected IEnumerable<Segment> Segments { get; set; }
public IEnumerable<Node> Graph(IEnumerable<Segment> origins = null)
{
if (origins == null)
origins = Segments;
foreach (var origin in origins)
{
var destinations = Segments.Where(p => p.Origin == origin.Destination);
yield return new Node(origin)
{
Children = Graph(destinations)
};
}
}
}
public static class Extensions
{
public static IEnumerable<IEnumerable<T>> Traverse<T>(
this IEnumerable<T> subjects,
Func<T, IEnumerable<T>> selector,
Stack<T> current = null)
{
if (current == null)
current = new Stack<T>();
foreach (var subject in subjects)
{
current.Push(subject);
var children = selector(subject);
if (children.Any())
{
foreach (var child in children.Traverse(selector, current))
{
yield return child;
}
}
else
{
yield return current.Reverse().ToList();
}
current.Pop();
}
}
}
public class Node : Segment
{
public Node(Segment segment)
{
Name = segment.Name;
Origin = segment.Origin;
Destination = segment.Destination;
Flight = segment.Flight;
}
public IEnumerable<Node> Children { get; set; }
public string Next
{
get
{
return Children == null ? null : string.Join(",", Children.Select(p => p.Name));
}
}
object ToDump() => new
{
Name,
Origin,
Destination,
Flight,
Next
};
}
public class Segment
{
public string Name { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public string Flight { get; set; }
}
void Main()
{
var trip = new
{
Origin = "CMB",
Destination = "DEL",
};
var segments = new List<Segment>()
{
new Segment { Name = "01", Origin = "CMB", Destination = "MAA", Flight = "123"},
new Segment { Name = "02", Origin = "MAA", Destination = "DEL", Flight = "543"},
new Segment { Name = "03", Origin = "MAA", Destination = "DEL", Flight = "320"},
new Segment { Name = "04", Origin = "CMB", Destination = "BOM", Flight = "644"},
new Segment { Name = "05", Origin = "BOM", Destination = "DEL", Flight = "233"},
new Segment { Name = "06", Origin = "CMB", Destination = "KMG", Flight = "233"},
new Segment { Name = "07", Origin = "KMG", Destination = "PEK", Flight = "233"},
new Segment { Name = "08", Origin = "PEK", Destination = "DEL", Flight = "233"},
};
segments.Dump("Segments");
var itineraries = new Analyzer(segments).Process();
itineraries.Dump("Itineraries");
var query = from itinerary in itineraries
let first = itinerary.First()
let last = itinerary.Last()
where 1 == 1
&& trip.Origin == first.Origin
&& trip.Destination == last.Destination
group itinerary by first.Flight into groupings
select groupings
.SelectMany(p => p)
.Distinct();
query.Dump("Results");
}
public class Analyzer
{
public Analyzer(IEnumerable<Segment> segments)
{
Segments = segments;
}
protected IEnumerable<Segment> Segments { get; set; }
public IEnumerable<IEnumerable<Segment>> Process(IEnumerable<Segment> origins = null, Stack<Segment> current = null)
{
if (origins == null)
origins = Segments;
if (current == null)
current = new Stack<Segment>();
foreach (var origin in origins)
{
current.Push(origin);
var destinations = Segments.Where(p => p.Origin == origin.Destination);
if (destinations.Any())
{
foreach (var child in Process(destinations, current))
{
yield return child;
};
}
else
{
yield return current.Reverse().ToList();
}
current.Pop();
}
}
}
public class Segment
{
public string Name { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public string Flight { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment