Refactored BestCombination.FindFrom2

This commit is contained in:
AJ
2024-12-29 22:17:05 -05:00
parent 58b3c49cc6
commit 8651465864

View File

@@ -6,99 +6,110 @@ namespace SawCut
{ {
public static BestComboResult FindFrom2(double length1, double length2, double stockLength) public static BestComboResult FindFrom2(double length1, double length2, double stockLength)
{ {
var result = new BestComboResult(); var result = InitializeResult(length1, length2);
result.Item1Length = length1;
result.Item2Length = length2;
stockLength += Tolerance.Epsilon; stockLength += Tolerance.Epsilon;
if (length1 > stockLength) if (length1 > stockLength)
{ {
if (length2 > stockLength) if (length2 > stockLength)
{
//throw new Exception($"Either {nameof(length1)} or {nameof(length2)} must be less than or equal to the {nameof(stockLength)}");
return null; return null;
}
result.Item1Count = 0; return CalculateSingleItemResult(result, length2, stockLength, false);
result.Item2Count = (int)Math.Floor(stockLength / length2);
return result;
} }
else if (length2 > stockLength)
if (length2 > stockLength)
{ {
result.Item1Count = (int)Math.Floor(stockLength / length1); return CalculateSingleItemResult(result, length1, stockLength, true);
result.Item2Count = 0;
return result;
} }
else
{
return CalculateOptimalCombination(result, length1, length2, stockLength);
}
}
private static BestComboResult InitializeResult(double length1, double length2)
{
return new BestComboResult
{
Item1Length = length1,
Item2Length = length2
};
}
private static BestComboResult CalculateSingleItemResult(BestComboResult result, double length, double stockLength, bool isItem1)
{
if (isItem1)
{
result.Item1Count = (int)Math.Floor(stockLength / length);
result.Item2Count = 0;
}
else
{
result.Item1Count = 0;
result.Item2Count = (int)Math.Floor(stockLength / length);
}
return result;
}
private static BestComboResult CalculateOptimalCombination(BestComboResult result, double length1, double length2, double stockLength)
{
var maxCountLength1 = (int)Math.Floor(stockLength / length1); var maxCountLength1 = (int)Math.Floor(stockLength / length1);
result.Item1Count = maxCountLength1; result.Item1Count = maxCountLength1;
result.Item2Count = 0; result.Item2Count = 0;
var remnant = stockLength - maxCountLength1 * length1; var remnant = stockLength - maxCountLength1 * length1;
if (remnant.IsEqualTo(0))
return result;
for (int countLength1 = 0; countLength1 <= maxCountLength1; ++countLength1) for (int countLength1 = 0; countLength1 <= maxCountLength1; ++countLength1)
{ {
var remnant1 = stockLength - countLength1 * length1; var remnant1 = stockLength - countLength1 * length1;
if (remnant1 >= length2) if (remnant1 >= length2)
{ remnant = UpdateResultForTwoItems(result, length2, remnant1, remnant, countLength1);
var countLength2 = (int)Math.Floor(remnant1 / length2);
var remnant2 = remnant1 - length2 * countLength2;
if (!(remnant2 < remnant))
continue;
result.Item1Count = countLength1;
result.Item2Count = countLength2;
if (remnant2.IsEqualTo(0))
break;
remnant = remnant2;
}
else else
{ remnant = UpdateResultForOneItem(result, remnant1, remnant, countLength1);
if (!(remnant1 < remnant))
continue;
result.Item1Count = countLength1; if (remnant.IsEqualTo(0))
result.Item2Count = 0; break;
if (remnant1.IsEqualTo(0))
break;
remnant = remnant1;
}
} }
return result; return result;
} }
private static double UpdateResultForTwoItems(BestComboResult result, double length2, double remnant1, double currentRemnant, int countLength1)
{
var countLength2 = (int)Math.Floor(remnant1 / length2);
var remnant2 = remnant1 - countLength2 * length2;
if (remnant2 < currentRemnant)
{
result.Item1Count = countLength1;
result.Item2Count = countLength2;
return remnant2;
}
return currentRemnant;
}
private static double UpdateResultForOneItem(BestComboResult result, double remnant1, double currentRemnant, int countLength1)
{
if (remnant1 < currentRemnant)
{
result.Item1Count = countLength1;
result.Item2Count = 0;
return remnant1;
}
return currentRemnant;
}
} }
public class BestComboResult public class BestComboResult
{ {
public double Item1Length { get; set; } public double Item1Length { get; set; }
public int Item1Count { get; set; } public int Item1Count { get; set; }
public double Item1TotalLength => Item1Length * Item1Count;
public double Item1TotalLength
{
get { return Item1Length * Item1Count; }
}
public double Item2Length { get; set; } public double Item2Length { get; set; }
public int Item2Count { get; set; } public int Item2Count { get; set; }
public double Item2TotalLength => Item2Length * Item2Count;
public double Item2TotalLength
{
get { return Item2Length * Item2Count; }
}
} }
} }