Skip to content
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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
33 changes: 26 additions & 7 deletions src/Cis194/Hw/Week1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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]))
Copy link
Collaborator

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).


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 --
Expand All @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The 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)
61 changes: 61 additions & 0 deletions src/Cis194/Hw/week1.exs
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]))
File renamed without changes.
49 changes: 27 additions & 22 deletions test/Cis194/Hw/Week1Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Cis194.Hw.Week1Spec (main, spec) where
import Test.Hspec
import Test.QuickCheck
import Cis194.Hw.Week1
{-import Cis194.Hw.AcceptHanoi-}
import Cis194.Hw.AcceptHanoi

main :: IO ()
main = hspec spec
Expand Down Expand Up @@ -65,32 +65,37 @@ spec = do
it "should solve for 1 disc" $ do
hanoi 1 "a" "b" "c" `shouldBe` [("a", "b")]

{-it "should solve for 2 discs" $ do-}
{-(acceptHanoi3 hanoi 2) `shouldBe` Just (HanoiState3 [] [1..2] [])-}
it "should solve for 2 discs" $ do
(acceptHanoi3 hanoi 2) `shouldBe` Just (HanoiState3 [] [1..2] [])

{-it "should solve for 5 discs" $ do-}
{-(acceptHanoi3 hanoi 5) `shouldBe` Just (HanoiState3 [] [1..5] [])-}
it "should solve for 5 discs" $ do
(acceptHanoi3 hanoi 5) `shouldBe` Just (HanoiState3 [] [1..5] [])

{-it "should solve for 10 discs" $ do-}
{-(acceptHanoi3 hanoi 10) `shouldBe` Just (HanoiState3 [] [1..10] [])-}
it "should solve for 10 discs" $ do
(acceptHanoi3 hanoi 10) `shouldBe` Just (HanoiState3 [] [1..10] [])

{- This is an optional assigment
describe "hanoi4" $ do
it "should return an empty list for zero discs" $ do
hanoi4 0 "a" "b" "c" "d" `shouldBe` []
-- This is an optional assigment
describe "hanoi4" $ do
it "should return an empty list for zero discs" $ do
hanoi4 0 "a" "b" "c" "d" `shouldBe` []

it "should solve for 1 disc" $ do
hanoi4 1 "a" "b" "c" "d" `shouldBe` [("a", "b")]
it "should solve for 1 disc" $ do
hanoi4 1 "a" "b" "c" "d" `shouldBe` [("a", "b")]

it "should solve for 2 discs" $ do
(acceptHanoi4 hanoi4 2) `shouldBe` Just (HanoiState4 [] [1..2] [] [])
it "should solve for 2 discs" $ do
(acceptHanoi4 hanoi4 2) `shouldBe` Just (HanoiState4 [] [1..2] [] [])

it "should solve for 5 discs" $ do
(acceptHanoi4 hanoi4 5) `shouldBe` Just (HanoiState4 [] [1..5] [] [])
it "should solve for 3 discs" $ do
(acceptHanoi4 hanoi4 3) `shouldBe` Just (HanoiState4 [] [1..3] [] [])

it "should solve for 10 discs" $ do
(acceptHanoi4 hanoi4 10) `shouldBe` Just (HanoiState4 [] [1..10] [] [])
it "should solve for 4 discs" $ do
(acceptHanoi4 hanoi4 4) `shouldBe` Just (HanoiState4 [] [1..4] [] [])

it "should solve for 5 discs" $ do
(acceptHanoi4 hanoi4 5) `shouldBe` Just (HanoiState4 [] [1..5] [] [])

it "should solve for 10 discs" $ do
(acceptHanoi4 hanoi4 10) `shouldBe` Just (HanoiState4 [] [1..10] [] [])

it "should find an optimal solution for 15 disks" $ do
length (hanoi4 15 "a" "b" "c" "d") `shouldBe` 129
-}
it "should find an optimal solution for 15 disks" $ do
length (hanoi4 15 "a" "b" "c" "d") `shouldBe` 129