Haskell Sudoku Solver - Random Block Coordinates Generator - haskell

I have a question regarding an assignment of mine. So I am supposed to implement the following using Haskell: "Write a program that generates Sudoku problems with three empty blocks. Is it also possible to generate Sudoku problems with four empty blocks?"
The random generators using IO aren't a problem, but the coordinates of the Sudoku puzzle are.. If I get for example an random integer (for example 3 (3rd block)), how can I then determine the coordinates of the random-given block? I have tried several approaches such as list comprehension, but the problem is setting the property of (x,y) - coordinates.
I would really appreciate if somebody could give me some hint.
Thanks

The question isn't entirely clear, but if I understand it correctly then you can use something like this (nb: this actually needs a number between 0 and 8 inclusive, not 1 and 9)
blockCoords n = let
[bx,by] = map (\f -> (n `f` 3) * 3) [mod,div]
r t = map (+ t) [1,2,3]
in [(x,y) | x <- r bx, y <- r by]

I'm not positive on what you're asking in the question but I think a nice solution would be to use lenses. They're quite nice when you have data structures you want to index into.
For example you could create a record type for a block
Block = { _x :: Int
_y :: Int }
$(makeLenses ''Block)
I believe the syntax is along those lines. I used lenses when I was making a minesweeper game and it made indexing the board incredibly simple.
Hope this helps!

Related

Infinite list of Fibonacci numbers in Haskell

Sorry for a question like this. I'm a very beginner programmer, and I'm just started to learn about Haskell. I recently ran into an exercise to implement a function in Haskell that returns an infinite list of Fibonacci numbers. The following code was the answer to the exercise:
fibs :: [Int]
fibs = fibs2 0
where
fibs2 :: Int -> [Int]
fibs2 x = (fib2) x : (fibs2 (x+1))
Can someone explain to me why we should declare another function (fibs2) here and what "where" does in this case?
Can someone explain to me why we should declare another function (fibs2) here?
You certainly aren't obligated to declare another function. However, this particular pattern is quite common. Think of it a bit like loop initialization in other languages. If you want to iterate some process, the easiest way to do that is to write a function that takes some information describing where you are in the iteration, does one step of the "loop", then calls itself with a suitably modified description. For example, if you wanted to sum up all the numbers from 0 to n, you might write:
sumTo :: Int -> Int
sumTo 0 = 0
sumTo n = n + foo (n-1)
BUT frequently the function or value you want is actually the one that starts at a specific value. It's annoying to force all callers of your loop to specify that starting value; and the fact that you've implemented your loop as a recursive function with an argument is an implementation detail they shouldn't have to worry about anyway. So what to do? Well, you define something that calls the loop with the right starting value.
gauss :: Int
gauss = sumTo 100
This way, users can just use gauss and not have to know that 100 is the right starting value for your internal function.
Can someone explain to me what "where" does in this case?
Well, there's one more thing that's a bit unfortunate about our previous sumTo/gauss values: we aren't really interested in sumTo itself, only in gauss, and the fact that it's visible outside of gauss is a violation of an abstraction barrier! If it's easy to call, it may be that somebody else tries to use it; then, if we need to change it to improve what gauss does, we are improving gauss but potentially breaking what that other user is using sumTo for. So we'd like to hide its existence.
That is the purpose of where here: it allows you to define a new thing that's accessible only locally. So:
gauss :: Int
gauss = sumTo 100 where
sumTo 0 = 0
sumTo n = n + sumTo (n-1)
In this variant, gauss can be called, but outside of the implementation of gauss, it isn't possible to call sumTo, maintaining a nice abstraction boundary.

Haskell: Assigning unique char to matrix values if x > 0

So my goal for the program is for it to receive an Int matrix for input, and program converts all numbers > 0 to a unique sequential char, while 0's convert into a '_' (doesn't matter, just any character not in the sequence).
eg.
main> matrixGroupings [[0,2,1],[2,2,0],[[0,0,2]]
[["_ab"],["cd_"],["__e"]]
The best I've been able to achieve is
[["_aa"],["aa_"],["__a"]]
using:
matrixGroupings xss = map (map (\x -> if x > 0 then 'a' else '_')) xss
As far as I can tell, the issue I'm having is getting the program to remember what its last value was, so that when the value check is > 0, it picks the next char in line. I can't for the life of me figure out how to do this though.
Any help would be appreciated.
Your problem is an instance of an ancient art: labelling of various structures with a stream of
labels. It dates back at least to Chris Okasaki, and my favourite treatment is by Jeremy
Gibbons.
As you can see from these two examples, there is some variety to the way a structure may be
labelled. But in this present case, I suppose the most straightforward way will do. And in Haskell
it would be really short. Let us dive in.
The recipe is this:
Define a polymorphic type for your matrices. It must be such that a matrix of numbers and a
matrix of characters are both rightful members.
Provide an instance of Traversable class. It may in many cases be derived automagically.
Pick a monad to your liking. One simple choice is State. (Actually, that is the only choice I
can think of.)
Create an action in this monad that takes a number to a character.
Traverse a matrix with this action.
Let's cook!
A type may be as simple as this:
newtype Matrix a = Matrix [[a]] deriving Show
It is entirely possible that the inner lists will be of unequal length — this type does not
protect us from making a "ragged" matrix. This is poor design. But I am going to skim over
it for now. Haskell provides an endless depth for perfection. This type is good enough for
our needs here.
We can immediately define an example of a matrix:
example :: Matrix Int
example = Matrix [[0,2,1],[2,2,0],[0,0,2]]
How hard is it to define a Traversable? 0 hard.
{-# language DeriveTraversable #-}
...
newtype Matrix a = Matrix [[a]] deriving (Show, Functor, Foldable, Traversable)
Presto.
Where do we get labels from? It is a side effect. The function reaches somewhere, takes a
stream of labels, takes the head, and puts the tail back in the extra-dimensional pocket. A
monad that can do this is State.
It works like this:
label :: Int -> State String Char
label 0 = return '_'
label x = do
ls <- get
case ls of
[ ] -> error "No more labels!"
(l: ls') -> do
put ls'
return l
I hope the code explains itself. When a function "creates" a monadic value, we call it
"effectful", or an "action" in a given monad. For instance, print is an action that,
well, prints stuff. Which is an effect. label is also an action, though in a different
monad. Compare and see for youself.
Now we are ready to cook a solution:
matrixGroupings m = evalState (traverse label m) ['a'..'z']
This is it.
λ matrixGroupings example
Matrix ["_ab","cd_","__e"]
Bon appetit!
P.S. I took all glory from you, it is unfair. To make things fun again, I challenge you for an exercise: can you define a Traversable instance that labels a matrix in another order — by columns first, then rows?

SIMPLE random number generation

I'm writing this after a good while of frustrating research, and I'm hoping someone here can enlighten me about the topic.
I want to generate a simple random number in a haskell function, but alas, this seems impossible to do without all sorts of non-trivial elements, such as Monads, asignation in "do", creating generators, etc.
Ideally I was looking for an equivalent of C's "rand()". But after much searching I'm pretty convinced there is no such thing, because of how the language is designed. (If there is, please someone enlighten me). As that doesn't seem feasible, I'd like to find a way to get a random number for my particular problem, and a general explanation on how it works to get a random number.
prefixGenerator :: (Ord a, Arbitrary a) => Gen ([a],[a])
prefixGenerator = frequency [
(1, return ([],[])),
(2, do {
xs1 <- orderedListEj13 ;
xs2 <- orderedListEj13 ;
return (xs1,xs2)
}),
(2, do {
xs2 <- orderedListEj13 ;
return ((take RANDOMNUMBERHERE xs2),xs2)
})
]
I'm trying to get to grips with QuickCheck but my inability to use random numbers is making it hard. I've tried something like this (by putting an drawInt 0 (length xs2) instead of RANDOMNUMBERHERE)but I get stuck with the fact that take requires an Int and that method leaves me with a IO Int, which seems impossible to transform to an Int according to this.
As haskell is a pure functional programming language, functions are referentially transparent which means essentially that only a function's arguments determine its result. If you were able to pull a random number out of the air, you can imagine how that would cause problems.
I suppose you need something like this:
prefixGenerator :: (Ord a, Arbitrary a) => Gen ([a],[a])
prefixGenerator = do
randn <- choose (1,999) -- number in range 1-999
frequency [
(1, return ([],[])),
(2, do {
xs1 <- orderedListEj13 ;
xs2 <- orderedListEj13 ;
return (xs1,xs2)
}),
(2, do {
xs2 <- orderedListEj13 ;
return ((take randn xs2),xs2)
})
]
In general in haskell you approach random number generation by either pulling some randomness from the IO monad, or by maintaining a PRNG that is initialized with some integer seed hard-coded, or pulled from IO (gspr's comment is excellent).
Reading about how pseudo random number generators work might help you understand System.Random, and this might help as well (scroll down to section on randomness).
You're right in that nondeterministic random (by which I mean "pseudo-random") number generation is impossible without trickery. Functions in Haskell are pure which means that the same input will always produce the same output.
The good news is that you don't seem to need a nondeterministic PRNG. In fact, it would be better if your QuickCheck test used the same sequence of "random" numbers each time, to make your tests fully reproducible.
You can do this with the mkStdGen function from System.Random. Adapted from the Haskell wiki:
import System.Random
import Data.List
randomInts :: Int -> [Int]
randomInts n = take n $ unfoldr (Just . random) (mkStdGen 4)
Here, 4 is the seed that you may want to choose by a fair dice roll.
The standard library provides a monad for random-number generation. The monadic stuff is not that hard to learn, but if you want to avoid it, find a pseudo-random function next that takes an Int to an Int in a pseudorandom way, and then just create and pass an infinite list of random numbers:
next :: Int -> Int
randoms :: [Int]
randoms = iterate next 73
You can then pass this list of random numbers wherever you need it.
Here's a linear congruential next from Wikipedia:
next n = (1103515245 * n + 12345) `mod` 1073741824
And here are the first 20 pseudorandom numbers following 73:
Prelude> take 20 $ iterate next 73
[73,25988430,339353199,182384508,910120965,1051209818,737424011,14815080,325218177,1034483750,267480167,394050068,4555453,647786674,916350979,980771712,491556281,584902142,110461279,160249772]

Storing values in a data structure Haskell

I'm trying to store randomly generated dice values in some data structure, but don't know how exactly to do it in Haskell. I have so far, only been able to generate random ints, but I want to be able to compare them to the corresponding color values and store the colors instead (can't really conceive what the function would look like). Here is the code I have --
module Main where
import System.IO
import System.Random
import Data.List
diceColor = [("Black",1),("Green",2),("Purple",3),("Red",4),("White",5),("Yellow",6)]
diceRoll = []
rand :: Int -> [Int] -> IO ()
rand n rlst = do
num <- randomRIO (1::Int, 6)
if n == 0
then printList rlst -- here is where I need to do something to store the values
else rand (n-1) (num:rlst)
printList x = putStrLn (show (sort x))
--matchColor x = doSomething()
main :: IO ()
main = do
--hSetBuffering stdin LineBuffering
putStrLn "roll, keep, score?"
cmd <- getLine
doYahtzee cmd
--rand (read cmd) []
doYahtzee :: String -> IO ()
doYahtzee cmd = do
if cmd == "roll"
then do rand 5 []
else putStrLn "Whatever"
After this, I want to be able to give the user the ability to keep identical dices (as in accumulate points for it) and give them a choice to re-roll the left over dices - I'm thinking this can done by traversing the data structure (with the dice values) and counting the repeating dices as points and storing them in yet another data structure. If the user chooses to re-roll he must be able to call random again and replace values in the original data structure.
I'm coming from an OOP background and Haskell is new territory for me. Help is much appreciated.
So, several questions, lets take them one by one :
First : How to generate something else than integers with the functions from System.Random (which is a slow generator, but for your application, performance isn't vital).
There is several approaches, with your list, you would have to write a function intToColor :
intToColor :: Int -> String
intToColor n = head . filter (\p -> snd p == n) $ [("Black",1),("Green",2),("Purple",3),("Red",4),("White",5),("Yellow",6)]
Not really nice. Though you could do better if you wrote the pair in the (key, value) order instead since there's a little bit of support for "association list" in Data.List with the lookup function :
intToColor n = fromJust . lookup n $ [(1,"Black"),(2,"Green"),(3,"Purple"),(4,"Red"),(5,"White"),(6,"Yellow")]
Or of course you could just forget this business of Int key from 1 to 6 in a list since lists are already indexed by Int :
intToColor n = ["Black","Green","Purple","Red","White","Yellow"] !! n
(note that this function is a bit different since intToColor 0 is "Black" now rather than intToColor 1, but this is not really important given your objective, if it really shock you, you can write "!! (n-1)" instead)
But since your colors are not really Strings and more like symbols, you should probably create a Color type :
data Color = Black | Green | Purple | Red | White | Yellow deriving (Eq, Ord, Show, Read, Enum)
So now Black is a value of type Color, you can use it anywhere in your program (and GHC will protest if you write Blak) and thanks to the magic of automatic derivation, you can compare Color values, or show them, or use toEnum to convert an Int into a Color !
So now you can write :
randColorIO :: IO Color
randColorIO = do
n <- randomRIO (0,5)
return (toEnum n)
Second, you want to store dice values (colors) in a data structure and give the option to keep identical throws. So first you should stock the results of several throws, given the maximum number of simultaneous throws (5) and the complexity of your data, a simple list is plenty and given the number of functions to handle lists in Haskell, it is the good choice.
So you want to throws several dices :
nThrows :: Int -> IO [Color]
nThrows 0 = return []
nThrows n = do
c <- randColorIO
rest <- nThrows (n-1)
return (c : rest)
That's a good first approach, that's what you do, more or less, except you use if instead of pattern matching and you have an explicit accumulator argument (were you going for a tail recursion ?), not really better except for strict accumulator (Int rather than lists).
Of course, Haskell promotes higher-order functions rather than direct recursion, so let's see the combinators, searching "Int -> IO a -> IO [a]" with Hoogle gives you :
replicateM :: Monad m => Int -> m a -> m [a]
Which does exactly what you want :
nThrows n = replicateM n randColorIO
(I'm not sure I would even write this as a function since I find the explicit expression clearer and almost as short)
Once you have the results of the throws, you should check which are identical, I propose you look at sort, group, map and length to achieve this objective (transforming your list of results in a list of list of identical results, not the most efficient of data structure but at this scale, the most appropriate choice). Then keeping the colors you got several time is just a matter of using filter.
Then you should write some more functions to handle interaction and scoring :
type Score = Int
yahtzee :: IO Score
yahtzeeStep :: Int -> [[Color]] -> IO [[Color]] -- recursive
scoring :: [[Color]] -> Score
So I recommend to keep and transmit a [[Color]] to keeps track of what was put aside. This should be enough for your needs.
You are basically asking two different questions here. The first question can be answered with a function like getColor n = fst . head $ filter (\x -> snd x == n) diceColor.
Your second question, however, is much more interesting. You can't replace elements. You need a function that can call itself recursively, and this function will be driving your game. It needs to accept as parameters the current score and the list of kept dice. On entry the score will be zero and the kept dice list will be empty. It will then roll as many dice as needed to fill the list (I'm not familiar with the rules of Yahtzee), output it to the user, and ask for choice. If the user chooses to end the game, the function returns the score. If he chooses to keep some dice, the function calls itself with the current score and the list of kept dice. So, to sum it up, playGame :: Score -> [Dice] -> IO Score.
Disclaimer: I am, too, very much a beginner in Haskell.
at first thought:
rand :: Int -> IO [Int]
rand n = mapM id (take n (repeat (randomRIO (1::Int, 6))))
although the haskellers could remove the parens

Repeating function recursive in Haskell

I am trying to make a function that outputs char*m n times, as such as the expected output would be ["ccc","ccc"] for the input 2 3 c. Here is what i have so far:
rectangle :: Int -> Int -> Char -> [string]
rectangle n m c
| m > 0 = [concat ([[c]] ++ (rectangle n (m-1) c))]
| otherwise = []
I am able to carry out the first part, char*m, so it returns ["ccc"]. Thing is: I also would like to be able to repeat my string n times.
I have tried using replicate but it doesn't seem to work, yet it works if doing it in the console: replicate 2 (rectangle 2 3 c).
Try the replicate function this way:
replicate :: Int -> a -> [a]
rectangle n m c = replicate n (replicate m c)
Also, don't forget to mention if this is homework.
As an addendum to Refactor's answer, I think his approach is the correct one. He subdivides the problem until it can be solved trivially using built-in functions. If you want to roll your own solution for learning purposes, I suggest you keep this subdivision, and go from there, implementing your own replicate. Otherwise, you will end up with a single function which does too much.
So the remaining problem is that of implementing replicate. My first idea would be to look at the source code for replicate. I found it via hoogle, which led me to hackage, which has links to the source code. Excerpted from the source:
replicate :: Int -> a -> [a]
replicate n x = take n (repeat x)
which is nice and concise, again using the built-in functions. If you want to completely roll your own replicate, you can do:
myReplicate :: Int -> a -> [a]
myReplicate n x | n <= 0 = []
| otherwise = x : replicate (n-1) x
----------EDIT----------------
As a side note, I think your problem requires two rather orthogonal skills. The first is trying not to tackle the whole problem at once, but making some small progress instead. Then you can try to solve that smaller problem, before returning to the larger. In your case, it would likely involve recognizing that you definitely need a way of transforming the character into a series of characters of length n. Experience with functions such as map, filter, foldr and so on will help you here, since they each represent a very distinct transformation, which you might recognize.
The second skill required for your solution - if you want to roll your own - is recognizing when a function can be expressed recursively. As you can see, your problem - and indeed many common problems - can be solved without explicit recursion, but it is a nice skill to have, when the need arises. Recursive solutions do not always come easily mind, so I think the best way to gain familiarity with them are to read and practice.
For further study, I'm sure you have already been pointed to the excellent Learn You a Haskell and Real World Haskell, but just in case you haven't, here they are.

Resources