Haskell List Monad State Dependance - list

I have to write a program in Haskell that will solve some nondeterministic problem.
I think i understand List Monad in 75% so it is oblivious choice but...
(My problem is filling n x m board with ships and water i am given sums of rows and colums every part of ship has its value etd its not important right now).
I want to guard as early as possible to make algoritm effective the problem is that possibility of insertion of ship is dependant from what i am given / what i have inserted in previus moves lets call it board state and i have no idea how to pass it cuz i can't generate a new state from board alone)
My Algoritm is:
1. Initialize First Board
2. Generate First Row trying applying every possible insertion (i can insert sheep verticaly so i need to remember to insert other parts of sheep in lower rows)
3. Solve the problem for smaller board (ofc after generating each 2 rows i check is everything ok)
But i have no idea how can I pass new states cuz as far as i have read about State Monad it generates new state from old state alone and this is impossible for me to do i would want to generate new state while doing operations on value).
I am sorry for my hatred towards Haskell but after few years of programing in imperative languages being forced to fight with those Monads to do things which in other languages i could write almost instantly makes me mad. (well other things in Haskell are fine for me and some of them are actually quite nice).

Combine StateT with the list monad to get your desired behavior.
Here's a simple example of using the non-determinism of the list monad while still keeping a history of previous choices made:
import Control.Monad
import Control.Monad.Trans.Class
import Control.Monad.Trans.State
fill :: StateT [Int] [] [Int]
fill = do
history <- get
if (length history == 3)
then return history
else do
choice <- lift [0, 1, 2]
guard (choice `notElem` history)
put (choice:history)
fill
fill maintains a separate history for each path that it tries out. If it fills up the board it returns successfully, but if the current choice overlaps with a previous choice it abandons that solution and tries a different path.
You run it using evalStateT, supplying an initial empty history:
>>> evalStateT fill []
[[2,1,0],[1,2,0],[2,0,1],[0,2,1],[1,0,2],[0,1,2]]
It returns a list of all possible solutions. In this case, that just happens to be the list of all permutations in which we could have filled up the board.

Related

Riddle puzzle in clingo

So in the tag prolog someone wanted to solve the "the giant cat army riddle" by Dan Finkel (see video / Link for description of the puzzle).
Since I want to improve in answer set programming I hereby challenge you to solve the puzzle more efficient than me. You will find my solution as answer. I'll accept the fastest running answer (except if it's using dirty hacks).
Rules:
hardcoding the length of the list (or something similar) counts as dirty hack.
The output has to be in the predicate r/2, where it's first argument is the index of the list and the second its entry.
Time measured is for the first valid answer.
num(0..59).
%valid operation pairs
op(N*N,N):- N=2..7.
% no need to add operations that start with 14
op(Ori,New):- num(Ori), New = Ori+7, num(New), Ori!=14.
op(Ori,New):- num(Ori), New = Ori+5, num(New), Ori!=14.
%iteratively create new numbers from old numbers
l(0,0).
{l(T+1,New) : op(Old,New)} = 1 :- l(T,Old), num(T+1), op(Old,_).
%no number twice
:- 2 #sum {1,T : l(T,Value)}, num(Value).
%2 before 10 before 14
%linear encoding
reached(T,10) :- l(T,10).
reached(T+1,10) :- reached(T,10), num(T+1).
:- reached(T,10), l(T,2).
:- l(T,14), l(T+1,_).
%looks nicer, but quadratic
%:- l(T2,2), l(T10,10), T10<T2.
%:- l(T14,14), l(T10,10), T14<T10.
%we must have these three numbers in the list somewhere
:- not l(_,2).
:- not l(_,10).
:- not l(_,14).
#show r(T,V) : l(T,V).
#show.
Having a slightly more ugly encoding improves grounding a lot (which was your main problem).
I restricted op/2 to not start with 14, as this should be the last element in the list
I do create the list iteratively, this may not be as nice, but at least for the start of the list it already removed impossible to reach values via grounding. So you will never have l(1,33) or l(2,45) etc...
Also list generation stops when reaching the value 14, as no more operation is possible/needed.
I also added a linear scaling version of the "before" section, although it is not really necessary for this short list (but a cool trick in general if you have long lists!) This is called "chaining".
Also note that your show statement is non-trivial and does create some constraints/variables.
I hope this helps, otherwise feel free to ask such questions also on our potassco mailing list ;)
My first attempt is to generate a permutation of numbers and force successor elements to be connected by one of the 3 operations (+5, +7 or sqrt). I predefine the operations to avoid choosing/counting problems. Testing for <60 is not necessary since the output of an operation has to be a number between 0 and 59. The generated List l/2 is forwarded to the output r/2 until the number 14 appears. I guess there is plenty of room to outrun my solution.
num(0..59).
%valid operation pairs
op(N*N,N):- N=2..7.
op(Ori,New):- num(Ori), New = Ori+7, num(New).
op(Ori,New):- num(Ori), New = Ori+5, num(New).
%for each position one number
l(0,0).
{l(T,N):num(N)}==1:-num(T).
{l(T,N):num(T)}==1:-num(N).
% following numbers are connected with an operation until 14
:- l(T,Ori), not op(Ori,New), l(T+1,New), l(End,14), T+1<=End.
% 2 before 10 before 14
:- l(T2,2), l(T10,10), T10<T2.
:- l(T14,14), l(T10,10), T14<T10.
% output
r(T,E):- l(T,E), l(End,14), T<=End.
#show r/2.
first Answer:
r(0,0) r(1,5) r(2,12) r(3,19) r(4,26) r(5,31) r(6,36) r(7,6)
r(8,11) r(9,16) r(10,4) r(11,2) r(12,9) r(13,3) r(14,10) r(15,15)
r(16,20) r(17,25) r(18,30) r(19,37) r(20,42) r(21,49) r(22,7) r(23,14)
There are multiple possible lists with different length.

Struggling to extract a section of a list in Haskell

I am trying to implement a basic function but I'm out of practice with Haskell and struggling so would really appreciate some help. My question is specifically how to select a section of a list by index. I know how to in other languages but have been struggling
[ x | x <- graph, x!! > 5 && x!! <10 ]
I have been fiddling around with basic list comprehension similar to what is above, and while I know that isn't right I was hoping a similarly simple solution would be available.
If anyone wants more information or felt like helping on the further question I have included more information below, thanks!
type Node = Int
type Branch = [Node]
type Graph= [Node]
next :: Branch -> Graph -> [Branch]
This is the individual question for the "next" function
This is the general set up information but most importantly that the graph is represented as a flattened adjacency matric
Apologies for the two pictures but it seemed the best way to convey the information.
As pointed out in the comments !! does not give you the index of a value in the way it seems you expect. It is just an infix for getting an element of a list.
There is no way to get the index of x like this in Haskell since the x object doesn't keep track of where it is.
To fix this we can make a list of objects that do keep track of where they were. This can be achieved with zip.
zip [0..] graph
This creates a list of tuples each containing their index and the value in graph.
So you can write your list comprehensions as
[ x | (index, x) <- zip [0..] graph, index > 5, index < 10 ]
Now this is not going to be terribly fast since it still needs to go through every element of the list despite the fact that we know no element after the 11th will be used. For speed we would want to use a combination of take and drop.
drop 5 (take 10 graph)
However if we wanted to do some other selections (e.g. all even indexes), we can still go back to the list comprehension.
In this case, you could drop 5 <&> take 4. As in drop 5 x & take 4. Drop skips the first few elements and take leaves out all but the first few left after the drop.

How to create lists in prolog with size set by the user

I am writing a game in Prolog. The game has a "board" of the form shown below and it has two lists of "pawns". The size of the board is fixed to 16 positions. I want to make the board "dynamic" so when the game starts the user will define the size.
I have thought of a way but the problem is that my way is more on a procedural way which for Prolog is not that correct.
I thought of creating a predicate size/1 which will be initialized by the user in the beginning and then all the lists will be initialized according to that predicate using repeats and cuts and assert...
Could someone propose any better implementation?
/*--------------------------------------------------------------------------
Initial armies (lists of 1 to 8)
--------------------------------------------------------------------------*/
black_army([1,2,3,4,5,6,7,8]).
white_army([1,2,3,4,5,6,7,8]).
/*--------------------------------------------------------------------------
Initial Board (all positions empty)
--------------------------------------------------------------------------*/
board([
(1,-,-),(2,-,-),(3,-,-),(4,-,-),
(5,-,-),(6,-,-),(7,-,-),(8,-,-),
(9,-,-),(10,-,-),(11,-,-),
(13,-,-),(14,-,-),(15,-,-),(16,-,-),(12,-,-)
]).
I think I would keep board size implicit in data declaration, just make it dynamic, and initialize when user request to change: so, keep your code as is, just add in front (note: untested code)
:- dynamic(black_army/1).
:- dynamic(white_army/1).
:- dynamic(board/1).
initialize_data(Size) :-
Size > 1, % this should be a sensible value, of course
retract(black_army(_)),
retract(white_army(_)),
retract(board(_)),
numlist(1,Size,B),
assertz(black_army(B)),
numlist(1,Size,W),
assertz(white_army(W)),
D is Size*2, findall((I,-,-), between(1,D,I), Board),
assertz(board(Board)).

Creating a list of players

I want to create a list of "players".
The user of the program can say how many players he wants.
Amount = io:get_line("how many players? \n"),
Int = string:to_integer(Amount),
List = Lists:seq(1,Int).
But now I want to create a list of players in the form [Player1, Player2...PlayerN].
Can someone tell me how to do so?
Remember that string:to_int/1 will return a tuple, not a single value. Also keep in mind that users do some pretty wild stuff in input, so you'll want to check that. (That said... when you're just trying to get a program written for yourself to test an idea, meh, whatever.)
{PlayerCount, _} = string:to_integer(io:get_line("How many players? ")),
Pretty simple. Mess around with this a bit. Input is its own world, and its good to think through this stuff a few times in toy programs (and give yourself insane input to see how the program reacts).
From here you can do a few things. If you just want a list of tuples that indicate you have a player whose serial number is a number, that's easy with a list comprehension:
Players = [{player, Number} || Number <- lists:seq(1, PlayerCount)],
You can write that as a map as well:
Players = lists:map(fun(N) -> {player, N} end, lists:seq(1, PlayerCount)),
I find the list comprehension more readable, though. Another alternative is to write your own custom recursive function. You almost never need to do this, but if you're new to programming it is good practice, and early on its way more readable because you see exactly what is happening each iteration:
player_list(Count) -> player_list(1, Count, []).
player_list(Max, Max, Players) ->
lists:reverse(Players);
player_list(Current, Max, Players) ->
player_list(Current + 1, Max, [make_new_player(Current) | Players]).
Note that the above is equivalent to, but more naturally stated than:
player_list(Current, Max, Players) ->
Next = Current + 1,
case Next == Max of
true -> lists:reverse(Players);
false -> player_list(Next, Max, [make_new_player(Current) | Players])
end.
Matching in function heads is much more clear and readable over the course of a program than a bunch of case and if statements. Over time, though, as I mentioned above, you will eventually stop writing recursive functions yourself (for the most part) and find yourself using a lot of list operations (map, fold, filter, list comprehensions, etc.) as you gain experience.
The details of make_new_player/0,1 are entirely up to you, of course -- you didn't indicate what sort of structure you wanted for their data, but you can do whatever you want there. Here are some other ways that might play out:
[make_new_player(Z) || Z <- lists:seq(1, PlayerCount)]
or
[#player{serial = Z} || Z <- lists:seq(1, PlayerCount)]

Haskell: Procedurally generating level without slowing down

To better learn Haskell, I'm trying to basically build a variant of the well-known Indie Game Super Hexagon.
I am however having a problem with the level generation:
Right now, level generation is done by having a list containing all different "gauntlets" (patterns of walls, implemented as [[Bool]],a variable number of rows, each containing True or False for ); these are the building blocks of the level. Using the getStdGen() number generator, I'm able to create an infinite list of gauntlets.
However, at a single time, we only want to render part of these. To keep track of if a gauntlet has already been passed or not, a second argument is introduced, containing the sum of the number of rows of all gauntlets before this one. (e.g, length (gauntletData currentRandomNumber) + snd $ randomGauntletList !! (n-1), where randomGauntletList has the type [(Gauntlet,Integer)]
The problem is in how this list is used in the rendering function and the updating function: take 30 $ dropWhile (\(_,distance) -> currentDistance > distance) randomGauntletList
The dropWhile results in the program taking longer and longer to return the current 'starting point' of the list, therefore slowing down the game after +- 30 seconds.
I'm out of my depth: Is there a way to solve this problem?