Skip to content

Instantly share code, notes, and snippets.

@archer884
Created September 3, 2014 02:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save archer884/ee38d5560dc65bfa1076 to your computer and use it in GitHub Desktop.
Save archer884/ee38d5560dc65bfa1076 to your computer and use it in GitHub Desktop.
Episode stitcher togetherer
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace _01_Episodes
{
static class Extensions
{
public delegate bool TryParseDelegate<T1, T2>(T1 value, out T2 result);
public static IEnumerable<T2> TrySelect<T1, T2>(this IEnumerable<T1> collection, TryParseDelegate<T1, T2> tryParse)
{
foreach (var item in collection)
{
T2 select;
if (tryParse(item, out select)) yield return select;
}
}
}
class Program
{
static void Main(string[] args)
{
args = new[] { "data.txt" }; // cheating
var parser = new EpisodeDataParser(ParseColonDelimited, ParseNonDelimited);
var input = args.Length > 0 && File.Exists(args[0])
? File.ReadLines(args[0])
: ReadStandardInput();
var episodes = input.TrySelect<string, EpisodeData>(parser.TryParse)
.OrderBy(e => e.Season)
.ThenBy(e => e.Episode);
foreach (var episode in episodes)
{
Console.WriteLine(episode);
}
}
static IEnumerable<string> ReadStandardInput()
{
string input;
while(true)
if (!String.IsNullOrWhiteSpace(input = Console.ReadLine()))
yield return input;
else break;
}
static EpisodeData ParseColonDelimited(string data)
{
var tokenDelimitedData = new Regex(@"(\d|\w)+?:(\d|\w)+?(?=\s)");
if (tokenDelimitedData.IsMatch(data))
{
var values = tokenDelimitedData.Match(data).Value.Split(':');
return new EpisodeData()
{
Season = Int32.Parse(new String(values[0].SkipWhile(Char.IsLetter).TakeWhile(Char.IsDigit).ToArray())),
Episode = Int32.Parse(new String(values[1].SkipWhile(Char.IsLetter).TakeWhile(Char.IsDigit).ToArray())),
Title = data,
Url = "get real I didn't bother with this",
};
}
else return null;
}
static EpisodeData ParseNonDelimited(string data)
{
var nonDelimitedData = new Regex(@"(\d)(?=: )");
if (nonDelimitedData.IsMatch(data))
{
var value = nonDelimitedData.Match(data).Value;
return new EpisodeData()
{
Season = 1,
Episode = Int32.Parse(value),
Title = data,
Url = "still didn't bother with this",
};
}
else return null;
}
class EpisodeDataParser
{
IList<Func<string, EpisodeData>> Parsers { get; set; }
public EpisodeDataParser()
{
}
public EpisodeDataParser(params Func<string, EpisodeData>[] parsers)
{
Parsers = new List<Func<string, EpisodeData>>(parsers);
}
public bool TryParse(string data, out EpisodeData episodeData)
{
episodeData = null;
foreach (var parser in Parsers)
{
if ((episodeData = parser(data)) != null)
return true;
}
return false;
}
}
class EpisodeData : IEquatable<EpisodeData>, IComparable<EpisodeData>
{
public int Season { get; set; }
public int Episode { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public EpisodeData()
{
}
// From http://stackoverflow.com/questions/892618/create-a-hashcode-of-two-numbers
public override int GetHashCode()
{
return (int)(Season.GetHashCode() ^ RotateLeft(Episode.GetHashCode(), 16));
}
private uint RotateLeft(int value, int count)
{
uint workingValue = (uint)value;
return (workingValue << count) | (workingValue >> (32 - count));
}
public bool Equals(EpisodeData other)
{
return this.Season == other.Season && this.Episode == other.Episode;
}
public int CompareTo(EpisodeData other)
{
if (this.Season == other.Season)
return this.Season.CompareTo(other.Season);
else return this.Episode.CompareTo(other.Episode);
}
public override string ToString()
{
return String.Format("{0}:{1} - {2}", Season, Episode, Title);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment