Skip to content

Instantly share code, notes, and snippets.

@ivanxpetrov
Last active May 18, 2018 03:18
Show Gist options
  • Select an option

  • Save ivanxpetrov/1f3f858be5b7d725add215b99fa6ca53 to your computer and use it in GitHub Desktop.

Select an option

Save ivanxpetrov/1f3f858be5b7d725add215b99fa6ca53 to your computer and use it in GitHub Desktop.
/*
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