patternMinor
A different code?
Viewed 0 times
codedifferentstackoverflow
Problem
I have a
And I need something like:
or
Where the
I solve it this way:
For
Finally, one question: any suggestion to solve this problem with a different approach/code?
Thanks.
edit: type signatures added.
xxs list:xxs:: [(([Char], [Char]),([Char], [Char]),[(Double, [Char], [Char])])]
xxs = [(("a11","b11"),("a12","b12"), [(0,"a1","b1"),(1.2,"a2","b2"),(2.3,"a3","b3"),(4.2,"a4","b4")]), (("c11","d11"),("a12","b12"),[(1,"a5","b5"),(1.4,"a6","b6"),(1.9,"a7","b7"),(4.4,"a8","b8")])]And I need something like:
foo 1 -- 1 is the index
output: [(0.0,0.0,"a1","b1"),(1.2,1.2,"a2","b2"),(2.3,3.5,"a3","b3"),(4.2,7.7,"a4","b4")]or
foo 2 -- 2 is the index
output: [(1.0,1.0,"a5","b5"),(1.4,2.4,"a6","b6"),(1.9,4.3,"a6","b6"),(4.4,8.7,"a6","b6")]Where the
second element of each tuple is the summation of all the Doubles from the xxs inner list.I solve it this way:
auxA :: Int -> [(Double, [Char], [Char])]
auxA indexP = aux1 xxs!!(indexP-1)
where aux1 [] = []
aux1 ((_,_,c):xs) = c:aux1 xs
auxB :: Int -> [Double]
auxB indexP = aux2 (auxA indexP)
where aux2 [] = []
aux2 ((x,_,_):xs) = x:aux2 xs
integer1 :: Int -> [Double]
integer1 indexP = [ i | (i,_,_) [Double]
intSummation indexP = scanl (+) (head (auxB indexP)) (drop 1 (auxB indexP))
string1 :: Int -> [[Char]]
string1 indexP = [ st1 | (_,st1,_) [[Char]]
string2 indexP = [ st2 | (_,_,st2) [(Double, Double, [Char], [Char])]
foo indexP = zip4 (integer1 indexP) (intSummation indexP) (string1 indexP) (string2 indexP)
--or
fob :: Int -> [(Double, Double, [Char], [Char])]
fob indexP = [(i,intSum,st1,st2) | (((i,intSum),st1),st2) <- zip (zip(zip (integer1 indexP) (intSummation indexP)) (string1 indexP)) (string2 indexP)]For
fob, I've found a similar code here: https://stackoverflow.com/questions/2468226/how-to-zip-multiple-lists-in-haskellFinally, one question: any suggestion to solve this problem with a different approach/code?
Thanks.
edit: type signatures added.
Solution
Wow! What an ugly data structure. I suggest making small transformations until you arrive at the form you desire; this is in contrast to your current solution that extracts the exact element you desire (performing all needed computations) without building a new representation.
1) Eliminate unused fields
This gets rid of the first two elements of the tuple, which your transformation didn't seem to use.
The first line simply drops your first two tuples, so instead of:
Which didn't seem needed for your computations (you didn't really explain what you want in words, so it's possible I missed the point by skipping your code). Now you have:
2) Compute the running sum
The "scan" just transforms a list using a binomial and a starting element. In this case, you see the
The final code looks like:
With correct results (afaict):
If #2 is too much in one step
Comparing to your code (learning to use standard functions)
Mostly, you seem to be of a mind to looking data on demand when it's easier and cleaner to build a list of all results and pull out the desired values. Some specific observations:
P.S. Good work coming in with a complete solution!
1) Eliminate unused fields
map (\(_,_,lst) -> lst) -- This is like 'auxA' with the lookupThis gets rid of the first two elements of the tuple, which your transformation didn't seem to use.
The first line simply drops your first two tuples, so instead of:
xxs:: [(([Char], [Char]),([Char], [Char]),[(Double, [Char], [Char])])]Which didn't seem needed for your computations (you didn't really explain what you want in words, so it's possible I missed the point by skipping your code). Now you have:
xxs:: [[(Double, [Char], [Char])]]2) Compute the running sum
-- This is similar to your interger1, intSummation, string1, and string2 all rolled in one
drop 1 . scanl (\(_,s,_,_) (n,x,y) -> (n,n+s,x,y)) (0,0,"","")The "scan" just transforms a list using a binomial and a starting element. In this case, you see the
n+s is the second element while the original value, n, is the first element of the output tuples. I call drop 1 to get rid of my initial 4-tuple that starts the scan.The final code looks like:
import Data.List
tmd i =
let xxs' = map (\(_,_,lst) -> lst) xxs -- This is like 'auxA' with the lookup
xxsFinal = map (drop 1 . scanl (\(_,s,_,_) (n,x,y) -> (n,n+s,x,y)) (undefined,0,undefined,undefined)) $ xxs'
in lookup i (zip [1..] xxsFinal)With correct results (afaict):
> Just (foo 2) == tmd 2
True
> Just (foo 1) == tmd 1
TrueIf #2 is too much in one step
- Extract the values:
let vals = map (\(n,_,_) -> n) input
- Compute the sums:
let sums = drop 1 . scanl (+) 0 $ vals
- Combine the info:
zipWith3 (\v s (_,a,b) -> (v,s,a,b)) vals sums input
Comparing to your code (learning to use standard functions)
Mostly, you seem to be of a mind to looking data on demand when it's easier and cleaner to build a list of all results and pull out the desired values. Some specific observations:
- Your
aux1andaux2functions are just maps, for exampleaux1 = map (\(_,_,c) -> c).
!!is a partial function. I suggest you uselookup index . zip [1..].
- Most of your list comprehensions are easier to read as a
mapfunction and simple lambda. They really don't deserve to be separate functions.
- Way to go, using
scanlas a beginner - nice work. However, instead of using 'head' and 'drop' perhaps you could just use your own zero element (like I did with0and""- or I could have usedundefined) or usescanl1 (+) . auxB.
P.S. Good work coming in with a complete solution!
Code Snippets
map (\(_,_,lst) -> lst) -- This is like 'auxA' with the lookupxxs:: [(([Char], [Char]),([Char], [Char]),[(Double, [Char], [Char])])]xxs:: [[(Double, [Char], [Char])]]-- This is similar to your interger1, intSummation, string1, and string2 all rolled in one
drop 1 . scanl (\(_,s,_,_) (n,x,y) -> (n,n+s,x,y)) (0,0,"","")import Data.List
tmd i =
let xxs' = map (\(_,_,lst) -> lst) xxs -- This is like 'auxA' with the lookup
xxsFinal = map (drop 1 . scanl (\(_,s,_,_) (n,x,y) -> (n,n+s,x,y)) (undefined,0,undefined,undefined)) $ xxs'
in lookup i (zip [1..] xxsFinal)Context
StackExchange Code Review Q#7011, answer score: 7
Revisions (0)
No revisions yet.