HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Extract logic applied in a sequence of integers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
logicappliedsequenceextractintegers

Problem

I've done it in C# before but thought that a functional language would be a good fit for this kind of thing.

From this ascending list of integers:


[100,103,106,112,118,121]

I had to calculate the difference between two consecutive numbers and group them while the result doesn't change. The final output must be a string like this:


"(group.length x difference)+(next group.length + next diff)+.."

Note that a same difference can appear multiple times in the sequence if it's not consecutive.

For this sample: "2x3+2x6+1x3"

import Data.List

countDelta :: [[a]] -> [(Int,a)]
countDelta [] = []
countDelta [[]] = []
countDelta ( (y:zs) : (bs) ) =  (length zs + 1, y) : countDelta bs

groupByDelta :: [Int] -> [(Int,Int)]
groupByDelta (xs) = countDelta ( group [b-a | (a:b:_)  String
printTuples [] = ""
printTuples [(x,y)] = show x ++ "x" ++ show y
printTuples (x:xs) = printTuples [x] ++ "+" ++ printTuples xs

getSequenceLogic :: [Int] -> String
getSequenceLogic [] = ""
getSequenceLogic [x] = printTuples [(1,0)]
getSequenceLogic (xs) = printTuples (groupByDelta xs)


Sample call:

getSequenceLogic [100,103,106,112,118,121]


I get the expected result but is there any obvious error?

Solution

I managed to simplify a pair of your functions:

countDelta

countDelta = map (\(x:xs) -> (length xs + 1, x))


In fact most of the logic in your countDelta was just reinventing map, so actually using map makes it much easier.

ShowTuples

(You named it printTuples but it does not print the tuples, printing to the screen is an action, while this function is pure, so I named it showTuples as show is conventionally used in Haskell when a String is the output)

import Data.List

showTuples = intercalate "+" . map (\(x, y) -> (show x ++ "x" ++ show y))


Here you were just putting "x" in between the two elements of each tuple and "+" in between the tuples. Half of the code was reinventing map, the other half intercalate using these built-ins makes the code much shorter and self-explanatory.

getSequenceLogic

A minor simplification only here: you can drop the [] case as the xs case already handles it correctly:

getSequenceLogic [x] = showTuples [(1,0)]
getSequenceLogic xs = showTuples (groupByDelta xs)

Code Snippets

countDelta = map (\(x:xs) -> (length xs + 1, x))
import Data.List

showTuples = intercalate "+" . map (\(x, y) -> (show x ++ "x" ++ show y))
getSequenceLogic [x] = showTuples [(1,0)]
getSequenceLogic xs = showTuples (groupByDelta xs)

Context

StackExchange Code Review Q#68339, answer score: 6

Revisions (0)

No revisions yet.