public void Constructor_GivenValidChargeableDevice_SetsPropertiesAsExpected(IChargeableDevice device, int expectedLowInput, int expectedHighInput, IDictionary <int, bool> testSocketData) { var sut = new ChargeableDevice(device); Assert.Equal(expectedLowInput, sut.LowInput); Assert.Equal(expectedHighInput, sut.HighInput); foreach (var kvp in testSocketData) { var testSocket = MockSocket(kvp.Key); Assert.Equal(kvp.Value, sut.CanAttach(testSocket)); } }
/// <inheritdoc/> public long Permute(IEnumerable <ISocket> toPermute, ChargeableDevice toCharge) { // combine our lists. Did this to ensure only one chargeable device at the end of all of this. var devices = toPermute.Select(adapter => adapter as IDevice).Append(toCharge); var chargingPorts = devices.Where(device => device is Socket).Count(); if (chargingPorts > 1) { throw new ArgumentException("toPermute may have at most one Socket", nameof(toPermute)); } if (chargingPorts == 0) { // Need to create our own, I guess. var chargingPort = new Socket(); devices = devices.Append(chargingPort); } var socketsWithPlugs = devices .Where(device => device is ISocket) .Select(device => (ISocket)device) .OrderBy(device => device.Output) .Select( socket => new { socketVoltage = socket.Output, plugs = devices .Where(device => device is IChargeableDevice) .Select(device => ((IChargeableDevice)device)) .Where(device => device.CanAttach(socket)) .OrderByDescending(device => device.LowInput) } ); var waysToGetThere = new Dictionary <int, long>(); // creating a running list of how many ways it takes to get to the goal LowInput from each previous spot waysToGetThere.Add(toCharge.HighInput + 1, 1); foreach (var socketPlug in socketsWithPlugs.OrderByDescending(sp => sp.socketVoltage)) { long waysThereFromHere = 0; foreach (var plug in socketPlug.plugs) { waysThereFromHere += waysToGetThere[plug.HighInput + 1]; // fake out the output } waysToGetThere.Add(socketPlug.socketVoltage, waysThereFromHere); } return(waysToGetThere.Values.Max()); }
public int CreateStack(IEnumerable <IDevice> toStack) { var chargeables = toStack.Where(device => device is ChargeableDevice).Count(); if (chargeables > 1) { throw new ArgumentException("toStack may only have at most one ChargeableDevice", nameof(toStack)); } var chargingPorts = toStack.Where(device => device is Socket).Count(); if (chargingPorts > 1) { throw new ArgumentException("toStack may have at most one Socket", nameof(toStack)); } if (chargeables == 0) { // Need to create our own, I guess. var toCharge = new ChargeableDevice(toStack.Where(device => device is ISocket).Select(socket => (ISocket)socket)); toStack = toStack.Append(toCharge); } if (chargingPorts == 0) { // Need ot create our own, I guess. var chargingPort = new Socket(); toStack = toStack.Append(chargingPort); } // Sort the source devices by their output var sources = toStack.Where(device => device is ISocket).Select(device => device as ISocket).OrderBy(device => device.Output); // Sort the sink devices by their lower input var sinks = toStack.Where(device => device is IChargeableDevice).Select(device => device as IChargeableDevice).OrderBy(device => device.LowInput); // If all is correct, the elements in sources and sinks OUGHT to be matched such that we can pair them up trivially and all will satisfy IChargeableDevice.CanAttach var stack = sources.Zip(sinks, (source, sink) => new { Socket = source, Plug = sink }); // Sanity check if (stack.Where(pair => pair.Plug.CanAttach(pair.Socket) == false).Any()) { throw new ArgumentException("Could not pair up sockets and plugs"); } var threes = stack.Where(pair => pair.Plug.LowInput == pair.Socket.Output).Count(); var ones = stack.Where(pair => pair.Plug.HighInput == pair.Socket.Output).Count(); return(threes * ones); }
public void Constructor_GivenSourcesAndOutputSelector_SetsPropertiesAsExpected( IEnumerable <ISocket> sources, Func <IEnumerable <ISocket>, int> outputSelector, int expectedLowInput, int expectedHighInput, IDictionary <int, bool> testSocketData ) { var sut = new ChargeableDevice(sources, outputSelector); Assert.Equal(expectedLowInput, sut.LowInput); Assert.Equal(expectedHighInput, sut.HighInput); foreach (var kvp in testSocketData) { var testSocket = MockSocket(kvp.Key); Assert.Equal(kvp.Value, sut.CanAttach(testSocket)); } }
/// <summary> /// AdaptrStackr.Cmd entry point /// </summary> /// <param name="args">Command line arguments (not used)</param> static void Main(string[] args) { var filePath = "./input"; var reader = new FileReader(); var inputs = reader.ReadFileByLines(filePath); if (inputs.Where(input => int.TryParse(input, out var _) == false).Any()) { throw new FormatException("Could not parse the input data."); } var adapters = inputs.Select(input => new Adapter(int.Parse(input))); var stacker = new DeviceStacker(); var result = stacker.CreateStack(adapters); Console.WriteLine(result); var toCharge = new ChargeableDevice(adapters); var permutations = stacker.Permute(adapters, toCharge); Console.WriteLine(permutations); }
public void CountPermutations_GivenGoodData_ReturnsExpectedResult(IEnumerable <ISocket> toPermute, ChargeableDevice toCharge, int expectedPermutationCount) { var sut = new DeviceStacker(); var result = sut.Permute(toPermute, toCharge); Assert.Equal(expectedPermutationCount, result); }