Created
July 8, 2017 20:56
-
-
Save ff8c00/7fbc29a6203697102f1bb7cb2f3cb8b5 to your computer and use it in GitHub Desktop.
Reddit Daily Programmer 321 Intermediate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
namespace Reddit | |
{ | |
internal static class Intermediate | |
{ | |
internal static void Run(string input) | |
{ | |
var items = new List<Result>(); | |
int size = Alphabet.Length; | |
for (int i = 0; i < size * size; i++) | |
{ | |
int a = i / size; | |
int b = i % size; | |
if (HighestCommonFactor(a, size) == 1) | |
{ | |
var item = new Result() | |
{ | |
A = a, | |
B = b | |
}; | |
items.Add(item); | |
} | |
} | |
foreach (var item in items) | |
{ | |
item.Message = Decrypt(item.A, item.B, input); | |
} | |
foreach (var item in items) | |
{ | |
var words = Split(item.Message); | |
var comparer = StringComparer.OrdinalIgnoreCase; | |
int score = 0; | |
foreach (var word in words) | |
{ | |
if (Words.Contains(word, comparer)) | |
{ | |
score = score + 1; | |
} | |
} | |
item.Score = score; | |
} | |
int max = items.Max(e => e.Score); | |
foreach (var item in items | |
.Where(e => e.Score == max)) | |
{ | |
Console.WriteLine(item.Message); | |
} | |
} | |
internal class Result | |
{ | |
internal int A; | |
internal int B; | |
internal string Message; | |
internal int Score; | |
} | |
internal static char[] Alphabet = "abcdefghijklmnopqrstuvwxyz".ToArray(); | |
internal static int HighestCommonFactor(int first, int second) | |
{ | |
int a = Math.Abs(first); | |
int b = Math.Abs(second); | |
int c; | |
while (b != 0) | |
{ | |
c = b; | |
b = a % b; | |
a = c; | |
} | |
return a; | |
} | |
internal static string Decrypt(int a, int b, string message) | |
{ | |
char[] array = Affine(a, b); | |
return Substitute(array, Alphabet, message); | |
} | |
internal static char[] Affine(int a, int b) | |
{ | |
int size = Alphabet.Length; | |
char[] array = new char[size]; | |
for (int i = 0; i < size; i++) | |
{ | |
int index = ((a * i) + b) % size; | |
array[i] = Alphabet[index]; | |
} | |
return array; | |
} | |
internal static string Substitute(char[] first, char[] second, string message) | |
{ | |
var builder = new StringBuilder(); | |
foreach (char c in message) | |
{ | |
int i = Array.IndexOf(first, char.ToLower(c)); | |
if (i == -1) | |
{ | |
builder.Append(c); | |
} | |
else | |
{ | |
if (char.IsUpper(c)) | |
{ | |
builder.Append(char.ToUpper(second[i])); | |
} | |
else | |
{ | |
builder.Append(second[i]); | |
} | |
} | |
} | |
return builder.ToString(); | |
} | |
internal static List<string> Split(string message) | |
{ | |
var items = new List<string>(); | |
char[] separator = new char[] { ' ', '.' }; | |
using (var reader = new StringReader(message)) | |
{ | |
string value; | |
while ((value = reader.ReadLine()) != null) | |
{ | |
items.AddRange(value.Split(separator, | |
StringSplitOptions.RemoveEmptyEntries)); | |
} | |
} | |
return items; | |
} | |
internal static List<string> Words = new List<string>(); | |
internal static void Load(string path) | |
{ | |
Words.AddRange(File.ReadAllLines(path)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment