-
-
Save Siliconrob/6877a325014208c7eff67829c350aed2 to your computer and use it in GitHub Desktop.
Senior Software Engineer - Full Stack (Top 20 Pizzas)
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.Net.Http; | |
using System.Runtime.Serialization; | |
using System.Threading.Tasks; | |
using Newtonsoft.Json; | |
namespace orders | |
{ | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
var parsedOrders = Task.Run(async () => await OrderSnapshot<PizzaOrder>("http://files.olo.com/pizzas.json")); | |
Task.WaitAll(parsedOrders); | |
var rank = 1; | |
foreach (var order in CountOrders(parsedOrders.Result).Top(20)) | |
{ | |
Console.WriteLine($"Rank: {rank}, Pizza: {string.Join(",", order.Key.Toppings)}, Times ordered: {order.Value}"); | |
rank++; | |
} | |
Console.ReadLine(); | |
} | |
private static Dictionary<string, KeyValuePair<PizzaOrder, int>> CountOrders(IEnumerable<PizzaOrder> parsedOrders) | |
{ | |
var uniqueOrders = new Dictionary<string, KeyValuePair<PizzaOrder, int>>(); | |
foreach (var order in parsedOrders) | |
{ | |
var sortedToppings = string.Join(",", order.Toppings.OrderBy(z => z)); | |
if (uniqueOrders.ContainsKey(sortedToppings)) | |
{ | |
var current = uniqueOrders[sortedToppings]; | |
uniqueOrders[sortedToppings] = new KeyValuePair<PizzaOrder, int>(current.Key, current.Value + 1); | |
continue; | |
} | |
uniqueOrders.Add(sortedToppings, new KeyValuePair<PizzaOrder, int>(order, 1)); | |
} | |
return uniqueOrders; | |
} | |
private static async Task<IEnumerable<T>> OrderSnapshot<T>(string orderUrl) where T : class, new() | |
{ | |
using (var client = new HttpClient()) | |
{ | |
return await client.GetDataAsync<T>(orderUrl); | |
} | |
} | |
} | |
public static class DictionaryExtensions | |
{ | |
public static Dictionary<T, int> Top<T>(this Dictionary<string, KeyValuePair<T, int>> uniqueOrders, int topN) where T : class, new() | |
{ | |
var results = uniqueOrders.OrderByDescending(z => z.Value.Value) | |
.Take(topN) | |
.ToDictionary(x => x.Value.Key, x => x.Value.Value); | |
return results; | |
} | |
} | |
public static class HttpClientExtensions | |
{ | |
private static IEnumerable<T> Read<T>(JsonReader reader) where T : class, new() | |
{ | |
var items = new List<T>(); | |
reader.SupportMultipleContent = true; | |
var serializer = new JsonSerializer(); | |
while (reader.Read()) | |
{ | |
if (reader.TokenType != JsonToken.StartObject) { continue; } | |
items.Add(serializer.Deserialize<T>(reader)); | |
} | |
return items; | |
} | |
public static async Task<IEnumerable<T>> GetDataAsync<T>(this HttpClient current, string orderUrl) where T : class, new() | |
{ | |
using (var stream = await current.GetStreamAsync(orderUrl)) | |
using (var streamReader = new StreamReader(stream)) | |
using (var reader = new JsonTextReader(streamReader)) | |
{ | |
return Read<T>(reader); | |
} | |
} | |
} | |
[DataContract] | |
public class PizzaOrder | |
{ | |
[DataMember(Name = "toppings")] | |
public string[] Toppings { get; set; } | |
} | |
} |
I like to write functional like C# code because it lends itself to pipelines and composition which reduce cognitive load. Your company is using F# so you know about the benefits of switching to a functional style of programming.
I wrote this as a .NET Core 1.1 console application because I want to live in the present that is pointing to the future, not gazing backwards at the past wistfully.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Rank: 1, Pizza: pepperoni, Times ordered: 4616
Rank: 2, Pizza: mozzarella cheese, Times ordered: 1014
Rank: 3, Pizza: four cheese, Times ordered: 956
Rank: 4, Pizza: bacon, Times ordered: 732
Rank: 5, Pizza: beef, Times ordered: 623
Rank: 6, Pizza: sausage, Times ordered: 402
Rank: 7, Pizza: italian sausage, Times ordered: 361
Rank: 8, Pizza: chicken, Times ordered: 229
Rank: 9, Pizza: pepperoni,four cheese, Times ordered: 203
Rank: 10, Pizza: ham, Times ordered: 165
Rank: 11, Pizza: mushrooms, Times ordered: 159
Rank: 12, Pizza: mozzarella cheese,pepperoni, Times ordered: 155
Rank: 13, Pizza: pepperoni,beef, Times ordered: 122
Rank: 14, Pizza: bacon,pepperoni, Times ordered: 121
Rank: 15, Pizza: black olives, Times ordered: 117
Rank: 16, Pizza: alredo sauce, Times ordered: 101
Rank: 17, Pizza: sausage,pepperoni, Times ordered: 96
Rank: 18, Pizza: cheddar cheese, Times ordered: 95
Rank: 19, Pizza: italian sausage,pepperoni, Times ordered: 85
Rank: 20, Pizza: pineapple, Times ordered: 79