Erlang, Day 2: Thoughts
I'm finding it very easy to dive into Erlang. After going through the Prolog and Scala chapters of this book, as well as making heavy use of Scala at work, the functional constructs used in Erlang feel natural. I've grown very fond of pattern matching in the last few months and have found it to be a very powerful tool for expressing complex concepts in a very concise and readable manner. Erlang's heavy reliance on pattern matching makes me happy.
However, the syntax does feel slightly clunky: I constantly forget to end lines with dots and separating clauses of control structures with semi-colons gets annoying. I suspect this is something you get used to. Moreover, the end result, at least in the dead-simple code snippets I've looked at so far, is pleasantly readable.
Erlang, Day 2: Problems
List lookup
Consider a list of keyword-value tuples, such as [{erlang, "a functional language"}, {ruby, "an OO language"}]. Write a function that accepts the list and a keyword and returns the associated value for the keyword.
My implementation:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(list_lookup). | |
-export([lookup/2]). | |
lookup(List, Keyword) -> do_lookup(List, Keyword). | |
do_lookup([{Keyword, Value}|_], Keyword) -> Value; | |
do_lookup([_|Tail], Keyword) -> do_lookup(Tail, Keyword). |
Shopping list price
Consider a shopping list that looks like [{item, quantity, price}, ...]. Write a list comprehension that builds a list of items of the form [{item, total_price}, ...] where total_price is quantity times the price.
My implementation:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(shopping_list_price). | |
-export([total_price/1]). | |
total_price(ShoppingList) -> [{Item, Quantity * Price} || {Item, Quantity, Price} <- ShoppingList]. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35> shopping_list_price:total_price([{"Cheese", 7.99, 100}, {"Bread", 1.99, 500}]). | |
[{"Cheese",799.0},{"Bread",995.0}] |
Tic-tac-toe
Write a program that reads a tic-tac-toe board presented as a list or a tuple of size nine. Return the winner (x or o) if a winner has been determined, cat if there are no more possible moves, or no_winner if no player has won yet.
My implementation:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(tic_tac_toe). | |
-export([game_state/1]). | |
game_state(GameState) -> | |
case GameState of | |
[X, X, X, | |
_, _, _, | |
_, _, _] -> X; | |
[_, _, _, | |
X, X, X, | |
_, _, _] -> X; | |
[_, _, _, | |
_, _, _, | |
X, X, X] -> X; | |
[X, _, _, | |
X, _, _, | |
X, _, _] -> X; | |
[_, X, _, | |
_, X, _, | |
_, X, _] -> X; | |
[_, _, X, | |
_, _, X, | |
_, _, X] -> X; | |
[X, _, _, | |
_, X, _, | |
_, _, X] -> X; | |
[_, _, X, | |
_, X, _, | |
X, _, _] -> X; | |
_ -> | |
case lists:any(fun(X) -> X == "_" end, GameState) of | |
true -> cat; | |
_ -> no_winner | |
end | |
end. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27> tic_tac_toe:game_state( | |
["X", "X", "O", | |
"X", "O", "O", | |
"X", "O", "X"]). | |
"X" | |
29> tic_tac_toe:game_state( | |
["X", "X", "O", | |
"X", "O", "O", | |
"O", "X", "O"]). | |
"O" | |
31> tic_tac_toe:game_state( | |
["X", "O", "X", | |
"X", "O", "O", | |
"O", "X", "X"]). | |
no_winner | |
32> tic_tac_toe:game_state( | |
["X", "O", "X", | |
"X", "O", "O", | |
"O", "X", "_"]). | |
cat |