Last active
May 18, 2018 03:18
-
-
Save ivanxpetrov/1f3f858be5b7d725add215b99fa6ca53 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| /* | |
| RUN in LinqPad. | |
| NUnitLite 3.2 depedency from NUget | |
| A program that outputs the possible sequences of digits from 1 to 9 whose sum is 100. | |
| e.g. | |
| 12-3-4+5-6+7+89 | |
| */ | |
| void Main() | |
| { | |
| new AutoRun().Execute(new[]{"--noheader","--noresult"}); | |
| GenerateAllPossibleCombinationsFor(100, 1, 9); | |
| } | |
| void GenerateAllPossibleCombinationsFor(int desiredResult, int firstDigit, int lastDigit) | |
| { | |
| if (firstDigit < 1 || firstDigit > 9) | |
| { | |
| throw new ArgumentException($"{nameof(firstDigit)} needs to be within 1 to 9 "); | |
| } | |
| if (lastDigit < 1 || lastDigit > 9) | |
| { | |
| throw new ArgumentException($"{nameof(lastDigit)} needs to be within 1 to 9 "); | |
| } | |
| var listOfLevels = new Dictionary<int, List<Accumulation>>(); | |
| for (int i = firstDigit; i <= lastDigit; i++) | |
| { | |
| listOfLevels[i] = new List<Accumulation>(); | |
| } | |
| var initialAccumulation = new Accumulation(firstDigit); | |
| listOfLevels[firstDigit].Add(initialAccumulation); | |
| for (int i = firstDigit + 1; i <= lastDigit; i++) | |
| { | |
| foreach (var element in listOfLevels[i - 1]) | |
| { | |
| foreach (StepOption stepOption in Accumulation.SupportedOptions) | |
| { | |
| var newAccumulation = element.AccumulateNextStep(i, stepOption); | |
| listOfLevels[i].Add(newAccumulation); | |
| } | |
| } | |
| } | |
| var result = listOfLevels[lastDigit] | |
| .Where(x => x.Result == desiredResult) | |
| .Select(x => new { x.AccumulatedExpression, x.Result }); | |
| result.Dump(); | |
| } | |
| public enum StepOption | |
| { | |
| Concat, | |
| Add, | |
| Subtract, | |
| Multiply, | |
| Divide, | |
| } | |
| public class Accumulation | |
| { | |
| public static IEnumerable<StepOption> SupportedOptions = new List<StepOption> | |
| { | |
| StepOption.Subtract, | |
| StepOption.Add, | |
| StepOption.Concat, | |
| }; | |
| public Accumulation(int initialNumber) | |
| { | |
| this.Result = initialNumber; | |
| this.AccumulatedExpression = initialNumber.ToString(); | |
| this.LastDigit = initialNumber; | |
| } | |
| public int Result { get; set; } | |
| public string AccumulatedExpression { get; set; } | |
| public int LastDigit { get; set; } | |
| public Accumulation AccumulateNextStep(int nextStep, StepOption stepOption) | |
| { | |
| if (!SupportedOptions.Contains(stepOption)) | |
| { | |
| throw new ArgumentException($@"{stepOption} is not supported. | |
| The only options that are supported are {string.Join(",", Accumulation.SupportedOptions)} | |
| "); | |
| } | |
| var newObject = (Accumulation)this.MemberwiseClone(); | |
| switch (stepOption) | |
| { | |
| case StepOption.Add: | |
| newObject.LastDigit = nextStep; | |
| newObject.AccumulatedExpression = newObject.AccumulatedExpression + $"+{nextStep}"; | |
| newObject.Result = newObject.Result + nextStep; | |
| break; | |
| case StepOption.Subtract: | |
| newObject.LastDigit = nextStep; | |
| newObject.AccumulatedExpression = newObject.AccumulatedExpression + $"-{nextStep}"; | |
| newObject.Result = newObject.Result - nextStep; | |
| break; | |
| case StepOption.Concat: | |
| newObject.LastDigit = nextStep; | |
| var lastNumberBefore = newObject.FindLastNumberFromExpression(); | |
| newObject.AccumulatedExpression = newObject.AccumulatedExpression + nextStep; | |
| var lastNumberAfter = newObject.FindLastNumberFromExpression(); | |
| var delta = lastNumberAfter - lastNumberBefore; | |
| newObject.Result = newObject.Result + delta; | |
| break; | |
| default: | |
| break; | |
| } | |
| return newObject; | |
| } | |
| public int FindLastNumberFromExpression() | |
| { | |
| // hodi ot dqsno na lqvo dokato ne stignesh krainiq bound ili ne stignesh | |
| // + ili - | |
| var lastIndexOfExpression = this.AccumulatedExpression.Length - 1; | |
| var indexOutOfRange = -1; | |
| var result = ""; | |
| for (int i = lastIndexOfExpression; i > indexOutOfRange; i--) | |
| { | |
| if (this.AccumulatedExpression[i] == '+') | |
| { | |
| break; | |
| } | |
| result = this.AccumulatedExpression[i] + result; | |
| if (this.AccumulatedExpression[i] == '-') | |
| { | |
| break; | |
| } | |
| } | |
| var resultParsedToInt = int.Parse(result); | |
| return resultParsedToInt; | |
| } | |
| } | |
| [TestFixture] | |
| public static class AccumulationTests | |
| { | |
| public const bool DumpStrategy = false; | |
| [TestCase(DumpStrategy)] | |
| public static void AccumulateNextStepAddAndConcat_ResultShouldBeCorrect(bool useDump) | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = 24; | |
| // Act | |
| var accAddConcat = acc | |
| .AccumulateNextStep(2, StepOption.Add) | |
| .AccumulateNextStep(3, StepOption.Concat); | |
| if (useDump) | |
| { | |
| accAddConcat.Dump(); | |
| } | |
| var actual = accAddConcat.Result; | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [TestCase(false)] | |
| public static void AccumulateNextStepAddAndConcat_ExpressionShouldBeCorrect(bool useDump) | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = "1+23"; | |
| // Act | |
| var accAddConcat = acc | |
| .AccumulateNextStep(2, StepOption.Add) | |
| .AccumulateNextStep(3, StepOption.Concat); | |
| if (useDump) | |
| { | |
| accAddConcat.Dump(); | |
| } | |
| var actual = accAddConcat.AccumulatedExpression; | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [TestCase(DumpStrategy)] | |
| public static void AccumulateNextStepSubtractAndConcat_ResultShouldBeCorrect(bool useDump) | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = -22; | |
| // Act | |
| var accSubtractConcat = acc | |
| .AccumulateNextStep(2, StepOption.Subtract) | |
| .AccumulateNextStep(3, StepOption.Concat); | |
| if (useDump) | |
| { | |
| accSubtractConcat.Dump(); | |
| } | |
| var actual = accSubtractConcat.Result; | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [TestCase(false)] | |
| public static void AccumulateNextStepSubtractAndConcat_ExpressionShouldBeCorrect(bool useDump) | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = "1-23"; | |
| // Act | |
| var accSubtractConcat = acc | |
| .AccumulateNextStep(2, StepOption.Subtract) | |
| .AccumulateNextStep(3, StepOption.Concat); | |
| if (useDump) | |
| { | |
| accSubtractConcat.Dump(); | |
| } | |
| var actual = accSubtractConcat.AccumulatedExpression; | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [TestCase(DumpStrategy)] | |
| public static void AccumulateNextStepConcat_ResultShouldBeCorrect(bool useDump) | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = 12; | |
| // Act | |
| var accConcat = acc | |
| .AccumulateNextStep(2, StepOption.Concat); | |
| if (useDump) | |
| { | |
| accConcat.Dump(); | |
| } | |
| var actual = accConcat.Result; | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [TestCase(false)] | |
| public static void AccumulateNextStepConcat_ExpressionShouldBeCorrect(bool useDump) | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = "12"; | |
| // Act | |
| var accConcat = acc | |
| .AccumulateNextStep(2, StepOption.Concat); | |
| if (useDump) | |
| { | |
| accConcat.Dump(); | |
| } | |
| var actual = accConcat.AccumulatedExpression; | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [Test] | |
| public static void AccumulateNextStepMultiply() | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = 12; | |
| // Act | |
| TestDelegate testDelegate = | |
| () => acc | |
| .AccumulateNextStep(2, StepOption.Multiply); | |
| // Assert | |
| Assert.Throws<ArgumentException>(testDelegate); | |
| } | |
| [Test] | |
| public static void FindLastNumberFromExpression_SingleNumberWorksCorrectly() | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| var expected = 1; | |
| // Act | |
| var actual = acc.FindLastNumberFromExpression(); | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [Test] | |
| public static void FindLastNumberFromExpression_AfterPlusSignWorksCorrectly() | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| acc.AccumulatedExpression = "1+23"; | |
| var expected = 23; | |
| // Act | |
| var actual = acc.FindLastNumberFromExpression(); | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| [Test] | |
| public static void FindLastNumberFromExpression_AfterMinusSignWorksCorrectly() | |
| { | |
| // Arrange | |
| var acc = new Accumulation(1); | |
| acc.AccumulatedExpression = "1-23"; | |
| var expected = -23; | |
| // Act | |
| var actual = acc.FindLastNumberFromExpression(); | |
| // Assert | |
| Assert.AreEqual(expected, actual); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment