Hey folks, I have the following piece of code from C++.
for (int i=0; i < nObstacles; i++)
{
int x,y;
bool bAlreadyExists;
do {
x = rand() % nGridWidth;
y = rand() % nGridHeight;
} while (HasObstacle(x, y));
SetObstacle(x, y, true);
}
I can translate it to F# directly with no problem.
let R = new System.Random()
for i=0 to nObstacles do
let mutable bGoodToGo = false;
let mutable x =0;
let mutable y = 0
while not bGoodToGo do
x <-R.Next(nWidth)
y <-R.Next(nHeight)
bGoodToGo <- IsEmptyAt x y
board.[x,y]<-Obstacle;
Of course this probably makes most of you cringe, since this is not the way F# was meant to be used. This code has some "unkosher" concepts for F#, such as do-while loops and mutable data.
But what I would be interested in seeing is a "proper" F# translation with immutable data, and some sort of do-while equivalent.
As a first step, you can take a look how to simplify the while loop inside the for loop. One option is to use Seq.initInfinite to generate a sequence that will give you any number of random X, Y coordinates. Then you can use Seq.find to find the first one that refers to an empty board field.
I also changed isEmpty to take a tuple (so that you can pass as argument to Seq.find using partial function application) and I changed some names to follow more standard F# style (you generally wouldn't use hungarian naming notation):
let isEmpty (x, y) = board.[x,y] = -1
let rnd = new System.Random()
for i = 0 to obstacleCount do
let x, y =
// Generate infinite sequence of random X Y coordinates
Seq.initInfinite (fun _ -> rnd.Next(width), rnd.Next(height))
// Find first coordinate that refers to empty field
|> Seq.find isEmpty
// We still have mutation here
board.[x,y] <- Obstacle
I think this is quite elegant functional solution. It may be a bit slower than the imperative solution, but the point is that functional style makes it easier to write & change the implementation once you learn it (You can always use imperative style as optimization).
To avoid all mutable state, you'll need to generate locations for obstacles first and then initialize the array. For example, you could recursively add new coordinates to a set until it has the required length. Then you can generate array using Array2D.init:
let rec generateObstacles obstacles =
if Set.count obstacles = obstacleCount then obstacles
else
// Try generating new coordinate and add it to the set
// (if it is already included, this doesn't do anything)
obstacles
|> Set.add (rnd.Next(width), rnd.Next(height))
|> generateObstacles
let obstacles = generateObstacles Set.empty
Array2D.init width height (fun x y ->
if obstacles.Contains(x, y) then Obstacle else Empty)
This isn't really shorter and it will be a bit slower, so I'd stick to the first solution. However, it is a nice exercise showing recursion and sets...
Here is my try:
Seq.initInfinite (fun _ -> rnd.Next(width), rnd.Next(height))
|> Seq.filter (fun (x, y) -> IsEmptyAt x y)
|> Seq.distinct
|> Seq.take nObstacles
|> Seq.iter (fun (x, y) -> board.[x,y] <- Obstacle)
You can remove the Seq.filter if the board is empty at the beginning. Like in Tomas solution, it generates an infinite sequence of positions. Then, it removes bad and duplicated positions. Finally, it updates the board with the nObstacles first elements.
Related
I am new to haskell code. I tried to compute the sum of squares of negative integer in a list using foldr high order.
sumsq :: Int -> Int
sumsq n = foldr op 0 [1..n]
where op x y = x*x + y
Please help to explain each line of code and give any solution if error in this code
When using "where", important to follow the indentation rule.
Here lambda will be appropriate
sumsq n = foldr (\x y -> x*x + y) 0 [1..n]
I have this function:
fun min x y = if x >= y then y else x
and I need to use this function (as a partial application) and make function clipupdown with arguments number and list, where number represents the minimal number that should exist in that list and all numbers lower than min should be set to that minimal number. For example when I call:
clipdown 10 [1,11,21,4,6,7,12]
I should get
[10,11,21,10,10,10,12]
Any hints?
Any hints?
What do you get when you call min (edit: or, actually max) with only one element?
min 10
how do you map a function over a list?
fun clipdown lowest numbers = map (max lowest) numbers
You have to use max, instead of min. Whenever the program finds a number below the minimum, it should choose the minimum (which is greater than the encountered number). So you need to choose the max value.
Since Int.min and Int.max already exist, but take tuples, you could write a function
fun curry f x y = f (x, y)
and use this like map o curry Int.max to get clipdown.
Similarly you could get clipup with map o curry Int.min.
You might also get clipupdown by composing both like
fun clipupdown lower higher = clipdown lower o clipup higher
But you could also use that (map f) ∘ (map g) = map (f ∘ g):
fun clipupdown lower higher = map (curry Int.max lower o curry Int.min higher)
This is called map fusion.
I'm learning functional programming (in Haskell) by re-writing some of my old C++ code. One example I'm working on involves the Floyd-Warshall graph search which runs on a 2D NxN adjacency matrix to find the shortest path between all pairs. It uses three nested for loops to scan the 2D array and iteratively reach a solution.
The C++ code would typically be:
int size = adjacencyMatrix.size();
for ( int k = 0; k < size; k++)
{
for ( int i = 0; i < size; i++)
{
for ( int j = 0; j < size; j++)
{
double sum = adjacencyMatrix[i][k] + adjacencyMatrix[k][j];
if ( sum < adjacencyMatrix[i][j] )
{
adjacencyMatrix[i][j] = sum;
}
}
}
}
The key to such a graph search is its iterative method. For example the code above is very sequential; it can only be parallelised to a moderate extent as some calculations can't be done till others have completed.
Furthermore, having access to the index of the matrix means some clever manipulations within the array can be done. The innermost loop of the above graph search uses adjacencyMatrix[i][k], adjacencyMatrix[k][j] and adjacencyMatrix[i][j]. I'm aware of the map function in Haskell, but that doesn't seem to have the same power and flexibility as using array indices.
Aside from trying to simulate an imperative procedure in Haskell I can't work out how re-write the above code in a 'pure' functional style.
How does an iterative procedure that uses complex nested loops to access array indices, such as the graph search above, translate to the functional paradigm?
Aside from trying to simulate an imperative procedure in Haskell I can't work out how re-write the above code in a 'pure' functional style.
I'm not sure you can always rewrite a fundamentally imperative algorithm in a functional style. That said, here's how one would translate your example in Haskell. Note that in general, whenever you find yourself really needing to have mutable variables for a bit, you probably want to use the ST monad. For arrays, you have the efficient array package.
Here's what a full translation of that algorithm can look like
import Data.Array.Unboxed (UArray)
import Data.Array.ST (runSTUArray, newListArray, readArray, writeArray)
import Data.Maybe (fromMaybe)
import Control.Monad (when)
import Data.Foldable (for_)
-- | Takes as input the number of vertices, function to weigh edges, and returns
-- a matrix of the shortest distance between every two vertices.
floydWarshall :: Int -> ((Int,Int) -> Maybe Double) -> UArray (Int,Int) Double
floydWarshall n weight = runSTUArray $ do
-- initialize the array with the right values
arr <- newListArray ((0,0),(n-1,n-1))
[ if i == j then 0 else fromMaybe (1 / 0) (weight (i,j))
| i<-[0..(n-1)], j<-[0..(n-1)] ]
-- iteratively improve the shortest distances
for_ [0..(n-1)] $ \k ->
for_ [0..(n-1)] $ \i ->
for_ [0..(n-1)] $ \j -> do
arr_ik <- readArray arr (i,k)
arr_kj <- readArray arr (k,j)
arr_ij <- readArray arr (i,j)
let sum = arr_ik + arr_kj
when (sum < arr_ij)
(writeArray arr (i,j) sum)
return arr
The best option is to use Data.Vector package and use ifoldl with nested imaps which will look like this:
{-# LANGUAGE OverloadedLists #-}
import Data.Vector
type Matrix a = Vector (Vector a)
floydwarshall mat = ifoldl (\m k _ ->
imap (\i row ->
imap (\j v ->
(m!i!k + m!k!j) `min` v) row) m) mat mat
Ifoldl and imap alongside values stored inside vector maps using their indices, which allows you to call values at specific index. The foldl is needed to accumulate all the changes in iterations of k while keeping structure immutable. Inside of imaps you must index inside matrix m which is our accumulator for foldr and which keeps all changes.
If you don't want to import packages, you may always implement imap and ifoldl for stock prelude lists
imap :: (Int -> a -> b) -> [a] -> [b]
imap f = map (uncurry f) . zip [0,1..]
ifoldl :: (b -> Int -> a -> b) -> b -> [a] -> b
ifoldl f acc = foldl (\ac -> uncurry (f ac)) acc . zip [0,1..]
EDITED: According to suggestion by #chi
I have written the following function in F# which, given two points, returns a function representing the line which passes throught the two points:
let getFunction (point1:float*float) (point2:float*float) =
let x1 = fst point1
let y1 = snd point1
let x2 = fst point2
let y2 = snd point2
let m = (y2-y1)/(x2-x1)
let n = y1-x1*m
fun x -> m*x+n
I would like to unit test this function, but I haven't find how to do it, since I can't use a function in a equality assertion. I have thought about generating a secuence of random points and testing the application of the function against the expected result for each point, but I was wondering if there is a better way.
I would use a property-based testing approach (see http://fsharpforfunandprofit.com/pbt/ for an excellent introduction).
You presumably want to check that, for any inputs (x1, y1) and (x2, y2), that the resulting function satisfies the following properties:
f(x1) = y1
f(x2) = y2
f is linear
If the function satisifies these, it must be correct.
You can check the first two easily. For the final property, you can pick some random x values to test.
Repeat for a selection of inputs, and you're done. As Carsten mentions, FsCheck can be used to automate testing these properties using a large number of randomly generated test cases.
I am making a sudoku solving program and I have a potentialNbrsAt function that gets the numbers that could be at position x y.
Now, I am trying to get the intersect of each lists of potential numbers in a column. Something like the onlyOnePlaceForNbrInCol function bellow.
Code:
potentialNbrsAt :: Int -> Int -> Sudoku -> [Int]
potentialNbrsAt x y sudoku = intersect rowMissingNbrs $ intersect colMissingNbrs sqrMissingNbrs
where rowMissingNbrs = getMissingNbrs $ getRow y sudoku
colMissingNbrs = getMissingNbrs $ getCol x sudoku
sqrMissingNbrs = getMissingNbrs $ getSquare squareIndex sudoku
squareIndex = 3 * (y `div` 3) + (x `div` 3)
onlyOnePlaceForNbrInCol :: Int -> Int -> Sudoku -> Bool
onlyOnePlaceForNbrInCol colIndex nbr sudoku = -- What goes here? Some pointers please???
I think onlyOnePlaceForNbrInCol should, at some point, call potentialNbrsAt with each numbers from 0 to 8 as an argument for y. Telling me how to do this would greatly help.
What about [ potentialNbrsAt x y sudoku | y <- [0..8] ] ? This gives you a list of all the results for such values of y.
So you're trying to determine whether all of the numbers [0..8] fulfill a given predicate.