Skip to content

Instantly share code, notes, and snippets.

@ghthor
Created July 30, 2021 19:03
Show Gist options
  • Save ghthor/8ae36becc53c5f2a79c43c7e57239ffd to your computer and use it in GitHub Desktop.
Save ghthor/8ae36becc53c5f2a79c43c7e57239ffd to your computer and use it in GitHub Desktop.
Product Pricing
/*
(ns ch-market-place.core-test
(:require [clojure.test :refer :all]
[ch-market-place.core :refer :all]))
;; Here are the minimal inputs you should use for your test
;; cases. These test cases must be shown to work in your program:
;; Scan these items in this order: ABCDABAA; Verify the total price is
;; $32.40.
;; Scan these items in this order: CCCCCCC; Verify the total price is
;; $7.25.
;; Scan these items in this order: ABCD; Verify the total price is
;; $15.40.
(deftest test-market-place)
(ns ch-market-place.core)
;; Consider a store where items have prices per unit but also volume
;; prices. For example, apples may be $1.00 each or 4 for $3.00.
;; Implement a point-of-sale scanning API that accepts an arbitrary
;; ordering of products (similar to what would happen at a checkout
;; line) and then returns the correct total price for an entire
;; shopping cart based on the per unit prices or the volume prices as
;; applicable.
;; Here are the products listed by code and the prices to use (there
;; is no sales tax):
;; Product Code | Price
;; --------------------
;; A | $2.00 each or 4 for $7.00
;; B | $12.00
;; C | $1.25 or $6 for a six pack
;; D | $0.15
;; In your solution there should be a top level point of sale
;; function that looks something like the code below.
;; You are free to design and implement the rest of the code
;; however you wish, including how you specify the prices in the
;; system:
;; This should accept ABCDABAA and return $32.40.
;; This should accept CCCCCCC and return $7.25.
(defn total-price [products])
*/
package main
import "fmt"
const Dollar = 100
type Cents int
func (c Cents) String() string {
dollars := c / 100
cents := c % 100
return fmt.Sprintf(" $%d.%02d", dollars, cents)
}
type Product interface {
TotalFor(count int) Cents
}
type SinglePrice struct {
PricePerItem Cents
}
type BulkPrice struct {
GroupSize int
PricePerItem Cents
PricePerGroup Cents
}
func (p SinglePrice) TotalFor(count int) Cents {
return Cents(count) * p.PricePerItem
}
func (p BulkPrice) TotalFor(count int) Cents {
// if count < p.GroupSize {
// return Cents(count) * p.PricePerItem
// }
groups := Cents(count / p.GroupSize)
remainder := Cents(count % p.GroupSize)
totalCents := Cents(0)
totalCents += (groups * p.PricePerGroup)
totalCents += (remainder * p.PricePerItem)
return totalCents
}
// ;; Product Code | Price
// ;; --------------------
// ;; A | $2.00 each or 4 for $7.00
// ;; B | $12.00
// ;; C | $1.25 or $6 for a six pack
// ;; D | $0.15
var Products = map[rune]Product{
'A': BulkPrice{4, 2 * Dollar, 7 * Dollar},
'B': SinglePrice{12 * Dollar},
'C': BulkPrice{6, 125, 6 * Dollar},
'D': SinglePrice{15},
}
func totalPrice(cart string) Cents {
totalCount := make(map[rune]int)
for _, r := range cart {
c, exists := totalCount[r]
if exists {
totalCount[r] = c + 1
} else {
totalCount[r] = 1
}
}
const Dollar = 100
totalCents := Cents(0)
for k, count := range totalCount {
p := Products[k]
totalCents += p.TotalFor(count)
// switch k {
// case 'A':
// if count < 4 {
// totalCents += (count * 2 * Dollar)
// continue
// }
// groups := count / 4
// remainder := count % 4
// totalCents += (groups * 7 * Dollar)
// totalCents += (remainder * 2 * Dollar)
// case 'B':
// totalCents += count * 12 * Dollar
// case 'C':
// if count < 6 {
// totalCents += (count * 125)
// continue
// }
// groups := count / 6
// remainder := count % 6
// totalCents += (groups * 6 * Dollar)
// totalCents += (remainder * 125)
// case 'D':
// totalCents += count * 15
// }
}
return Cents(totalCents)
}
func main() {
fmt.Println("vim-go")
// ;; Scan these items in this order: ABCDABAA; Verify the total price is
// ;; $32.40.
fmt.Println(totalPrice("ABCDABAA"))
// ;; Scan these items in this order: CCCCCCC; Verify the total price is
// ;; $7.25.
fmt.Println(totalPrice("CCCCCCC"))
// ;; Scan these items in this order: ABCD; Verify the total price is
// ;; $15.40.
fmt.Println(totalPrice("ABCD"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment