Hello,
parallel to Exercism i use Hackerrank to practice at work.
At this i am really struggeling with the 2D Array data structures challange. The following code should solve the problem, but unfortunately does not compile.
hourglassSum arr = do
sumAndMax unpack2DArray arr
unpack2DArray [] = []
unpack2DArray (head : tail) =
append1DArray (head (unpack2DArray tail))
append1DArray (head : []) tail2 =
head : tail2
append1DArray (head : tail) tail2 =
append1DArray tail tail2
sumAndMax arr
case arr of
(a:b:c:_:_:_:_:d:_:_:_:_:e:f:g:[]) -> a+b+c+d+e+f+g
(a:b:c:_:_:_:_:d:_:_:_:_:e:f:g:_) ->
let prev = sumAndMax (Data.List.tail (arr))
let cur = a+b+c+d+e+f+g
if cur > prev then
cur
else
prev
If i were to use pattern matching in the function signature of “sumAndMax”, i do not know how to take the whole list and pass it on for recursion. Therefore, i want to extract the data later, sum it and then call the recursion. How can i achieve this?
The posted code has some syntax issues:
-sumAndMax arr
+sumAndMax arr =
- let prev = sumAndMax (Data.List.tail (arr))
+ let prev = sumAndMax (Data.List.tail (arr)) in
- let cur = a+b+c+d+e+f+g
+ let cur = a+b+c+d+e+f+g in
There are also some type errors, some with obvious fixes and some with less obvious ones. I recommend always giving type signatures for global definitions and non-trivial local definitions, because they greatly help finding logic errors.
The HackerRank problem is about a 2D structure. I do not know off the top of my head how to solve it with a flat list (if that is even – reasonably – possible). A complicating factor is that the array is not guaranteed to be a certain size. You probably want to use a [[Int]]
or an Array (Int, Int) Int
instead. Indexing can be done with !!
(list, partial), !?
(list, total), and !
(array, partial).
The first solution that comes to my mind goes
(code provided in an attempt to communicate approach to problems generally)
maxHourglassSum array = maximum hourglassSums
where
hourglassSums :: [Int]
hourglassSums = map sum hourglasses
hourglasses :: [[Int]]
hourglasses = map hourglassAt coordinates
coordinates = _ -- where are all the hourglasses?
hourglassAt coordinate = _ -- an indexing feast
I’m not seeing what to recurse on here, sorry. Are there ways of combining subsolutions into larger solutions?
In the problem specification of the 2d Array it is guaranteed that the input is 6 by 6.
The input is a list of lists. Because the recursive natrue of lists in Haskell is new to me, i try to use it as much as possible. With indexing, i could probably solve the problem within a blink of an eye.
The recursion should lie in the sumAndMax function. If the input array is large enough, call the same function with the tail of the array, until the array has reached a certain length. Basically, by omitting the head in the next recursion, i shift the indices by one to the right. If the sum is greater then the previous one, use this sum, else use the previous.
What does the in Keyword do? The Haskell Wiki article about keywords does not really help: Keywords - HaskellWiki. I also did not encurter it in any Haskell book so far.
Ah, I missed that.
Assuming that the array be represented as a [[Int]]
, this might look like
sumAndMax (firstRow : secondRow : thirdRow : rest) =
maxHourglassSumInRows firstRow secondRow thirdRow
`max`
sumAndMax (secondRow : thirdRow : rest) -- recursion
sumAndMax _ = minBound -- base cases
Does that help?
I still haven’t been able to come up with a flat list approach.
Just like then
and else
, in
never comes alone: it is part of the let … in _
expression.
let
expressions are similar in purpose to where
clauses. The differences are
let
’s and where
’s purposes are the same: allowing local definitions.
Inside do
blocks let
does occur alone, but that is syntactic sugar for let … in _
:
_ = do
actions
let value = computation
moreActions value
-- which means
_ = actions >> let value = computation in moreActions value
The let _ = _
that is sometimes seen in GHCi contexts (example in LYAH) is actually the one from do
notation. GHCi is special like that. A REPL in an language without true variables is a bit weird.