# A daily programmer – nuts and bolts

I’ve mentioned r/dailyprogrammer in previous posts, since I think they are fun little problems to solve when I have time on my hands. They’re also great problem sets to do when learning a new language.

This time around I decided to do an easy one with haskell.

## Nuts and bolts problem description

The goal is stated as:

You have just been hired at a local home improvement store to help compute the proper costs of inventory. The current prices are out of date and wrong; you have to figure out which items need to be re-labeled with the correct price.

You will be first given a list of item-names and their current price. You will then be given another list of the same item-names but with the correct price. You must then print a list of items that have changed, and by how much.

The formal inputs and outputs:

Input Description
The first line of input will be an integer N, which is for the number of rows in each list. Each list has N-lines of two space-delimited strings: the first string will be the unique item name (without spaces), the second string will be the price (in whole-integer cents). The second list, following the same format, will have the same unique item-names, but with the correct price. Note that the lists may not be in the same order!
Output Description

For each item that has had its price changed, print a row with the item name and the price difference (in cents). Print the sign of the change (e.g. ‘+’ for a growth in price, or ‘-‘ for a loss in price). Order does not matter for output.

And the sample input/output:

Sample Input 1
4
CarriageBolt 45
Eyebolt 50
Washer 120
Rivet 10
CarriageBolt 45
Eyebolt 45
Washer 140
Rivet 10

Sample Output 1
Eyebolt -5
Washer +20

And here is my haskell solution

module Temp where

import Data.List

data Item = Item { name :: String, price :: Integer }

strToLine :: String -> Item
strToLine str = Item name (read price)
where
name:price:_ = words str

formatPair :: (Item, Item) -> [Char]
formatPair (busted, actual) = format
where
diff = price actual – price busted
direction = if diff > 0 then "+" else "-"
format = name busted ++ " " ++ direction ++ show (abs diff)

getPairs :: IO [(Item, Item)]
getPairs = do
let readGroup = fmap (sort . map strToLine) (replicateM n getLine)
I had a lot of fun with this one, since it really forced me to understand and utilize `fmap` given that you had to deal with being in the `IO` monad. I also liked being “forced” to separate the IO from the pure. I say forced in quotes because it’s really not that helpful to do all your work in the IO function; it’s not reusable.