[Haskell-beginners] Code review request?

Akhra Gannon tanuki at gmail.com
Wed Jan 15 20:02:04 UTC 2020


Also worth noting that Ut's version can be expressed as a fold:

canBalanceElem x acc@(y, z, p) = if p then acc else let y'=y+x; z'=z-x in
(y', z', y'==z')
canBalanceFold xs = (\(_, _, p) -> p) $ foldr canBalanceElem (0, sum xs,
False) xs


On Wed, Jan 15, 2020 at 10:54 AM Ut Primum <utprimum at gmail.com> wrote:

> Hi,
> this is how I would have solved the exercise:
>
> canBalanceRec [] _ _ = False
> canBalanceRec (x:xs) s1 s2 = s1+x==s2-x || canBalanceRec xs (s1+x) (s2-x)
> canBalance xs = s==0 || canBalanceRec xs 0 s where s=sum xs
>
> Note that there is one difference: in this case
> canBalance [-2,-2,4] = True
> because I think I can split the list into [ ] and the rest (since the sum
> of the empty list is 0 and the same is the sum of the elements of the
> lists). Anyway this is a matter of how we interpret the text of the
> exercise (your function would return False instead). Note that removing the
> "s==0 ||" makes no difference.
>
>  An advantage of my solution is that it is less expensive, since its
> computational complexity is linear in the length of the list xs. Yours uses
> sum and drop many times, and so is slower. Just to have an idea of the
> difference (using ghci interpreter):
>
> > canBalance [1..10000]
> False
> (*0.02* secs, 6,974,552 bytes)
> > can_split_even [1..10000]
> False
> (*5.60* secs, 11,395,843,384 bytes)
>
> Cheers,
> Ut
>
> Il giorno mer 15 gen 2020 alle ore 18:27 Jake Vossen <jake at vossen.dev> ha
> scritto:
>
>> Hey everyone,
>>
>> Let me know if this is not the right place for this, but I am curious if
>> someone could take a look at my code and maybe share some feedback / how
>> a more experienced haskeller would approach this problem.
>>
>> New to Haskell, pretty experienced with imperative languages. I have
>> solved the following problem in Haskell:
>>
>> > Given a non-empty array, return true if there is a place to split the
>> > array so that the sum of the numbers on one side is equal to the sum
>> > of the numbers on the other side.
>>
>> > canBalance([1, 1, 1, 2, 1]) -> true
>> > canBalance([2, 1, 1, 2, 1]) -> false
>> > canBalance([10, 10]) -> true
>>
>> Here is my code (my solution uses `can_split_even` not `canBalance`)
>>
>> ```
>> can_split_even :: (Num a) => (Eq a) => [a] -> Bool
>> can_split_even xs = True `elem` is_even_at_each_spot
>>   where
>>     is_even_at_each_spot :: [Bool]
>>     is_even_at_each_spot = map (is_split xs) [1 .. (length xs - 1)]
>>       where
>>         is_split :: (Num a) => (Eq a) => [a] -> Int -> Bool
>>         is_split xs index = sum (take index xs) == sum (drop index xs)
>> ```
>>
>> Thanks so much!
>>
>> --
>> Jake Vossen
>> Colorado School of Mines, Class of 2022
>> B.S. Computer Science
>> PGP: 08CD 67DA FE3A 0AE7 B946  6AC3 B812 7052 D9E3 817B
>> https://jake.vossen.dev
>>
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20200115/2bf901f4/attachment.html>


More information about the Beginners mailing list