Skip to content

Instantly share code, notes, and snippets.

# caelifer/change.go Last active Dec 10, 2019

Calculate change from available pool of coins simulating automatic cash register.
 package main import ( "fmt" "log" "strings" ) func main() { b := NewBank(map[Coin]int{ Penny: 100, Nickle: 20, Dime: 10, Quater: 2, }) fmt.Printf("Started with money in the bank: %v\n", b) fmt.Println("Start dispensing change") fmt.Println() for _, v := range []int{3, 5, 10, 17, 23, 25, 41, 91, 99, 50} { fmt.Printf("Requesting change of %d cents\n", v) fmt.Printf("Dispensed coins: %s\n", b.DispenseCoins(v)) fmt.Printf("Money in the bank: %s\n", b) fmt.Println() } } type Coin int const ( Penny Coin = 1 Nickle = 5 Dime = 10 Quater = 25 ) func (c Coin) singular() string { switch c { case Penny: return "penny" case Nickle: return "nickle" case Dime: return "dime" case Quater: return "quater" } return "unknown coin" } func (c Coin) plural() string { switch c { case Penny: return "pennies" default: return c.singular() + "s" } } type CoinStack struct { Type Coin Count int } func (cs CoinStack) Value() int { return int(cs.Type) * cs.Count } func (cs *CoinStack) Get(amount int) (*CoinStack, int) { needCoins := amount / int(cs.Type) balance := amount % int(cs.Type) if needCoins > cs.Count { defficit := needCoins - cs.Count balance += defficit * int(cs.Type) needCoins, cs.Count = cs.Count, 0 } else { cs.Count -= needCoins } if cs.Count == 0 { log.Printf("out of %s", cs.Type.plural()) } return &CoinStack{Type: cs.Type, Count: needCoins}, balance } func (cs CoinStack) String() string { denom := cs.Type.plural if cs.Count == 1 { denom = cs.Type.singular } return fmt.Sprintf("%d %s", cs.Count, denom()) } type Bank struct { Store [4]*CoinStack } func NewBank(money map[Coin]int) *Bank { bank := new(Bank) // Transfer coins into bank for i, c := range []Coin{Quater, Dime, Nickle, Penny} { if count, ok := money[c]; ok { bank.Store[i] = &CoinStack{Type: c, Count: count} } } return bank } func (b *Bank) DispenseCoins(amount int) string { res := make([]string, 0, 4) for _, cs := range b.Store[:] { if cs.Count == 0 { continue } var coins *CoinStack coins, amount = cs.Get(amount) if coins.Count > 0 { res = append(res, coins.String()) } if amount == 0 { break } } if amount > 0 { log.Fatalf("Not enough coins to make change on %d cents balance", amount) } return strings.Join(res, ", ") } func (b Bank) String() string { res := make([]string, 0, 4) val := 0 for _, cs := range b.Store[:] { val += cs.Value() res = append(res, cs.String()) } return fmt.Sprintf("%.2f dollars [%v]", float64(val)/100, strings.Join(res, ", ")) }
Owner Author

### caelifer commented Dec 10, 2019 • edited

 Live code - https://play.golang.org/p/SrQkFRmRzgC Output: ``````Started with money in the bank: 3.50 dollars [2 quaters, 10 dimes, 20 nickles, 100 pennies] Start dispensing change Requesting change of 3 cents Dispensed coins: 3 pennies Money in the bank: 3.47 dollars [2 quaters, 10 dimes, 20 nickles, 97 pennies] Requesting change of 5 cents Dispensed coins: 1 nickle Money in the bank: 3.42 dollars [2 quaters, 10 dimes, 19 nickles, 97 pennies] Requesting change of 10 cents Dispensed coins: 1 dime Money in the bank: 3.32 dollars [2 quaters, 9 dimes, 19 nickles, 97 pennies] Requesting change of 17 cents Dispensed coins: 1 dime, 1 nickle, 2 pennies Money in the bank: 3.15 dollars [2 quaters, 8 dimes, 18 nickles, 95 pennies] Requesting change of 23 cents Dispensed coins: 2 dimes, 3 pennies Money in the bank: 2.92 dollars [2 quaters, 6 dimes, 18 nickles, 92 pennies] Requesting change of 25 cents Dispensed coins: 1 quater Money in the bank: 2.67 dollars [1 quater, 6 dimes, 18 nickles, 92 pennies] Requesting change of 41 cents 2009/11/10 23:00:00 out of quaters Dispensed coins: 1 quater, 1 dime, 1 nickle, 1 penny Money in the bank: 2.26 dollars [0 quaters, 5 dimes, 17 nickles, 91 pennies] Requesting change of 91 cents 2009/11/10 23:00:00 out of dimes Dispensed coins: 5 dimes, 8 nickles, 1 penny Money in the bank: 1.35 dollars [0 quaters, 0 dimes, 9 nickles, 90 pennies] Requesting change of 99 cents 2009/11/10 23:00:00 out of nickles Dispensed coins: 9 nickles, 54 pennies Money in the bank: 0.36 dollars [0 quaters, 0 dimes, 0 nickles, 36 pennies] Requesting change of 50 cents 2009/11/10 23:00:00 out of pennies 2009/11/10 23:00:00 Not enough coins to make change on 14 cents balance ``````
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.