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

[CH4] A more concise implementation of fibTailRec. #452

Open
sandeep-datta opened this issue Aug 22, 2023 · 1 comment
Open

[CH4] A more concise implementation of fibTailRec. #452

sandeep-datta opened this issue Aug 22, 2023 · 1 comment

Comments

@sandeep-datta
Copy link

sandeep-datta commented Aug 22, 2023

Hi,

What do you think of the following implementation of fibTailRec from CH4?

fibTailRec :: Int -> Int
fibTailRec n = fibtr n 0 1 where
  fibtr :: Int -> Int -> Int -> Int
  fibtr n a b =
    if n == 0 then a
    else fibtr (n-1) b (a+b)
@sandeep-datta sandeep-datta changed the title A more concise implementation of fibTailRec from CH4. [CH4] A more concise implementation of fibTailRec. Aug 22, 2023
@milesfrain
Copy link
Member

I like it!

I think we should still keep the existing verbose and beginner-friendly reference solution, but you're welcome to make a PR to add your more optimized solution too.

Just add it after the reference solution here:

fibTailRec :: Int -> Int
fibTailRec 0 = 0
fibTailRec 1 = 1
fibTailRec n = fib' n 2 0 1
where
fib' :: Int -> Int -> Int -> Int -> Int
fib' limit count n1 n2 =
if limit == count then
n1 + n2
else
fib' limit (count + 1) n2 (n1 + n2)

Could call it fibTailRec2. Might be good to also include a comment describing that this is another way to do it by "counting down".

And be sure to test it:

suite "Exercise - fibTailRec" do
test "Verify 0" do
Assert.equal 0
$ fibTailRec 0
test "Verify 9" do
Assert.equal 34
$ fibTailRec 9
test "Verify 44" do
Assert.equal 701408733
$ fibTailRec 44

You could make a helper within that suite which calls both versions, and then replace the calls to each test case with a call to the helper.

Similar to what's done for primeFactors, although that helper is just testing one solution.

suite "Exercise - primeFactors" do
let
primeFactorsTest :: Int -> Array Int -> _
primeFactorsTest n xs =
test (show n) do
Assert.equal (sort xs)
$ sort
$ primeFactors n
primeFactorsTest 1 []

Note that you'll also need to make sure that the test for your optimized reference solution is deleted when users call prepareExercises.sh, since we don't expect both versions to be available when users run their tests. You can add a -- This line should have been automatically deleted comment after the call to your function in the helper.

# Delete lines with a note to delete them
perl -ni -e 'print if !/This line should have been automatically deleted/' $f

Might be good to increase coverage too for inputs 1, 2, and 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants