-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't Merge - HW 1 #2
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,19 +5,25 @@ module Cis194.Hw.Week1 where | |
------------- | ||
|
||
toDigits :: Integer -> [Integer] | ||
toDigits x = [x] | ||
toDigits = reverse . toDigitsRev | ||
|
||
toDigitsRev :: Integer -> [Integer] | ||
toDigitsRev x = [x] | ||
toDigitsRev x | x <= 0 = [] | ||
toDigitsRev x = mod x 10 : toDigitsRev (div x 10) | ||
|
||
doubleEveryOther :: [Integer] -> [Integer] | ||
doubleEveryOther xs = xs | ||
doubleEveryOther = flipMap (zipWith (*) (cycle [1, 2])) | ||
|
||
flipMap :: ([a] -> [b]) -> [a] -> [b] | ||
flipMap f = reverse . f . reverse | ||
|
||
sumDigits :: [Integer] -> Integer | ||
sumDigits _ = 0 | ||
sumDigits = sum . concatMap toDigits | ||
|
||
validate :: Integer -> Bool | ||
validate _ = False | ||
validate card = rem (total card) 10 == 0 | ||
where | ||
total = sumDigits . doubleEveryOther . toDigits | ||
|
||
--------------------- | ||
-- Towers of Hanoi -- | ||
|
@@ -27,7 +33,20 @@ type Peg = String | |
type Move = (Peg, Peg) | ||
|
||
hanoi :: Integer -> Peg -> Peg -> Peg -> [Move] | ||
hanoi _ _ _ _ = [] | ||
hanoi 0 _ _ _ = [] | ||
hanoi 1 s t _ = [(s, t)] | ||
hanoi n s t a = next n s a t ++ | ||
hanoi 1 s t a ++ | ||
next n a t s | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm still having to adjust to the order of operations in Haskell, since it wasn't immediately clear how this was working. The fact that all multi-argument functions are actually implemented as a series of one-argument functions is just ingenious...even if it does throw me for a loop sometimes. Anyway, nice use of it here! |
||
where | ||
next = hanoi . (subtract 1) | ||
|
||
hanoi4 :: Integer -> Peg -> Peg -> Peg -> Peg -> [Move] | ||
hanoi4 _ _ _ _ _ = [] | ||
hanoi4 0 _ _ _ _ = [] | ||
hanoi4 1 s e _ _ = [(s, e)] | ||
hanoi4 2 s e i _ = [(s, i), (s, e), (i, e)] | ||
hanoi4 n s e i a = next n s a e i ++ | ||
hanoi4 2 s e i a ++ | ||
next n a e i s | ||
where | ||
next = hanoi4 . (subtract 2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
defmodule CC do | ||
@spec to_digits(integer) :: [integer] | ||
def to_digits(num) do | ||
num | ||
|> to_digits_rev() | ||
|> Enum.reverse() | ||
end | ||
|
||
@spec to_digits_rev(integer) :: [integer] | ||
def to_digits_rev(num) when num <= 0 and is_integer(num) do | ||
[] | ||
end | ||
|
||
def to_digits_rev(num) when is_integer(num) do | ||
[Integer.mod(num, 10) | num |> div(10) |> to_digits_rev()] | ||
end | ||
|
||
@spec double_every_other([integer]) :: [integer] | ||
def double_every_other(digits) do | ||
double = &(&1 * 2) | ||
digits | ||
|> mapl(&(Enum.map_every(&1, 2, double))) | ||
end | ||
|
||
@spec mapl([term], ([term] -> [term])) :: [term] | ||
def mapl(items, fun) do | ||
items | ||
|> Enum.reverse() | ||
|> fun.() | ||
|> Enum.reverse() | ||
end | ||
|
||
def validate(card) do | ||
0 == | ||
card | ||
|> total() | ||
|> rem(10) | ||
end | ||
|
||
def total(card) do | ||
card | ||
|> to_digits() | ||
|> double_every_other() | ||
|> Enum.reduce(0, &sum_digits/2) | ||
end | ||
|
||
def sum_digits(integer, sum) do | ||
integer | ||
|> to_digits() | ||
|> Enum.sum() | ||
|> Kernel.+(sum) | ||
end | ||
end | ||
|
||
IO.inspect(CC.validate(4_012_888_888_881_882)) | ||
IO.inspect(CC.validate(4_012_888_888_881_881)) | ||
|
||
IO.inspect(CC.to_digits(1234)) | ||
|
||
IO.inspect(CC.double_every_other([8, 7, 6, 5])) | ||
IO.inspect(CC.double_every_other([1, 2, 3])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for a concise and elegant solution. And for knowing which tools you have in the toolbox (zipWith, cycle).