[Haskell-cafe] recursion problem part 2

Jeffrey Brown jeffbrown.the at gmail.com
Sat Feb 7 01:48:06 UTC 2015


 I see: what matters is that ++ has to traverse to the end of the first
list. The order in which its two arguments are evaluated is irrelevant.

Thank you, David and Arjun!

On Fri, Feb 6, 2015 at 5:38 PM, Arjun Comar <nrujac at gmail.com> wrote:

> Jeff,
> An expression of the form xs ++ [x] appends the element to the end of the
> list. In order to evaluate the result, the ++ function iterates through the
> elements of the first list to find the end of the list then sets the tail
> of the last element of the first list to the second list. This means that
> on each recursive call (once per digit), your algorithm must traverse the
> list of digits already produced to attach the newest element. You can avoid
> this problem by instead consing the new digit onto the front of the list,
> and then reverse the list at the end to produce the digits in the correct
> order. Alternatively, you could try and compute the digits in the reverse
> order.
>
> Here's another solution, though it also will only work on positive
> integers and will fail on negative inputs:
>
>     import Data.Char (digitToInt)
>
>     lastDigit :: Int -> [Int]
>     lastDigit x = map digitToInt (show x)
>
> You can fix the issues with this implementation by replacing digitToInt
> with a wrapper that checks if the character being analyzed is in fact a
> digit and then providing something if it is not. What you should provide in
> the failure case is up to the requirements of the problem.
>
> Thanks,
> Arjun
>
> On Fri, Feb 6, 2015 at 8:01 PM, Jeffrey Brown <jeffbrown.the at gmail.com>
> wrote:
>
>> Is it successively appending? My intention was to prepend. If it's
>> appending, Is that because the ++ operator always evaluates its left
>> argument first, then its right one?
>>
>> On Fri, Feb 6, 2015 at 2:42 PM, David Feuer <david.feuer at gmail.com>
>> wrote:
>>
>>>
>>> On Feb 6, 2015 3:41 PM, "Jeffrey Brown" <jeffbrown.the at gmail.com> wrote:
>>> >
>>> > Here's a solution:
>>> > lastDigit x = mod x 10
>>> > remainingDigits x = (x - lastDigit x) `div` 10
>>> > listDigits x
>>> >   | x < 10 = [x]
>>> >   | otherwise = (listDigits $ remainingDigits x) ++ [lastDigit x]
>>> >
>>> > Here's a faster one:
>>> > listDigits2 x
>>> >   | x < 10 = [x]
>>> >   | otherwise = (listDigits $ remainingDigits) ++ [lastDigit]
>>> >   where lastDigit = mod x 10
>>> >         remainingDigits = (x - lastDigit) `div` 10
>>>
>>> These give somewhat peculiar results when the argument is negative. That
>>> can be rectified, of course. Unfortunately, all of these proposed solutions
>>> have a serious performance problem: successively appending single elements
>>> to build a list of length n is O(n^2). There's an easy fix, which I'll let
>>> you come up with.
>>>
>>> David
>>>
>>
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20150206/2cce54d3/attachment-0001.html>


More information about the Haskell-Cafe mailing list