From 434e26356b9005dd5ca6feced5a3e10b55105fb7 Mon Sep 17 00:00:00 2001 From: Amos L King Date: Tue, 13 Nov 2018 13:45:40 -0600 Subject: [PATCH 1/3] HW 1 part 1 This is the first homework that I've done. The hardest part was going through docs and trying to find out what functions are available to me. I did know of the existence of the compose operator, but I didn't know what it was. After I found it in the docs I was able to make a the code more succinct. I think this is what they talk about with functional programming. I made the program about functions. I also implemented the hw in Elixir. I don't know how I feel about it there, but I did like that I had map_every. Amos King @adkron --- src/Cis194/Hw/{SExpr.hs => SExpr.hs.back} | 0 src/Cis194/Hw/Week1.hs | 16 +++-- src/Cis194/Hw/week1.exs | 61 +++++++++++++++++++ .../Hw/{SExprSpec.hs => SExprSpec.hs.back} | 0 4 files changed, 72 insertions(+), 5 deletions(-) rename src/Cis194/Hw/{SExpr.hs => SExpr.hs.back} (100%) create mode 100644 src/Cis194/Hw/week1.exs rename test/Cis194/Hw/{SExprSpec.hs => SExprSpec.hs.back} (100%) diff --git a/src/Cis194/Hw/SExpr.hs b/src/Cis194/Hw/SExpr.hs.back similarity index 100% rename from src/Cis194/Hw/SExpr.hs rename to src/Cis194/Hw/SExpr.hs.back diff --git a/src/Cis194/Hw/Week1.hs b/src/Cis194/Hw/Week1.hs index f39a811..1e11fec 100644 --- a/src/Cis194/Hw/Week1.hs +++ b/src/Cis194/Hw/Week1.hs @@ -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 -- diff --git a/src/Cis194/Hw/week1.exs b/src/Cis194/Hw/week1.exs new file mode 100644 index 0000000..80c7ff8 --- /dev/null +++ b/src/Cis194/Hw/week1.exs @@ -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])) diff --git a/test/Cis194/Hw/SExprSpec.hs b/test/Cis194/Hw/SExprSpec.hs.back similarity index 100% rename from test/Cis194/Hw/SExprSpec.hs rename to test/Cis194/Hw/SExprSpec.hs.back From 80ace105470a405c56f2953dc535522db0c0809d Mon Sep 17 00:00:00 2001 From: Amos L King Date: Mon, 19 Nov 2018 14:05:50 -0600 Subject: [PATCH 2/3] Completes towers of hanoi 3 and 4 Hanoi 3 is optimal, but hanoi 4 is not. I was wondering if there is a way to use hanoi 3 in hanoi 1. I spent quite a bit of time trying to figure that out. Amos King @adkron --- src/Cis194/Hw/Week1.hs | 17 +++++++++++-- test/Cis194/Hw/Week1Spec.hs | 49 ++++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/Cis194/Hw/Week1.hs b/src/Cis194/Hw/Week1.hs index 1e11fec..c5f36cc 100644 --- a/src/Cis194/Hw/Week1.hs +++ b/src/Cis194/Hw/Week1.hs @@ -33,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 + 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) diff --git a/test/Cis194/Hw/Week1Spec.hs b/test/Cis194/Hw/Week1Spec.hs index 7aa5488..38d59d7 100644 --- a/test/Cis194/Hw/Week1Spec.hs +++ b/test/Cis194/Hw/Week1Spec.hs @@ -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 @@ -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 From 7d42174b8246c50116c5ecc76ae6dc87df3fd5d3 Mon Sep 17 00:00:00 2001 From: Amos L King Date: Mon, 19 Nov 2018 22:06:15 -0600 Subject: [PATCH 3/3] Use hanoi to implement hanoi4 I wanted to make sure I was reusing as much code as I could. Amos King @adkron --- src/Cis194/Hw/Week1.hs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Cis194/Hw/Week1.hs b/src/Cis194/Hw/Week1.hs index c5f36cc..9f52cf5 100644 --- a/src/Cis194/Hw/Week1.hs +++ b/src/Cis194/Hw/Week1.hs @@ -34,19 +34,17 @@ type Move = (Peg, Peg) hanoi :: Integer -> Peg -> Peg -> Peg -> [Move] hanoi 0 _ _ _ = [] -hanoi 1 s t _ = [(s, t)] hanoi n s t a = next n s a t ++ - hanoi 1 s t a ++ + [(s, t)] ++ next n a t s where - next = hanoi . (subtract 1) + next = hanoi . subtract 1 hanoi4 :: Integer -> Peg -> Peg -> Peg -> Peg -> [Move] -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 n s e i a + | n <= 2 = hanoi n s e i + | otherwise = next n s a e i ++ hanoi4 2 s e i a ++ next n a e i s where - next = hanoi4 . (subtract 2) + next = hanoi4 . subtract 2