I'm trying to define a function in Haskell that takes an integer argument c and returns the list of all points on the cartesian plane of the form (x/c,y/c) where x and y are integers.
x/c is between -2 and 1 and y/r is between -1 and 1
This is what I've gotten so far which I'm almost sure is right but I'm getting a parse error on input = when I run it particularly at this line: cart xs ys c = [(y/c,x/c) | x <- xs, y <- ys]
plane :: Int -> [a]
plane c = cart [-1*c .. 1*c] [-2*c .. 1*c] c
cart xs ys c = [(y/c,x/c) | x <- xs, y <- ys]
A sample output would be: plane 1 would generate:
[(-2.0, -1.0), (-1.0, -1.0), ( 0.0, -1.0), ( 1.0, -1.0),
(-2.0, 0.0), (-1.0, 0.0), ( 0.0, 0.0), ( 1.0, 0.0),
(-2.0, 1.0), (-1.0, 1.0), ( 0.0, 1.0), ( 1.0, 1.0)]
Anyone have any idea how I can fix this! Thanks
you are missing the where, other than that it looks like you have some type errors.
[a] is too general
/ only works on fractional types.
so
plane :: Int -> [(Int,Int)]
plane c = cart [-1*c .. 1*c] [-2*c .. 1*c] c where
cart xs ys c = [(y `div` c,x `div` c) | x <- xs, y <- ys]
might be what you want. Smallest change from what you have that more or less works.
This is how I'd do it. fromintegral is a type 'glue' function that converts any value in the Integral type class to any other type in the Num typeclass. The result type has to be in RealFrac (like Double or Rational) to use the / operator.
plane :: (Integral a, RealFrac b) => a -> [(b,b)]
plane d = [(fI y / fI d,fI x / fI d) | x <- [-2*d..d], y <- [-d..d]]
where fI = fromIntegral
Related
I have an input of [ ( (Int,Int) , (Int,Int) ) ] which is the coordinate of the ends of the path. All paths run either horizontally (same y-value for both ends) or vertically (same x-value for both ends).
So I want to write a function that generates all the coordinates of the path from the input.
For example, the input pair of ends is [((0, 0), (0, 3)), ((0, 2), (2, 2))](this is two paths), the output of the function I need is [[(0, 0), (0, 1), (0, 2), (0, 3)], [(0, 2), (1, 2), (2, 2)]]
getPaths :: [ ( (Integer,Integer) , (Integer,Integer) ) ] -> [[(Integer,Integer)]]
getPaths [((xa, ya), (xb, yb))]
| xa == xb : [(xa, yb + 1) | yb < ya]++
| xa == xb : [(xa, ya + 1) | ya < yb]++
| ya == yb : [(xa + 1, ya) | xa < xb]++
| ya == yb : [(xb + 1, ya) | xb < xa]++
I'm not sure if its right, could anyone have a look at it?
I think it is better to first make a function that works with a single pair of coordinates:
path :: ((Int, Int), (Int, Int)) -> [(Int, Int)]
path = …
then getPaths is just a mapping of this:
getPaths :: [((Int, Int), (Int, Int))] -> [[(Int, Int)]]
getPaths = map path
as for the path, you can make use of ranges, indeed [x₁ .. x₂] will produce all (integral) values between x₁ and x₂ (both inclusive).
The function thus can be constructed with list comprehension with:
path :: ((Int, Int), (Int, Int)) -> [(Int, Int)]
path ((x₁, y₁), (x₂, y₂)) = [ … | … <- …, … <- … ]
where you still need to fill in the … parts.
I am having trouble finishing this problem. Any hints to a possible solution will be appreciated.
Given a Double value v and a list of Double values xs, calcList returns a list of Doubles
according to the following rules:
For each value x in xs, if x is not positive, there will be no corresponding value in the output list.
Otherwise, the corresponding output value will be x * ln x.
However, this value will be in the output list if and only if its value is greater than v.
The order of the corresponding output values (if present) should be the same as the input
values.
The followings are some examples:
calcList 1.0 [] = []
calcList 1.0 [3.0] = [3.2958]
calcList 1.0 [-1.0, 1.0, 3.0, 5.0, 7.0, 9.0] = [3.2958, 8.0472, 13.6214, 19.7750]
calcList 100.0 [1.0 .. 40.0] = [102.0359, 106.4536, 110.9035, 115.3847, 119.8963, 124.4372, 129.0067, 133.6040, 138.2283, 142.8789, 147.5552]
This what I have so far:
positive :: Double -> Bool
positive x = x > 0.0
calcValue :: Double -> Double
calcValue x = log x * x
calcList :: Double -> [Double] -> [Double]
calcList v xs = []
calcList v xs
So it looks like there are 3 steps.
Get rid of elements <= 0 (filter)
Multiply each remaining elements by its natural log (map)
Get rid of elements <= v (filter)
Instead of applying these each to an input, we can compose the functions using (.) (sincef.g == \x -> f (g x)).
calcList = \v -> filter (>v) . map (\x -> x*log x) . filter (>0)
You should checkout the docs on filter and map. Also this chapter from Learn You A Haskell would be a good read.
We can use an approach where we use functions like filter, and map. An equivalent solution can be obtained with list comprehension:
calcList :: (Ord d, Floating d) => d -> [d] -> [d]
calcList v xs = [xlogx | x <- xs, x > 0, let xlogx = x * log x, xlogx > v]
We thus here use x <- xs to iterate over the elements in xs, by using x > 0 we filter values such that only values where x > 0 are considered. Next we define a variable xlogx as let xlogx = x * log x, and then we have an extra filter that checks if xlogx > v.
The yield part of the list comprehension (the part before the pipe char |) specifies that we add xlogx to the list.
Another approach could be
calcList :: Double -> [Double] -> [Double]
calcList v [] = []
calcList v (x:xs) = case (positive x) of {
False -> calcList v xs;
True -> case ((calcValue x) > v) of {
False -> calcList v xs;
True -> (calcValue x):(calcList v xs);
};
}
In each of the cases you check for one of the conditions, plus you add the numbers at the beginning of the list so the order will be the same.
Assuming I have the list of tuples:
[('X', 3.0), ('B', 0.0), ('N', 4.33)]
I would like a function that deletes all tuples from the list where the second element is 0 or below. My attempt:
dELS :: [(Char, Float)] -> [(Char, Float)]
dELS x = [c | c <- x, snd x > 0.0]
But that returns...
*** Expression : snd x
*** Term : x
*** Type : [(Char,Float)]
*** Does not match : (a,b)
Thoughts?
When you do c <- x, you're using c as the name of an individual element of the list x, and it's c that you should be running snd x > 0.0 on instead of x. So change that last x to c.
No idea what the problem is. Following exactly the hmatrix buildMatrix doc:
Prelude Data.Packed.Matrix> let k= buildMatrix 3 4 ( (r,c) -> fromIntegral r * fromIntegral c)
<interactive>:1:26:
Pattern syntax in expression context:
(r, c) -> fromIntegral r * fromIntegral c
In the docs, the markup wasn't properly escaped, it must be
let k = buildMatrix 3 4 (\(r,c) -> fromIntegral r * fromIntegral c)
The haddock markup was
{- | creates a Matrix of the specified size using the supplied function to
to map the row\/column position to the value at that row\/column position.
#> buildMatrix 3 4 (\ (r,c) -> fromIntegral r * fromIntegral c)
(3><4)
[ 0.0, 0.0, 0.0, 0.0, 0.0
, 0.0, 1.0, 2.0, 3.0, 4.0
, 0.0, 2.0, 4.0, 6.0, 8.0]#
Hilbert matrix of order N:
#hilb n = buildMatrix n n (\(i,j)->1/(fromIntegral i + fromIntegral j +1))#
-}
The backslashes need to be escaped for them to be displayed.
t = True
f = False
anzNachbarn :: [[Bool]] -> (Integer,Integer) -> Integer
anzNachbarn a (x,y)
| x < 0 || y < 0=-1
| otherwise ... here comes the comparison
This is an example matrix:
[[True,False,False],
[True,False,False],
[False,True,False]]
here i need an algorithm, where it calculates (for given x and y position in matrix) its neighbours (only "true" neighboors) and increase it by 1 for each true neighboor.
For example: anzNachbarn [[True,False,False],[True,False,False],[False,True,False]] (0,1)
returns 2 back.
:Edit
I still have a question how can I now implement each component of the result matrix, the number of named elements with True neighboring fields indicates the corresponding component of the argument matrix Applies to
[[True, False, False],
[True, False, False],
[False, True , False]]
the function func returns the results matrix [[1,2,0], [2,3,1], [2,1,1]]
with signature func :: [[Bool]] -> [[Integer]]
have you got any idea about this ?
You almost certainly want to use an array (from Data.Array) in this situation, since looking up an item in a list by its index is very slow.
Here's a quick implementation using Array:
countNeighbors :: Array (Int, Int) Bool -> (Int, Int) -> Int
countNeighbors board (x, y) = length
[ (x', y')
| x' <- [x - 1, x, x + 1]
, y' <- [y - 1, y, y + 1]
, x' /= x || y' /= y
, inRange (bounds board) (x', y')
, board ! (x', y')
]
This is a list comprehension with two generators and three guards. The generators simply give us the indices of the nine positions in a three-by-three square centered at (x, y) (you'll need a minor change if you don't want neighbors at the corners to be considered).
The first guard (x' /= y') ignores (x, y) itself. The second throws out positions that aren't within the bounds of the array. The final guard throws out positions that are in the array but have a False value.
So we now have a list of indices for the neighbors with True values. The length of this list is the desired count.
This is ugly, but seems to work...
anzNachbarn :: [[Bool]] -> (Int,Int) → Integer
anzNachbarn a (x,y)
| x < 0 || y < 0 = -1
| otherwise = sum [v x' y' | x' <- [max 0 (x-1)..x+1],
y' <- [max 0 (y-1)..y+1],
x ≠ x' || y ≠ y' ]
where v i j = if j >= length a
|| i >= length (a !! 0)
|| not (a !! j !! i)
then 0 else 1
[Edit]
In order to convert the whole array, you can write the equally ugly
conv a = [line y | y <- [0 .. (length a) - 1]]
where line y = [anzNachbarn a (x,y) | x <- [0 .. ((length (a !! 0) - 1)]]
Note that the performance of this is terrible.