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.
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.
I'm working on making my program interact with an overarching framework that transfers information with lists.
I have a breed called 'people' and I export information about them with
to srti-lists
ask people [ foreach [self] of people [
set traits-list (list (who) (color) (heading)(xcor)(ycor)(shape)]]
set master-list [traits-list] of people
end
It works great for exporting that information. What I'm having trouble with is creating or updating people with information that I then receive in the form of a master-list.
I've been approaching it as probably a foreach problem, but the problem is that while that lets me execute commands for every item of the master-list, I haven't figured out how to then access the individual nested items.
So, say:
foreach master-list
[create person
set who item 0 master-list
etc. The problem is that syntax would create a person and then set the who as an entire sublist. Omitting the list throws up an error, and selecting the items more specifically is untenable since it'd be a list of variable length.
Any ideas how to iteratively select items from nested lists? Is foreach even the right approach?
I can't test it but this looks wrong to me:
to srti-lists
ask people [ foreach [self] of people [
set traits-list (list (who) (color) (heading)(xcor)(ycor)(shape)]]
set master-list [traits-list] of people
end
ask already loops through the people, so this looks like it is assigning to each turtle the list of traits for all turtles, and then the master-list is a list of those lists. You probably want:
to srti-lists
ask people [
set traits-list (list (who) (color) (heading)(xcor)(ycor)(shape)]
set master-list [traits-list] of people
end
On the setting of traits, the who number cannot be set - it is assigned automatically when the turtle is created and can never be changed. For example, try the following complete (broken) model and you will get an error:
to testme
create-turtles 5
ask one-of turtles [set who 10 ]
end
So I don't know what you mean when you say that who is assigned an entire sublist - who is always an integer and assigned sequentially.
Concerning your stated question - your syntax set who item 0 master-list would be find if you were trying to set a variable that you could actually set.
I am fairly new to netlogo and modelling as a whole. I am now modelling the municipal solid waste system of the Netherlands and I need to be able to distribute a predetermined amount of waste-generated randomly among a breed (municipalities) within my model. I need to do the same for money among waste processors.
I have tried it with globals, with breeds-own and even creating a new breed for waste (which sort of worked but my solution needed way too much calculation power which I don't see how to simplify it.
thanks in advance
To share[waste]
While [waste > .1] ;; or some small number
[
Let r random-float 1
Set waste waste - r
Ask one-of patches[set pcolor pcolor + r
]
Ask one-of patches[set pcolor pcolor + waste ;; ditch the dregs
End
Doing it with integers would not be much different.
To make it a list
Let pots []
Ask patches[set pots lput pcolor pots]
Answer 2 uniform distribution
Ask n[set take random-float resource / count n]
Let fix (resource - sum [take] of p) / count n
Ask n[set take take + fix]
I have used R quite a bit and I know I can use head(data[,"column"]) or head(data) to see the first few rows/cells of data.
How can I do that in Stata?
You can use the list command for this:
list column in 1/6
or
list in 1/6
If you have a look at help list, you will discover plenty of options to customize the display.