Implementing Specials

Take a look at the implementation of the specials module.

The implementation

A simple method is to count how many of each item is in the list. Account for the specials first, reducing the count every time the specials apply, and then run over the list of items that are not on sale.

-type item() :: string().
-type price() :: integer().
-type special() :: {item(), pos_integer(), price()}.

-spec total([item()], [{item(), price()}], [special()]) -> price(). 
total(ItemList, PriceList, Specials) ->
    Counts = count_seen(ItemList),
    {CountsLeft, Prices} = apply_specials(Counts, Specials), 
    Prices + apply_regular(CountsLeft, PriceList).

Here, count_seen/1 should create a list of each item and how many times it’s been seen. We then pass that data to apply_specials/2, which returns a tuple with two elements: the number of items not processed as part of a special on the left, and the summed-up prices of all specials on the right. Finally, we take that sum, and add it to the cost of the rest of the items, as defined by apply_regular/2.

This method is almost the opposite of how we approach the test. Rather than generating both lists and mashing them together, this splits them up to get the final count.

Helper functions

Here we have the count_seen/2, apply_specials/2, and the apply_regular/2 functions that will allow us to generate the total price.

Get hands-on with 1400+ tech skills courses.