Last active
August 28, 2020 10:30
-
-
Save o0101/83fd043e9f8e8f06fba95f93a8a1d6a4 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
#region Instructions | |
/* | |
* this as a secret gist: | |
* https://gist.github.com/dosyago-coder-0/83fd043e9f8e8f06fba95f93a8a1d6a4 | |
* | |
*/ | |
/* | |
* You are tasked with writing an algorithm that determines the value of a used car, | |
* given several factors. | |
* | |
* AGE: Given the number of months of how old the car is, reduce its value one-half | |
* (0.5) percent. | |
* After 10 years, it's value cannot be reduced further by age. This is not | |
* cumulative. | |
* | |
* MILES: For every 1,000 miles on the car, reduce its value by one-fifth of a | |
* percent (0.2). Do not consider remaining miles. After 150,000 miles, it's | |
* value cannot be reduced further by miles. | |
* | |
* PREVIOUS OWNER: If the car has had more than 2 previous owners, reduce its value | |
* by twenty-five (25) percent. If the car has had no previous | |
* owners, add ten (10) percent of the FINAL car value at the end. | |
* | |
* COLLISION: For every reported collision the car has been in, remove two (2) | |
* percent of it's value up to five (5) collisions. | |
* | |
* | |
* Each factor should be off of the result of the previous value in the order of | |
* 1. AGE | |
* 2. MILES | |
* 3. PREVIOUS OWNER | |
* 4. COLLISION | |
* | |
* E.g., Start with the current value of the car, then adjust for age, take that | |
* result then adjust for miles, then collision, and finally previous owner. | |
* Note that if previous owner, had a positive effect, then it should be applied | |
* AFTER step 4. If a negative effect, then BEFORE step 4. | |
*/ | |
#endregion | |
using System; | |
using NUnit.Framework; | |
namespace CarPricer | |
{ | |
public class Car | |
{ | |
public decimal PurchaseValue { get; set; } | |
public int AgeInMonths { get; set; } | |
public int NumberOfMiles { get; set; } | |
public int NumberOfPreviousOwners { get; set; } | |
public int NumberOfCollisions { get; set; } | |
} | |
public class PriceDeterminator | |
{ | |
public const decimal MONTH_PENALTY_PERCENT = 0.5 | |
public const int MAX_YEARS_PENALIZED = 10 | |
public const decimal KILOMILE_PENALTY_PERCENT = 0.2 | |
public const int MAX_MILES_PENALIZED = 150000 | |
public const decimal PRIOR_OWNER_PENALTY_PERCENT = 25.0 | |
public const decimal NO_PRIOR_OWNERS_BONUS_PERCENT = 10.0 | |
public const int PRIOR_OWNER_THRESHOLD_TO_PENALIZE = 2 | |
public const decimal COLLISION_PENALTY_PERCENT = 2.0 | |
public const int MAX_COLLISIONS_PENALIZED = 5 | |
public decimal DetermineCarPrice(Car car) | |
{ | |
let value = car.PurchaseValue; | |
let months = car.AgeInMonths; | |
let yearsCounted = 0; | |
while( months-- ) { | |
value *= (100.0 - this.MONTH_PENALTY_PERCENT)/(100.0); | |
yearsCounted += (1.0/12); | |
if ( yearsCounted >= this.MAX_YEARS_PENALIZED ) break; | |
} | |
let miles = car.NumberOfMiles; | |
let milesCounted = 0; | |
while( miles - 1000 > 0 ) { | |
value *= (100.0 - this.KILOMILE_PENALTY_PERCENT)/100.0; | |
miles -= 1000; | |
milesCounted += 1000; | |
if ( milesCounted >= this.MAX_MILES_PENALIZED ) break; | |
} | |
let priorOwners = car.NumberOfPreviousOwners; | |
let noOwnersBonus = false; | |
if ( priorOwners >= this.OWNER_THRESHOLD_TO_PENALIZE ) { | |
value *= (100.0 - this.PRIOR_OWNER_PENALTY_PERCENT)/100.0; | |
} else if ( priorOwners < this.OWNER_THRESHOLD_TO_PENALIZE ) { | |
noOwnersBonus = true; | |
} | |
let collisions = car.NumberOfCollisions; | |
let collisionsCounted = 0; | |
while( collisions-- ) { | |
value *= (100.0 - this.COLLISION_PENALTY_PERCENT)/100.0; | |
collisionsCounted += 1; | |
if ( collisionsCounted > this.MAX_COLLISIONS_PENALIZED ) break; | |
} | |
if ( noOwnersBonus ) { | |
value *= (100.0+this.NO_PRIOR_OWNERS_BONUS_PERCENT)/100.0; | |
} | |
return value; | |
} | |
} | |
public class UnitTests | |
{ | |
public void CalculateCarValue() | |
{ | |
AssertCarValue(25313.40m, 35000m, 3 * 12, 50000, 1, 1); | |
AssertCarValue(19688.20m, 35000m, 3 * 12, 150000, 1, 1); | |
AssertCarValue(19688.20m, 35000m, 3 * 12, 250000, 1, 1); | |
AssertCarValue(20090.00m, 35000m, 3 * 12, 250000, 1, 0); | |
AssertCarValue(21657.02m, 35000m, 3 * 12, 250000, 0, 1); | |
} | |
private static void AssertCarValue(decimal expectValue, decimal purchaseValue, | |
int ageInMonths, int numberOfMiles, int numberOfPreviousOwners, int | |
numberOfCollisions) | |
{ | |
Car car = new Car | |
{ | |
AgeInMonths = ageInMonths, | |
NumberOfCollisions = numberOfCollisions, | |
NumberOfMiles = numberOfMiles, | |
NumberOfPreviousOwners = numberOfPreviousOwners, | |
PurchaseValue = purchaseValue | |
}; | |
PriceDeterminator priceDeterminator = new PriceDeterminator(); | |
var carPrice = priceDeterminator.DetermineCarPrice(car); | |
Assert.AreEqual(expectValue, carPrice); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment