From 9e9aa098b78b572eef190677443dcd91a1cba8b3 Mon Sep 17 00:00:00 2001 From: paulbenjamin3409 Date: Mon, 26 Jan 2026 18:13:58 -0600 Subject: [PATCH 1/2] Initial commit --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d9c2e002 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +/.vs +/CashRegister/.vs/CashRegister +/CashRegister/bin/Debug/net9.0 +/CashRegister/obj From 8b100cb4992599dc9f5c61e43c0d45f22b337a28 Mon Sep 17 00:00:00 2001 From: paulbenjamin3409 Date: Mon, 26 Jan 2026 18:14:58 -0600 Subject: [PATCH 2/2] Main Program --- CashRegister/CashRegister.csproj | 22 ++++ CashRegister/CashRegister.sln | 25 ++++ CashRegister/Program.cs | 194 +++++++++++++++++++++++++++++++ CashRegister/denomination.csv | 10 ++ CashRegister/divisor.txt | 1 + CashRegister/transactions.csv | 3 + 6 files changed, 255 insertions(+) create mode 100644 CashRegister/CashRegister.csproj create mode 100644 CashRegister/CashRegister.sln create mode 100644 CashRegister/Program.cs create mode 100644 CashRegister/denomination.csv create mode 100644 CashRegister/divisor.txt create mode 100644 CashRegister/transactions.csv diff --git a/CashRegister/CashRegister.csproj b/CashRegister/CashRegister.csproj new file mode 100644 index 00000000..3809c25b --- /dev/null +++ b/CashRegister/CashRegister.csproj @@ -0,0 +1,22 @@ + + + + Exe + net9.0 + enable + enable + + + + + Always + + + Always + + + Always + + + + diff --git a/CashRegister/CashRegister.sln b/CashRegister/CashRegister.sln new file mode 100644 index 00000000..a28e73f0 --- /dev/null +++ b/CashRegister/CashRegister.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36915.13 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CashRegister", "CashRegister.csproj", "{CE3E71EF-2232-442D-8ED6-D88B79016264}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CE3E71EF-2232-442D-8ED6-D88B79016264}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE3E71EF-2232-442D-8ED6-D88B79016264}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE3E71EF-2232-442D-8ED6-D88B79016264}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE3E71EF-2232-442D-8ED6-D88B79016264}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {07EBE533-1856-402A-9985-7D4BFE493F5A} + EndGlobalSection +EndGlobal diff --git a/CashRegister/Program.cs b/CashRegister/Program.cs new file mode 100644 index 00000000..83a804e6 --- /dev/null +++ b/CashRegister/Program.cs @@ -0,0 +1,194 @@ +class Program +{ + + static void Main() + { + // Inputs + string sourceFile = "transactions.csv"; + string destinationFile = "output.txt"; + string denominationsFile = "denomination.csv"; + string divisorFile = "divisor.txt"; + + try + { + + // Get Data + int divisor = int.Parse(File.ReadAllText(divisorFile)); + + var transactions = GetFileData(sourceFile, divisor); + + var denominations = GetDenominations(denominationsFile); + + // Parse Data + var results = ParseTransaction(denominations, transactions); + + // Write results + WriteFileData(destinationFile, results); + + } + catch (Exception ex) + { + System.Console.WriteLine("Error: ", ex); + } + + } + + private static List ParseTransaction(List denominations, List transactions) + { + var parsedTransactions = new List(); + + foreach (var transaction in transactions) + { + try + { + // Per Transaction Rules can be applied here + + parsedTransactions.Add( + GetChange(denominations, transaction.amountOwed, transaction.amountPaid, transaction.divisibleByInput) + ); + + } + catch (Exception) + { + // skip invalid transactions; no requirements specified; + } + } + + return parsedTransactions; + } + + + #region File Operations + + + private static List GetFileData(string sourceFile, int divisor) + { + if (File.Exists(sourceFile) == false) + { + throw new FileNotFoundException("Source file not found", sourceFile); + } + + // File Format: Amount Owed, Amount Paid + return File.ReadLines(sourceFile) + .Select(line => + { + var parts = line.Split(','); + + return new Transaction + { + amountOwed = decimal.Parse(parts[0]), + amountPaid = decimal.Parse(parts[1]), + divisibleByInput = (int)(decimal.Parse(parts[0]) * 100) % divisor == 0 + }; + }) + .ToList(); + } + + private static void WriteFileData(string destinationFile, List results) + { + File.WriteAllLines(destinationFile, results); + } + + /// + /// Gets the List of currencies used + /// + /// + /// + /// + private static List GetDenominations(string sourceFile) + { + if (File.Exists(sourceFile) == false) + { + throw new FileNotFoundException("Source file not found", sourceFile); + } + + // File Format: decimal value, name of denomination, plural name of denomination + return File.ReadLines(sourceFile) + .Select(line => + { + var parts = line.Split(','); + + return new Denomination + { + value = decimal.Parse(parts[0]), + name = parts[1], + namePlural = parts[2] + }; + }) + .ToList(); + } + + #endregion + + #region Calculations + + private static decimal CalculateChange(decimal amountOwed, decimal amountPaid) + { + return amountPaid - amountOwed; + } + + private static string GetChange(List denominations, decimal amountOwed, decimal amountPaid, bool divisibleByThree) + { + var changeDue = CalculateChange(amountOwed, amountPaid); + + var result = new List(); + + var mostDenomination = denominations.OrderByDescending(d => d.value).FirstOrDefault(); + + foreach (var denomination in denominations) + { + var count = Math.Floor(changeDue / denomination.value); + + // Special Rule per Demoniation here + + if (divisibleByThree && denomination.value > 0.01M) + { + count = GetRandonIntPerDenomination(mostDenomination.value, count); + } + + if (count > 0) + { + result.Add(@$"{count} {(count > 1 ? denomination.namePlural : denomination.name)}"); + changeDue -= count * denomination.value; + } + } + + return string.Join(",", result); + } + + /// + /// Used the max count in the specific denomination to get a random integer between 0 and that count + /// + /// + /// + /// + private static int GetRandonIntPerDenomination(decimal maxBound, decimal count) + { + var random = new Random(); + int upperBound = Math.Min((int)maxBound, (int)count); + int lowerBound = 0; + return random.Next(lowerBound, upperBound + 1); + } + + #endregion + + #region Classes + + public class Transaction + { + public decimal amountOwed { get; set; } = 0.00M; + public decimal amountPaid { get; set; } = 0.00M; + + public bool divisibleByInput { get; set; } = false; + } + + public class Denomination + { + public decimal value { get; set; } = 0.00M; + public string name { get; set; } = default!; + public string namePlural { get; set; } = default!; + } + + #endregion + +} \ No newline at end of file diff --git a/CashRegister/denomination.csv b/CashRegister/denomination.csv new file mode 100644 index 00000000..14b3fb13 --- /dev/null +++ b/CashRegister/denomination.csv @@ -0,0 +1,10 @@ +100.00,hundred,hundreds +50.00,fifty,fifties +20.00,twenty,tenties +10.00,ten,tens +5.00,five,fives +1.00,dollar,dollars +0.25,quarter,quarters +0.10,dime,dimes +0.05,nickel,nickels +0.01,penny,pennies \ No newline at end of file diff --git a/CashRegister/divisor.txt b/CashRegister/divisor.txt new file mode 100644 index 00000000..e440e5c8 --- /dev/null +++ b/CashRegister/divisor.txt @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/CashRegister/transactions.csv b/CashRegister/transactions.csv new file mode 100644 index 00000000..fba6116f --- /dev/null +++ b/CashRegister/transactions.csv @@ -0,0 +1,3 @@ +2.12,3.00 +1.97,2.00 +3.33,5.00 \ No newline at end of file