-
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
HW: Week 1 #4
base: ogz
Are you sure you want to change the base?
HW: Week 1 #4
Changes from all 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 |
---|---|---|
@@ -0,0 +1 @@ | ||
:set -isrc/Cis194/Hw/Week1.hs -itest/Cis194/Hw | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,19 +5,26 @@ module Cis194.Hw.Week1 where | |
------------- | ||
|
||
toDigits :: Integer -> [Integer] | ||
toDigits x = [x] | ||
toDigits = reverse . toDigitsRev | ||
|
||
toDigitsRev :: Integer -> [Integer] | ||
toDigitsRev x = [x] | ||
toDigitsRev x | ||
| x > 0 = (mod x 10) : (toDigitsRev $ div x 10) | ||
| otherwise = [] | ||
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 wonder if having the thing that happens the most on top of the where clauses have a performance gain? I would think so since the compiler doesn't know which will happen more often. I like that. 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. Technically, yes, I believe there is a slight performance gain when placing the most frequently matched patterns as near to the top as possible. I just wanted to put the "default" case last. Even if the compiler was unable to optimize for your use cases, if the function was being called frequently (enough to warrant optimization) then you would hopefully benefit from processor branch prediction. I found these relevant posts |
||
|
||
doubleEveryOther :: [Integer] -> [Integer] | ||
doubleEveryOther xs = xs | ||
doubleEveryOther xs = reverse $ doubleEveryOther' $ reverse xs | ||
doubleEveryOther' [] = [] | ||
doubleEveryOther' (x:xs) = x : doubleEveryOther'' xs | ||
doubleEveryOther'' [] = [] | ||
doubleEveryOther'' (x:xs) = x * 2 : doubleEveryOther' xs | ||
|
||
sumDigits :: [Integer] -> Integer | ||
sumDigits _ = 0 | ||
sumDigits = sum . (map $ sum . toDigits) | ||
|
||
validate :: Integer -> Bool | ||
validate _ = False | ||
-- validate x = mod (sumDigits (doubleEveryOther $ toDigits x)) 10 == 0 | ||
validate x = mod ((sumDigits . doubleEveryOther . toDigits) x) 10 == 0 | ||
|
||
--------------------- | ||
-- Towers of Hanoi -- | ||
|
@@ -27,7 +34,16 @@ type Peg = String | |
type Move = (Peg, Peg) | ||
|
||
hanoi :: Integer -> Peg -> Peg -> Peg -> [Move] | ||
hanoi _ _ _ _ = [] | ||
hanoi 1 a b _ = [(a, b)] | ||
hanoi 0 _ _ _ = [] | ||
hanoi n a b c = (hanoi (n - 1) a c b) ++ (hanoi 1 a b c) ++ (hanoi (n - 1) c b a) | ||
|
||
hanoi4 :: Integer -> Peg -> Peg -> Peg -> Peg -> [Move] | ||
hanoi4 _ _ _ _ _ = [] | ||
hanoi4 2 a b c _ = [(a, c), (a, b), (c, b)] | ||
hanoi4 1 a b _ _ = [(a, b)] | ||
hanoi4 0 _ _ _ _ = [] | ||
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. All of the 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. Your comment made me realize that the case 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. Nice, I didn't think about that. |
||
hanoi4 n a b c d = | ||
(hanoi4 (n - m) a c b d) ++ | ||
(hanoi m a b d) ++ | ||
(hanoi4 (n - m) c b a d) | ||
where m = floor (sqrt (fromIntegral (n * 2))) | ||
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. You found a minimal solution! That is awesome. I looked at it for quite a while and gave up. I also love that you used hanoi in this solution. 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. @adkron I found out that it's not actually an optimal solution (technically no solution has been proven to be optimal, but many believe that this is optimal). I didn't properly form a recurrence relation when analyzing the algorithm...mostly because it was a complex case and my math skills are weak. However, I got close enough to satisfy the specs, which made me happy. |
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.
I didn't know you could do this. That is awesome!
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.
Ah, this is another thing I tried using before I was able to run the spec file. IIRC the .ghci file has no impact when executing
stack runghc
.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.
That is too bad. I wonder if stack has something like that. Like can I set a default command? I'll do some digging when I get a moment.