Milo Engineering Problem #2

I’m a fan of Ted Dziuba and enjoy reading his blog. I follow his twitter and he sent out a tweet a couple hours ago, apparently Bryce over at SctollingText posted his solution to his company’s (Milo) engineering challenge. You can take a look at Milo’s Engineering Challenge #2 for yourself. It’s a great little logic problem and engineering puzzle. The problem, Bryce got it wrong, opps. And he forgot to credit Milo, double opps. Oh did I mention it’s the MILO’s ENGINEERING CHALLENGE!!!!

I hate posting results to evaluation challenges, usually I play with them behind the scenes. But seeming this wrong answer is in the wild I wanted to take a crack at it. I’m using my language of choice, C#, and because the challenge mentioned language specific features I used Linq, TPL, auto properties, etc. Seeming Ted’s a *NIX guy I’m sure he doesn’t realize how bad he’s got it compared to us Windows programmers.

I time boxed 30 minutes to get something done. I went a little over but not by too much. Factor in this blog post and I’m probably a little over an hour spent on it. I didn’t have enough time to get to the 3rd part of the challenge, and it seems the most time/code intensive bit. My working theory was creating an array of all the unique parts of a name (length of 2 or more chars), then searching for an occurrence of any of those in the target string.

Logic.cs File

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace EP2CS
{
	public class Logic
	{
		public List<Product> Products { get; set;}
		public List<Customer> Customers { get; set; }

		public void PopulateProductsAndCustomersLists(string productsFileLocation, string customersFileLocation)
		{
			// Reset our lists
			Products = new List<Product>();
			Customers = new List<Customer>();

			// Load and read the products file
			if (File.Exists(productsFileLocation))
			{
				string[] lines = File.ReadAllLines(productsFileLocation);

				Parallel.ForEach(lines, line =>
				                        	{
				                        		Product p = new Product();
				                        		p.Name = line;

				                        		p.IsNameEven = (p.Name.Length % 2 == 0);
				                        		if (p.IsNameEven)
				                        			p.Multipler = 1.5f;
				                        		else
				                        			p.Multipler = 1f;

																		Products.Add(p);
				                        	}

					);
			}

			// Load and read the customers file
			if (File.Exists(customersFileLocation))
			{
				string[] lines = File.ReadAllLines(customersFileLocation);

				Parallel.ForEach(lines, line =>
				                        	{
				                        		Customer c = new Customer();
				                        		c.Name = line;
				                        		c.VowelCount = StringHelpers.CountVowels(c.Name);

																		Customers.Add(c);
				                        	}
					);
			}
		}

		public List<Suitability> ScoreCustomersAndProducts()
		{
			if (Products == null || Customers == null)
				return null;

			List<Suitability> suitability = new List<Suitability>();
			List<Customer> pickList = new List<Customer>(Customers);

			Parallel.ForEach(Products, product =>
			                           	{
			                           		Customer c = null;
																		lock (pickList)
																		{
																			while (c == null)
																			{
																				c = pickList.First();
																				pickList.Remove(c);
																			}
																		}

																		Suitability s = new Suitability();
			                           		s.Customer = c;
			                           		s.Product = product;

																		if (product.IsNameEven)
																			s.Score = c.VowelCount * product.Multipler;
																		else
																			s.Score = c.ConsonantCount * product.Multipler;

																		suitability.Add(s);
			                           	}
				);

			return suitability;
		}
	}
}

Customers:

Mark
Jason
Gabe
Terry
Bud
Debbie
Dale
Dean
Paul
Shawn

Products:

Epic Cool Prod
Epic Cool Prod II
Epic Cool Prod III
Cheap Junk
Imported Lead Filled Toy

The Result:

Scoring Result
  =========================

Result Count: 5
Total Score: 12

Product: Cheap Junk
        Length: 10      Multipler: 1.5
Customer: Dean
        Length: 4       Vowels: 2       Consonants: 2
Score: 3

Product: Epic Cool Prod II
        Length: 17      Multipler: 1
Customer: Debbie
        Length: 6       Vowels: 3       Consonants: 3
Score: 3

Product: Epic Cool Prod
        Length: 14      Multipler: 1.5
Customer: Gabe
        Length: 4       Vowels: 2       Consonants: 2
Score: 3

Product: Imported Lead Filled Toy
        Length: 24      Multipler: 1.5
Customer: Shawn
        Length: 5       Vowels: 1       Consonants: 4
Score: 1.5

Product: Epic Cool Prod III
        Length: 18      Multipler: 1.5
Customer: Terry
        Length: 5       Vowels: 1       Consonants: 4
Score: 1.5

Spent more time on it then I wanted but I think it’s working for the first two requirements. My initial thoughts on completing the third part would be pretty CPU/Mem intensive so I’d have to play with it a little to come up with a more elegant solution.

Download the source

About: Shawn Jackson

I’ve spent the last 18 years in the world of Information Technology on both the IT and Development sides of the aisle. I’m currently a Software Engineer for Paylocity. In addition to working at Paylocity, I’m also the Founder of Resgrid, a cloud services company dedicated to providing logistics and management solutions to first responder organizations, volunteer and career fire departments, EMS, ambulance services, search and rescue, public safety, HAZMAT and others.