using System.Collections.Generic;
public int id {get; set;}
ORDER_STATUS status {get; set;}
public DateTime? dispatchedTime {get; set;}
public DateTime? confirmedTime {get; set; }
public DateTime? rejectedTime {get; set; }
public DateTime? arrivalTime {get; set; }
public DateTime? deliveryTime {get; set;}
public DateTime targetArrivalStart {get; set;}
public DateTime targetArrivalEnd {get; set;}
public DateTime targetDeliveryStart {get; set;}
public DateTime targetDeliveryEnd {get; set; }
public decimal baseRate {get; set;}
public DateTime? createdWhen {get; set;}
public string createdBy {get; set;}
public static void Main()
public static void test1()
string input = "Ellen*Ripley*1234 Speedway*Tucson~Dwayne*Hicks*4567 Main*Houston~Carter*Burke*9876 Broadway*Las Vegas";
string expectedOutput = "<1><1-1>Ellen</1-1><1-2>Ripley</1-2><1-3>1234 Speedway</1-3><1-4>Tucson</1-4></1>" +
"<2><2-1>Dwayne</2-1><2-2>Hicks</2-2><2-3>4567 Main</2-3><2-4>Houston</2-4></2>" +
"<3><3-1>Carter</3-1><3-2>Burke</3-2><3-3>9876 Broadway</3-3><3-4>Las Vegas</3-4></3>";
string output = StringParser(input);
Assert.AreEqual(expectedOutput, output);
private static string StringParser(string input)
var parts = input.Split('~');
for (int i = 0; i < parts.Length; i++)
var details = parts[i].Split('*');
for (int j = 0; j < details.Length; j++)
result += $"<{i + 1}-{j + 1}>{details[j]}</{i + 1}-{j + 1}>";
public static void test2()
Assert.AreEqual(77, divisor(1232, 4, 200));
Assert.AreEqual(42.645454545454548d, divisor(234.55, 5.5, 171));
Assert.AreEqual(111, divisor(333, 3, 111));
Assert.AreEqual(20, divisor(20, 3, 33));
private static double divisor(double input, double denominator, double limit)
public static void test3()
Assert.AreEqual(77, divisorRecursive(1232, 4, 200));
Assert.AreEqual(42.645454545454548d, divisorRecursive(234.55, 5.5, 171));
Assert.AreEqual(111, divisorRecursive(333, 3, 111));
Assert.AreEqual(20, divisorRecursive(20, 3, 33));
private static double divisorRecursive(double input, double denominator, double limit)
if (input <= limit) return input;
return divisorRecursive(input / denominator, denominator, limit);
public static void test4()
Dictionary<string, string> dictionary = new Dictionary<string, string>
Assert.AreEqual("John", dictionary.GetValueOrNull("name"));
Assert.AreEqual(null, dictionary.GetValueOrNull("address"));
public static string GetValueOrNull(this Dictionary<string, string> dict, string key)
return dict.ContainsKey(key) ? dict[key] : null;
public static void test5()
List<Order> orders = new List<Order>
new Order { id = 1, status = ORDER_STATUS.DROPPED_OFF, createdWhen = new DateTime(2024, 11, 1), deliveryTime = DateTime.Now, baseRate = 10m },
new Order { id = 2, status = ORDER_STATUS.PICKED_UP, createdWhen = new DateTime(2024, 10, 20) },
new Order { id = 3, status = ORDER_STATUS.DROPPED_OFF, createdWhen = new DateTime(2024, 11, 2), deliveryTime = DateTime.Now, baseRate = 20m }
var result = FindLastDeliveredOrderAfterFirstOfMonth(orders);
Assert.AreEqual(3, result.id);
public static Order FindLastDeliveredOrderAfterFirstOfMonth(List<Order> orders)
.Where(o => o.createdWhen.HasValue && o.createdWhen.Value.Day > 1 && o.status == ORDER_STATUS.DROPPED_OFF)
.OrderByDescending(o => o.createdWhen)
public static void test6()
List<Order> orders = new List<Order>
new Order { id = 1, status = ORDER_STATUS.DROPPED_OFF, createdWhen = new DateTime(2024, 11, 1), deliveryTime = DateTime.Now, baseRate = 10m },
new Order { id = 2, status = ORDER_STATUS.PICKED_UP, createdWhen = new DateTime(2024, 10, 20) },
new Order { id = 3, status = ORDER_STATUS.DROPPED_OFF, createdWhen = new DateTime(2024, 11, 2), deliveryTime = DateTime.Now, baseRate = 20m }
.Where(o => o.createdWhen.HasValue && o.createdWhen.Value.Day > 1 && o.status == ORDER_STATUS.DROPPED_OFF)
Assert.AreEqual(3, result.id);
public static void test7()
status = ORDER_STATUS.DROPPED_OFF,
arrivalTime = DateTime.Now.AddMinutes(-10),
deliveryTime = DateTime.Now.AddMinutes(-5),
targetArrivalStart = DateTime.Now.AddMinutes(-20),
targetArrivalEnd = DateTime.Now.AddMinutes(20),
targetDeliveryStart = DateTime.Now.AddMinutes(-15),
targetDeliveryEnd = DateTime.Now.AddMinutes(15)
Assert.AreEqual(108m, CalculateDriverPay(order));
private static decimal CalculateDriverPay(Order order)
if (order.status == ORDER_STATUS.REJECTED)
if (order.status == ORDER_STATUS.CONFIRMED)
decimal pay = order.status == ORDER_STATUS.DROPPED_OFF ? order.baseRate : 0;
if (order.arrivalTime.HasValue && order.arrivalTime >= order.targetArrivalStart && order.arrivalTime <= order.targetArrivalEnd)
pay += order.baseRate * 0.03m;
if (order.deliveryTime.HasValue && order.deliveryTime >= order.targetDeliveryStart && order.deliveryTime <= order.targetDeliveryEnd)
pay += order.baseRate * 0.05m;