Haskell: Call a function with each element in a list - list

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.

Related

Haskell code to compute sum of squares of negative integers using foldr function

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]

How do i remove items from a list with specific rules in haskell?

Basically i have a tupple of positions from an 8 x 8 chess board like so
chessboard = [(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(1,0),
(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(2,0),(2,1),(2,2),(2,3),
(2,4),(2,5),(2,6),(2,7),(2,8),(3,0),(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),
(3,7),(3,8),(4,0),(4,1),(4,2),(4,3),(4,4),(4,5),(4,6),(4,7),(4,8),(5,0),
(5,1),(5,2),(5,3),(5,4),(5,5),(5,6),(5,7),(5,8),(6,0),(6,1),(6,2),(6,3),
(6,4),(6,5),(6,6),(6,7),(6,8),(7,0),(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),
(7,7),(7,8),(8,0),(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8)]
I need to be able to place 8 queens on the chess board without each one being able to kill another one. I figured out a method to do this: if a queen is, for example, on (0,0) then no positions containing the same row or column is allowed, so I can remove (0,1), (0,2), (0,3) ... (x,y+1) and (1,0) , (2,0), (3,0) ... (x+1,y) from the chessboard list. So if my queen is on (0,0), how can i remove all the tupples that are (x, y+1) , (x+1,y) , (x+1, y+1), (x-1,y-1) ? I'm leaning towards recursion, but cannot figure it out.
You can use filter :: (a -> Bool) -> [a] -> [a]. Note that the the first argument - the predicate - actually decides what to keep. Not what to remove (so if it says True that means it puts the element in the resulting list):
So in order to remove all values with x = 0, you can use
filter (\(x,_) -> x /= 0) chessboard
Or filter out all elements with y equal to k:
filtery k = filter (\(_,y) -> y /= k)
You can filter out all elements that attack a queen positioned at (xq,yq) with:
filterqueen :: (Int,Int) -> [(Int,Int)] -> [(Int,Int)]
filterqueen (xq,yq) = filter noattack
where noattack (x,y) = xq /= x && yq /= y && dx /= dy && dx /= -dy
where dx = x-xq
dy = y-yq

How to get integers from list where sum of them is less than X?

Sorry for the mess that was here.
I wanted a classic greedy algorithm for knapsack problem in haskell for integers.
But there was other question - how to refer to list in list comprehension?
There are several approaches to this:
Generate all lists which are smaller. Take the longest
For every n <= X, generate [1..n] and check whether its sum is lesser x. Take the longest of those sets:
allLists x = takeWhile ( (<=x) . sum) $ inits [1..]
theList = last . allLists
where inits is from Data.List
Alternatively, we remember mathematics
We know that the sum of [1..n] is n*(n+1)/2. We want x >= n * (n+1)/2. We solve for n and get that n should be 0.5 * (sqrt (8 * x + 1) - 1). Since that's not a natural number, we floor it:
theList x = [1..n]
where n = floor $ 0.5 * (sqrt (8 * (fromIntegral x) + 1) - 1)
This will give all the lists that its sum is not greater than 100:
takeWhile (\l -> sum l <= 100) $ inits [1..]

Prime factorizacion in haskell

I'm making a program that, for a given integer n, returns a list of a pair of integers, where the first element is a prime from the prime factorization of n, and the second element is the corresponding exponent of that prime. For example for n = 50, it would output [(2,1),(5,2)], since 50 =(2^1)*(5^2).
So anyway, this is my code:
--returns all numbers that divide x
divis :: Integer -> [Integer]
divis 1 = []
divis x = [n | n<-[2..(x-1)], mod x n == 0]
--checks if a number is prime
isprime :: Integer -> Bool
isprime 1 = False
isprime n = if divis n == [] then True else False
--list of prime numbers that divide x
facto :: Integer -> [Integer]
facto 1 = []
facto x = [n | n <- (divis x), isprime n == True]
--finds the biggest exponent of a number m that divides another number n
potencia :: Integer -> Integer -> Integer
potencia _ 0 = error "error"
potencia _ 1 = error "error"
potencia n m = (head [x | x <- [0..], not(mod n (m^x) == 0)]) - 1
The next step would be that, for a number n, I can put togheter in a pair for each number in facto n its corresponding exponent, and output that.
I have tried with this:
factorizar :: Integer -> [(Integer, Integer)]
factorizar 0 = error "nope"
factorizar 1 = [(1,1)] --This isn't accurate but I'll change it later
factorizar n = [(x,y) | x<-(facto n), y == potencia n x, mod n (x^y) == 0] --THIS
I know, the y part in the set comprehension is ugly everywhere. The thing is I dont know what to use since for defining y I need to use x as well, but it is part of the set comprehension. I have tried changing it, or using 'where' but it always has a problem with 'y', telling me it's not in the scope or something. What could be an elegant solution for this?
The simple answer is
y == potencia n x
should really read
let y = potencia n x
and you don't need to check that mod n (x^y) == 0 - I think it is going to be true by definition of potencia.
There are other things you could do differently, but they are tidy-ups.

C++ to F# smooth translation

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.