Towers of Hanoi using Lists Prolog - list

I know that there is already sample programs floating around that cover this, but I need to do the towers of hanoi with 6 discs a specific way for an assignment and I'm having trouble. Code I currently have is below:
s([],[],[]).
initial(s([1,2,3,4,5,6], [], [])).
goal(s([],[],[1,2,3,4,5,6])).
I also have 26 lines of code to verify valid states, however I tested that code on it's own and it works, the issue I'm having is creating the code to move the discs from stack to stack. An example of what I'm trying to do along with an example query is below:
changeState((s([A | B],[],[])), s([C], [D], [])) :- C is B, D is A.
?- changeState((s([1,2,3,4,5,6],[],[])), s([2,3,4,5,6], [1], [])).
So this would be the very beginning, where all 6 plates are on the first stack, and I want to move the top plate to the second stack. Essentially, I want to be able to remove the first element from a list, and add it to another list, whether it is empty or not.
Edits:
Got what I needed above working, now I just need help fixing the traverse predicate. Entire code is below:
%Post A, Post B, Post C
s([],[],[]).
initial(s([1,2,3,4,5,6], [], [])).
goal(s([],[],[1,2,3,4,5,6])).
valid([], _).
valid([H|_], X) :-
X < H.
changeState((s([A|T1], T2, T3)), s(T1, [A|T2], T3)) :-
valid(T2, A).
changeState((s([A|T1], T2, T3)), s(T1, T2, [A|T3])) :-
valid(T3, A).
changeState(s(T1, [A|T2], [B|T3]), s(T1, T2, [A,B|T3])) :-
valid(A,B).
changeState(s([A|T1], T2, [B|T3]), s([B,A|T1], T2, T3)) :-
valid(B, A).
changeState(s(T1, [A|T2], [B|T3]), s(T1, [B,A|T2], T3)) :-
valid(B, A).
changeState(s([A|T1], [B|T2], T3), s(T1, [A,B|T2], T3)) :-
valid(A,B).
changeState(s([A|T1], [B|T2], T3), s([B,A|T1], T2, T3)) :-
valid(B,A).
changeState(s([A|T1], T2, [B|T3]), s(T1, T2, [A,B|T3])) :-
valid(A,B).
changeState(s(T1, [A|T2], T3), s(T1, T2, [A|T3])) :-
valid(T3, A).
changeState(s(T1, [A|T2], T3), s([A|T1], T2, T3)) :-
valid(T1, A).
changeState(s(T1, T2, [A|T3]), s(T1, [A|T2], T3)) :-
valid(T2, A).
changeState(s(T1, T2, [A|T3]), s([A|T1], T2, T3)) :-
valid(T1, A).
traverse(StartNode,Sol,_) :- goal(StartNode), Sol = [StartNode].
traverse(StartNode,Sol,Visit) :- changeState(StartNode, NextNode),
not(member(NextNode, Visit)),
traverse(NextNode, PartialSol, [NextNode|Visit]),
Sol = [StartNode | PartialSol].
When I run this query:
?- traverse((s([1,2,3,4,5,6], [], [])), Sol, s([1,2,3,4,5,6], [], [])).
I get this output:
I've left it running after I get those responses for about 10 minutes and it still doesn't produce new ones so it's just continuing to run over and over again. As mentioned above, the point of the program is to solve the Towers of Hanoi problem with 6 discs using Lists. For those not familiar with Towers of Hanoi, you essentially need to move all discs from the first stack, to the last 3rd stack. You can only move 1 disc at a time, and you cannot place a larger disc on-top of a smaller disc. So you start with (s([1,2,3,4,5,6], [], [])) with each list representing Stack A, Stack B, Stack C respectively, and the goal is to end with (s([], [], [1,2,3,4,5,6])). I manually ran through an entire solution (63 moves) through the changeState predicates and all transitions were accepted, so the issue is with the transverse predicate. The transverse predicate is meant to show all steps that lead up to the solution, and all possible solutions. It's also meant to stop cycles, so that it's not just swapping the same 2 discs over and over again. Can't quite figure out what's wrong with my predicates thats causing me to get this output, I'm still fairly new to prolog, so I would appreciate any help!

You can use unification here instead of is/2 (which is typically used to evaluate expressions).
For example we can define a move from the first tower to the second tower, given the second tower is empty:
changeState((s([A|T1],[], T3)), s(T1, [A], T3)).
or we can move an element to the second tower that is non-empty, given the top of the stack is an element that is larger:
changeState(s([A|T1], [B|T2], T3), s(T1, [A,B|T2], T3)) :-
A < B.
The above will result in a total of 12 rules: 3 sources, times 2 destinations times 2 possibilities (empty destination, versus non-empty destination). This is not very elegant. We can construct a helper predicate that checks if the destination stack is valid, with:
valid_stack([], _).
valid_stack([H|_], X) :-
X < H.
so then we can compress the two rules above into:
changeState((s([A|T1], T2, T3)), s(T1, [A|T2], T3)) :-
valid_stack(T2, A).
This will thus result in six rules: three sources, and two destinations.
We thus no longer need to validate the moves, since if the changeState succeeds, then the proposed move is possible given the original state was valid.
This is not the full solution however (I leave the rest as an exercise). You will need a mechanism that enumerates over the possible moves, and makes sure that you do not end up in loops (like moving a disc constantly between two towers).
After using the traverse/3 predicate, we obtain a list of moves to the goal:
?- traverse(s([1,2,3,4,5,6], [], []), S, [s([1,2,3,4,5,6], [], [])]).
S = [s([1, 2, 3, 4, 5, 6], [], []), s([2, 3, 4, 5, 6], [1], []), s([3, 4, 5, 6], [1], [2]), s([1, 3, 4, 5|...], [], [2]), s([3, 4, 5|...], [], [1, 2]), s([4, 5|...], [3], [1, 2]), s([1|...], [3], [2]), s([...|...], [...|...], [...]), s(..., ..., ...)|...] [write]
S = [s([1, 2, 3, 4, 5, 6], [], []), s([2, 3, 4, 5, 6], [1], []), s([3, 4, 5, 6], [1], [2]), s([1, 3, 4, 5, 6], [], [2]), s([3, 4, 5, 6], [], [1, 2]), s([4, 5, 6], [3], [1, 2]), s([1, 4, 5, 6], [3], [2]), s([4, 5, 6], [1, 3], [2]), s([2, 4, 5, 6], [1, 3], []), s([1, 2, 4, 5, 6], [3], []), s([2, 4, 5, 6], [3], [1]), s([4, 5, 6], [2, 3], [1]), s([1, 4, 5, 6], [2, 3], []), s([4, 5, 6], [1, 2, 3], []), s([5, 6], [1, 2, 3], [4]), s([1, 5, 6], [2, 3], [4]), s([5, 6], [2, 3], [1, 4]), s([2, 5, 6], [3], [1, 4]), s([1, 2, 5, 6], [3], [4]), s([2, 5, 6], [1, 3], [4]), s([5, 6], [1, 3], [2, 4]), s([1, 5, 6], [3], [2, 4]), s([5, 6], [3], [1, 2, 4]), s([3, 5, 6], [], [1, 2, 4]), s([1, 3, 5, 6], [], [2, 4]), s([3, 5, 6], [1], [2, 4]), s([2, 3, 5, 6], [1], [4]), s([1, 2, 3, 5, 6], [], [4]), s([2, 3, 5, 6], [], [1, 4]), s([3, 5, 6], [2], [1, 4]), s([1, 3, 5, 6], [2], [4]), s([3, 5, 6], [1, 2], [4]), s([5, 6], [1, 2], [3, 4]), s([1, 5, 6], [2], [3, 4]), s([5, 6], [2], [1, 3, 4]), s([2, 5, 6], [], [1, 3, 4]), s([1, 2, 5, 6], [], [3, 4]), s([2, 5, 6], [1], [3, 4]), s([5, 6], [1], [2, 3, 4]), s([1, 5, 6], [], [2, 3, 4]), s([5, 6], [], [1, 2, 3, 4]), s([6], [5], [1, 2, 3, 4]), s([1, 6], [5], [2, 3, 4]), s([6], [1, 5], [2, 3, 4]), s([2, 6], [1, 5], [3, 4]), s([1, 2, 6], [5], [3, 4]), s([2, 6], [5], [1, 3, 4]), s([6], [2, 5], [1, 3, 4]), s([1, 6], [2, 5], [3, 4]), s([6], [1, 2, 5], [3, 4]), s([3, 6], [1, 2, 5], [4]), s([1, 3, 6], [2, 5], [4]), s([3, 6], [2, 5], [1, 4]), s([2, 3, 6], [5], [1, 4]), s([1, 2, 3, 6], [5], [4]), s([2, 3, 6], [1, 5], [4]), s([3, 6], [1, 5], [2, 4]), s([1, 3, 6], [5], [2, 4]), s([3, 6], [5], [1, 2, 4]), s([6], [3, 5], [1, 2, 4]), s([1, 6], [3, 5], [2, 4]), s([6], [1, 3, 5], [2, 4]), s([2, 6], [1, 3, 5], [4]), s([1, 2, 6], [3, 5], [4]), s([2, 6], [3, 5], [1, 4]), s([6], [2, 3, 5], [1, 4]), s([1, 6], [2, 3, 5], [4]), s([6], [1, 2, 3, 5], [4]), s([4, 6], [1, 2, 3, 5], []), s([1, 4, 6], [2, 3, 5], []), s([4, 6], [2, 3, 5], [1]), s([2, 4, 6], [3, 5], [1]), s([1, 2, 4, 6], [3, 5], []), s([2, 4, 6], [1, 3, 5], []), s([4, 6], [1, 3, 5], [2]), s([1, 4, 6], [3, 5], [2]), s([4, 6], [3, 5], [1, 2]), s([3, 4, 6], [5], [1, 2]), s([1, 3, 4, 6], [5], [2]), s([3, 4, 6], [1, 5], [2]), s([2, 3, 4, 6], [1, 5], []), s([1, 2, 3, 4, 6], [5], []), s([2, 3, 4, 6], [5], [1]), s([3, 4, 6], [2, 5], [1]), s([1, 3, 4, 6], [2, 5], []), s([3, 4, 6], [1, 2, 5], []), s([4, 6], [1, 2, 5], [3]), s([1, 4, 6], [2, 5], [3]), s([4, 6], [2, 5], [1, 3]), s([2, 4, 6], [5], [1, 3]), s([1, 2, 4, 6], [5], [3]), s([2, 4, 6], [1, 5], [3]), s([4, 6], [1, 5], [2, 3]), s([1, 4, 6], [5], [2, 3]), s([4, 6], [5], [1, 2, 3]), s([6], [4, 5], [1, 2, 3]), s([1, 6], [4, 5], [2, 3]), s([6], [1, 4, 5], [2, 3]), s([2, 6], [1, 4, 5], [3]), s([1, 2, 6], [4, 5], [3]), s([2, 6], [4, 5], [1, 3]), s([6], [2, 4, 5], [1, 3]), s([1, 6], [2, 4, 5], [3]), s([6], [1, 2, 4, 5], [3]), s([3, 6], [1, 2, 4, 5], []), s([1, 3, 6], [2, 4, 5], []), s([3, 6], [2, 4, 5], [1]), s([2, 3, 6], [4, 5], [1]), s([1, 2, 3, 6], [4, 5], []), s([2, 3, 6], [1, 4, 5], []), s([3, 6], [1, 4, 5], [2]), s([1, 3, 6], [4, 5], [2]), s([3, 6], [4, 5], [1, 2]), s([6], [3, 4, 5], [1, 2]), s([1, 6], [3, 4, 5], [2]), s([6], [1, 3, 4, 5], [2]), s([2, 6], [1, 3, 4, 5], []), s([1, 2, 6], [3, 4, 5], []), s([2, 6], [3, 4, 5], [1]), s([6], [2, 3, 4, 5], [1]), s([1, 6], [2, 3, 4, 5], []), s([6], [1, 2, 3, 4, 5], []), s([], [1, 2, 3, 4, 5], [6]), s([1], [2, 3, 4, 5], [6]), s([], [2, 3, 4, 5], [1, 6]), s([2], [3, 4, 5], [1, 6]), s([1, 2], [3, 4, 5], [6]), s([2], [1, 3, 4, 5], [6]), s([], [1, 3, 4, 5], [2, 6]), s([1], [3, 4, 5], [2, 6]), s([], [3, 4, 5], [1, 2, 6]), s([3], [4, 5], [1, 2, 6]), s([1, 3], [4, 5], [2, 6]), s([3], [1, 4, 5], [2, 6]), s([2, 3], [1, 4, 5], [6]), s([1, 2, 3], [4, 5], [6]), s([2, 3], [4, 5], [1, 6]), s([3], [2, 4, 5], [1, 6]), s([1, 3], [2, 4, 5], [6]), s([3], [1, 2, 4, 5], [6]), s([], [1, 2, 4, 5], [3, 6]), s([1], [2, 4, 5], [3, 6]), s([], [2, 4, 5], [1, 3, 6]), s([2], [4, 5], [1, 3, 6]), s([1, 2], [4, 5], [3, 6]), s([2], [1, 4, 5], [3, 6]), s([], [1, 4, 5], [2, 3, 6]), s([1], [4, 5], [2, 3, 6]), s([], [4, 5], [1, 2, 3, 6]), s([4], [5], [1, 2, 3, 6]), s([1, 4], [5], [2, 3, 6]), s([4], [1, 5], [2, 3, 6]), s([2, 4], [1, 5], [3, 6]), s([1, 2, 4], [5], [3, 6]), s([2, 4], [5], [1, 3, 6]), s([4], [2, 5], [1, 3, 6]), s([1, 4], [2, 5], [3, 6]), s([4], [1, 2, 5], [3, 6]), s([3, 4], [1, 2, 5], [6]), s([1, 3, 4], [2, 5], [6]), s([3, 4], [2, 5], [1, 6]), s([2, 3, 4], [5], [1, 6]), s([1, 2, 3, 4], [5], [6]), s([2, 3, 4], [1, 5], [6]), s([3, 4], [1, 5], [2, 6]), s([1, 3, 4], [5], [2, 6]), s([3, 4], [5], [1, 2, 6]), s([4], [3, 5], [1, 2, 6]), s([1, 4], [3, 5], [2, 6]), s([4], [1, 3, 5], [2, 6]), s([2, 4], [1, 3, 5], [6]), s([1, 2, 4], [3, 5], [6]), s([2, 4], [3, 5], [1, 6]), s([4], [2, 3, 5], [1, 6]), s([1, 4], [2, 3, 5], [6]), s([4], [1, 2, 3, 5], [6]), s([], [1, 2, 3, 5], [4, 6]), s([1], [2, 3, 5], [4, 6]), s([], [2, 3, 5], [1, 4, 6]), s([2], [3, 5], [1, 4, 6]), s([1, 2], [3, 5], [4, 6]), s([2], [1, 3, 5], [4, 6]), s([], [1, 3, 5], [2, 4, 6]), s([1], [3, 5], [2, 4, 6]), s([], [3, 5], [1, 2, 4, 6]), s([3], [5], [1, 2, 4, 6]), s([1, 3], [5], [2, 4, 6]), s([3], [1, 5], [2, 4, 6]), s([2, 3], [1, 5], [4, 6]), s([1, 2, 3], [5], [4, 6]), s([2, 3], [5], [1, 4, 6]), s([3], [2, 5], [1, 4, 6]), s([1, 3], [2, 5], [4, 6]), s([3], [1, 2, 5], [4, 6]), s([], [1, 2, 5], [3, 4, 6]), s([1], [2, 5], [3, 4, 6]), s([], [2, 5], [1, 3, 4, 6]), s([2], [5], [1, 3, 4, 6]), s([1, 2], [5], [3, 4, 6]), s([2], [1, 5], [3, 4, 6]), s([], [1, 5], [2, 3, 4, 6]), s([1], [5], [2, 3, 4, 6]), s([], [5], [1, 2, 3, 4, 6]), s([5], [], [1, 2, 3, 4, 6]), s([1, 5], [], [2, 3, 4, 6]), s([5], [1], [2, 3, 4, 6]), s([2, 5], [1], [3, 4, 6]), s([1, 2, 5], [], [3, 4, 6]), s([2, 5], [], [1, 3, 4, 6]), s([5], [2], [1, 3, 4, 6]), s([1, 5], [2], [3, 4, 6]), s([5], [1, 2], [3, 4, 6]), s([3, 5], [1, 2], [4, 6]), s([1, 3, 5], [2], [4, 6]), s([3, 5], [2], [1, 4, 6]), s([2, 3, 5], [], [1, 4, 6]), s([1, 2, 3, 5], [], [4, 6]), s([2, 3, 5], [1], [4, 6]), s([3, 5], [1], [2, 4, 6]), s([1, 3, 5], [], [2, 4, 6]), s([3, 5], [], [1, 2, 4, 6]), s([5], [3], [1, 2, 4, 6]), s([1, 5], [3], [2, 4, 6]), s([5], [1, 3], [2, 4, 6]), s([2, 5], [1, 3], [4, 6]), s([1, 2, 5], [3], [4, 6]), s([2, 5], [3], [1, 4, 6]), s([5], [2, 3], [1, 4, 6]), s([1, 5], [2, 3], [4, 6]), s([5], [1, 2, 3], [4, 6]), s([4, 5], [1, 2, 3], [6]), s([1, 4, 5], [2, 3], [6]), s([4, 5], [2, 3], [1, 6]), s([2, 4, 5], [3], [1, 6]), s([1, 2, 4, 5], [3], [6]), s([2, 4, 5], [1, 3], [6]), s([4, 5], [1, 3], [2, 6]), s([1, 4, 5], [3], [2, 6]), s([4, 5], [3], [1, 2, 6]), s([3, 4, 5], [], [1, 2, 6]), s([1, 3, 4, 5], [], [2, 6]), s([3, 4, 5], [1], [2, 6]), s([2, 3, 4, 5], [1], [6]), s([1, 2, 3, 4, 5], [], [6]), s([2, 3, 4, 5], [], [1, 6]), s([3, 4, 5], [2], [1, 6]), s([1, 3, 4, 5], [2], [6]), s([3, 4, 5], [1, 2], [6]), s([4, 5], [1, 2], [3, 6]), s([1, 4, 5], [2], [3, 6]), s([4, 5], [2], [1, 3, 6]), s([2, 4, 5], [], [1, 3, 6]), s([1, 2, 4, 5], [], [3, 6]), s([2, 4, 5], [1], [3, 6]), s([4, 5], [1], [2, 3, 6]), s([1, 4, 5], [], [2, 3, 6]), s([4, 5], [], [1, 2, 3, 6]), s([5], [4], [1, 2, 3, 6]), s([1, 5], [4], [2, 3, 6]), s([5], [1, 4], [2, 3, 6]), s([2, 5], [1, 4], [3, 6]), s([1, 2, 5], [4], [3, 6]), s([2, 5], [4], [1, 3, 6]), s([5], [2, 4], [1, 3, 6]), s([1, 5], [2, 4], [3, 6]), s([5], [1, 2, 4], [3, 6]), s([3, 5], [1, 2, 4], [6]), s([1, 3, 5], [2, 4], [6]), s([3, 5], [2, 4], [1, 6]), s([2, 3, 5], [4], [1, 6]), s([1, 2, 3, 5], [4], [6]), s([2, 3, 5], [1, 4], [6]), s([3, 5], [1, 4], [2, 6]), s([1, 3, 5], [4], [2, 6]), s([3, 5], [4], [1, 2, 6]), s([5], [3, 4], [1, 2, 6]), s([1, 5], [3, 4], [2, 6]), s([5], [1, 3, 4], [2, 6]), s([2, 5], [1, 3, 4], [6]), s([1, 2, 5], [3, 4], [6]), s([2, 5], [3, 4], [1, 6]), s([5], [2, 3, 4], [1, 6]), s([1, 5], [2, 3, 4], [6]), s([5], [1, 2, 3, 4], [6]), s([], [1, 2, 3, 4], [5, 6]), s([1], [2, 3, 4], [5, 6]), s([], [2, 3, 4], [1, 5, 6]), s([2], [3, 4], [1, 5, 6]), s([1, 2], [3, 4], [5, 6]), s([2], [1, 3, 4], [5, 6]), s([], [1, 3, 4], [2, 5, 6]), s([1], [3, 4], [2, 5, 6]), s([], [3, 4], [1, 2, 5, 6]), s([3], [4], [1, 2, 5, 6]), s([1, 3], [4], [2, 5, 6]), s([3], [1, 4], [2, 5, 6]), s([2, 3], [1, 4], [5, 6]), s([1, 2, 3], [4], [5, 6]), s([2, 3], [4], [1, 5, 6]), s([3], [2, 4], [1, 5, 6]), s([1, 3], [2, 4], [5, 6]), s([3], [1, 2, 4], [5, 6]), s([], [1, 2, 4], [3, 5, 6]), s([1], [2, 4], [3, 5, 6]), s([], [2, 4], [1, 3, 5, 6]), s([2], [4], [1, 3, 5, 6]), s([1, 2], [4], [3, 5, 6]), s([2], [1, 4], [3, 5, 6]), s([], [1, 4], [2, 3, 5, 6]), s([1], [4], [2, 3, 5, 6]), s([], [4], [1, 2, 3, 5, 6]), s([4], [], [1, 2, 3, 5, 6]), s([1, 4], [], [2, 3, 5, 6]), s([4], [1], [2, 3, 5, 6]), s([2, 4], [1], [3, 5, 6]), s([1, 2, 4], [], [3, 5, 6]), s([2, 4], [], [1, 3, 5, 6]), s([4], [2], [1, 3, 5, 6]), s([1, 4], [2], [3, 5, 6]), s([4], [1, 2], [3, 5, 6]), s([3, 4], [1, 2], [5, 6]), s([1, 3, 4], [2], [5, 6]), s([3, 4], [2], [1, 5, 6]), s([2, 3, 4], [], [1, 5, 6]), s([1, 2, 3, 4], [], [5, 6]), s([2, 3, 4], [1], [5, 6]), s([3, 4], [1], [2, 5, 6]), s([1, 3, 4], [], [2, 5, 6]), s([3, 4], [], [1, 2, 5, 6]), s([4], [3], [1, 2, 5, 6]), s([1, 4], [3], [2, 5, 6]), s([4], [1, 3], [2, 5, 6]), s([2, 4], [1, 3], [5, 6]), s([1, 2, 4], [3], [5, 6]), s([2, 4], [3], [1, 5, 6]), s([4], [2, 3], [1, 5, 6]), s([1, 4], [2, 3], [5, 6]), s([4], [1, 2, 3], [5, 6]), s([], [1, 2, 3], [4, 5, 6]), s([1], [2, 3], [4, 5, 6]), s([], [2, 3], [1, 4, 5, 6]), s([2], [3], [1, 4, 5, 6]), s([1, 2], [3], [4, 5, 6]), s([2], [1, 3], [4, 5, 6]), s([], [1, 3], [2, 4, 5, 6]), s([1], [3], [2, 4, 5, 6]), s([], [3], [1, 2, 4, 5, 6]), s([3], [], [1, 2, 4, 5, 6]), s([1, 3], [], [2, 4, 5, 6]), s([3], [1], [2, 4, 5, 6]), s([2, 3], [1], [4, 5, 6]), s([1, 2, 3], [], [4, 5, 6]), s([2, 3], [], [1, 4, 5, 6]), s([3], [2], [1, 4, 5, 6]), s([1, 3], [2], [4, 5, 6]), s([3], [1, 2], [4, 5, 6]), s([], [1, 2], [3, 4, 5, 6]), s([1], [2], [3, 4, 5, 6]), s([], [2], [1, 3, 4, 5, 6]), s([2], [], [1, 3, 4, 5, 6]), s([1, 2], [], [3, 4, 5, 6]), s([2], [1], [3, 4, 5, 6]), s([], [1], [2, 3, 4, 5, 6]), s([1], [], [2, 3, 4, 5, 6]), s([], [], [1, 2, 3, 4, 5, 6])]
In SWI-Prolog, one needs to hit W you ask the interactive shell to print the full list.

Related

How to efficiently multiply each element of vector with matrix getting enlarged matrix

I would like to achieve the following in an efficient way in numpy. Suppose I have a matrix
A = np.asarray([[1, 2], [3, 4]])
and
B = np.asarray([1, 10, 100])
I would like to multiply each element in A with the first element of B, then each element in A with the second element in B etc. At the end a matrix of shape (A.shape[0]*B.shape[0], A.shape[1])
the result should be
np.asarray([[1, 2], [3, 4], [10, 20], [30, 40], [100, 200], [300, 400]])
Out[216]:
array([[ 1, 2],
[ 3, 4],
[ 10, 20],
[ 30, 40],
[100, 200],
[300, 400]])
Reshape with numpy broadcasting:
# option 1
(A * B[:,None,None]).reshape(-1, A.shape[1])
#array([[ 1, 2],
# [ 3, 4],
# [ 10, 20],
# [ 30, 40],
# [100, 200],
# [300, 400]])
# option 2
(A.ravel() * B[:,None]).reshape(-1, A.shape[1])
#array([[ 1, 2],
# [ 3, 4],
# [ 10, 20],
# [ 30, 40],
# [100, 200],
# [300, 400]])
Or use np.einsum:
np.einsum('ij,k->kij', A, B).reshape(-1, A.shape[1])
#array([[ 1, 2],
# [ 3, 4],
# [ 10, 20],
# [ 30, 40],
# [100, 200],
# [300, 400]])

Google Chart hAxis Title

options: {"title":"Overall Stats","height":230,"legend":{"position":"in"},"hAxis":{"title":"Division"}},
I have this as my options for my google column chart but this displays "Division" on both my vertical and horizontal axis and removes all the labels on the hAxis. Can anyone tell me why this is happening?
is there more you can share?
seems to work fine here...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable();
data.addColumn('timeofday', 'Time of Day');
data.addColumn('number', 'Motivation Level');
data.addColumn('number', 'Energy Level');
data.addRows([
[{v: [8, 0, 0], f: '8 am'}, 1, .25],
[{v: [9, 0, 0], f: '9 am'}, 2, .5],
[{v: [10, 0, 0], f:'10 am'}, 3, 1],
[{v: [11, 0, 0], f: '11 am'}, 4, 2.25],
[{v: [12, 0, 0], f: '12 pm'}, 5, 2.25],
[{v: [13, 0, 0], f: '1 pm'}, 6, 3],
[{v: [14, 0, 0], f: '2 pm'}, 7, 4],
[{v: [15, 0, 0], f: '3 pm'}, 8, 5.25],
[{v: [16, 0, 0], f: '4 pm'}, 9, 7.5],
[{v: [17, 0, 0], f: '5 pm'}, 10, 10],
]);
new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
dataTable: data,
options: {"title":"Overall Stats","height":230,"legend":{"position":"in"},"hAxis":{"title":"Division"}}
}).draw();
},
packages: ['corechart', 'controls']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Printing each item in a multidimensional list on a new line doesn't work

Here is a snippet of my code:
maximum = list([[x[0], x[-1]] for x in score_list])
print ("Here are the student's higest scores:")
for i in maximum:
print(maximum)
Maximum contains:
[['Andy', 8], ['Bill', 7], ['Steve', 7], ['Andrew', 10], ['Ted', 9], ['Lisa', 10]]
I am adding some values from the front and end of maximum and converting them to a list. I am trying to print them out all on a new line with the for loop but it seems to just print
[['Andy', 8], ['Bill', 7], ['Steve', 7], ['Andrew', 10], ['Ted', 9], ['Lisa', 10]]
[['Andy', 8], ['Bill', 7], ['Steve', 7], ['Andrew', 10], ['Ted', 9], ['Lisa', 10]]
[['Andy', 8], ['Bill', 7], ['Steve', 7], ['Andrew', 10], ['Ted', 9], ['Lisa', 10]]
[['Andy', 8], ['Bill', 7], ['Steve', 7], ['Andrew', 10], ['Ted', 9], ['Lisa', 10]]
[['Andy', 8], ['Bill', 7], ['Steve', 7], ['Andrew', 10], ['Ted', 9], ['Lisa', 10]]
[['Andy', 8], ['Bill', 7], ['Steve', 7], ['Andrew', 10], ['Ted', 9], ['Lisa', 10]]
instead of each value once like:
['Andy',8]
['Steve',7]
['Bill',7]
(and so on)
I've googled for a solution to this but everywhere I go I see the for loop that I have above yet it does not work.
for i in maximum:
print (i)

Length of Pairing

I've defined a function
def pair(m,v):
ans = []
for x in m:
for sub in x[-1]:
if sub[1] == v:
ans = ans + [x[0][0], sub[0]]
print ans
Then I set pairing = pair(regs,5)
I get the desired output:
[['551c1', 5], ['2665d1', 11], ['2784a1', 5], ['3112b1', 5], ['3280i1', 7], ['3380d1',7], ['3474f1', 5], ['3774d1', 7], ['3782a1', 5], ['3879d1', 13], ['4086b1', 7], ['4556b1', 11], ['4600m1', 7], ['4617d1', 5], ['4656k1', 7], ['4979b1', 5], ['5094e1', 5], ['5982h1', 7], ['6501b1', 5], ['6786f1', 5], ['7232c1', 5], ['7566j1', 5], ['7617a1', 5], ['7742m1', 5], ['7826m1', 5], ['7974k1', 5], ['8262c1', 7], ['8528h1', 5], ['8534b1', 7], ['8710h1', 7], ['8949a1', 5], ['9048n1', 5], ['9285e1', 7], ['9520l1', 11], ['9559d1', 7], ['9622d1', 7], ['9650f1', 7], ['9865b1', 13], ['10082c1', 7], ['10549c1', 13], ['10789a1', 5], ['10926a1', 5], ['10994d1', 5], ['11482a1', 5], ['11610e1', 13], ['11840g1', 13], ['11907z1', 5], ['12114b1', 5], ['13002b1', 5], ['13188b1', 5], ['13328x1', 5], ['13502d1', 5], ['13630j1', 7], ['14123c1', 7], ['14577b1', 7], ['14706b1', 5], ['15246h1', 13], ['15575e1', 13], ['15834b1', 5], ['16224n1', 17], ['16491e1', 7], ['16577g1', 5], ['16880r1', 7], ['16936a1', 5], ['17157c1', 5], ['17507k1', 5], ['17584c1', 5], ['17898b1', 5], ['19043a1', 11], ['19431a1', 5], ['19620m1', 7]]
Why is it that when I now do len(pairing), I get the following error:
TypeError: object of type 'NoneType' has no len()
Because you are not returning anything from your function.
Try changing
print ans
to
return ans
Or, if you want to keep the print statement, put return ans below it.

how to connect selected points in scatter plot in google api

I'm using scatter plot for my application, so I selected google API for scatter charts. For my application I need to connect some points with line marker. I followed this
link for test. please help me to improve.
If you need to connect points on your ScatterChart, you can do so by setting either the lineWidth option (creates lines connecting points for all data series) or the series.<series index>.lineWidth option (which creates lines connecting the points of a single series). Here are some examples:
Use the lineWidth option to connect points in all series (jsfiddle example):
function drawChart () {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
data.addRows([
[0, 2, 5],
[1, 6, 6],
[2, 5, 9],
[3, 6, 5],
[4, 5, 4],
[7, 9, 2],
[8, 4, 6],
[9, 3, 7]
]);
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, {
height: 400,
width: 600,
lineWidth: 1
});
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
Connect all the points in one data series using the series.<series index>.lineWidth option (jsfiddle example):
function drawChart () {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
data.addRows([
[0, 2, 5],
[1, 6, 6],
[2, 5, 9],
[3, 6, 5],
[4, 5, 4],
[7, 9, 2],
[8, 4, 6],
[9, 3, 7]
]);
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, {
height: 400,
width: 600,
series: {
0: {
// connect the points in Y1 with a line
lineWidth: 1
}
}
});
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
If you want to connect only certain points in a data series, you must insert null values between all points that you do not want lines to connect. Here's an example connecting points (2, 5) and (3, 6) in series Y1 (jsfiddle example):
function drawChart () {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
data.addRows([
[0, 2, 5],
[null, null, null],
[1, 6, 6],
[null, null, null],
[2, 5, 9],
[3, 6, 5],
[null, null, null],
[4, 5, 4],
[null, null, null],
[7, 9, 2],
[null, null, null],
[8, 4, 6],
[null, null, null],
[9, 3, 7]
]);
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, {
height: 400,
width: 600,
series: {
0: {
// connect the points in Y1 with a line
lineWidth: 1
}
}
});
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
The important thing to note here is that points which are adjacent in the DataTable will be connected with lines. If you want to connect points which are not adjacent in the chart, you need to re-arrange the data. Here's an example that connects the points (2, 5) and (8, 4) in Y1 and (4, 4) and (8, 6) in Y2 (jsfiddle example):
function drawChart () {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
data.addRows([
[null, null, null],
// Y1 data
// make (2, 5) and (8, 4) adjacent in the DataTable
[2, 5, null],
[8, 4, null],
// split all others with nulls
[null, null, null],
[0, 2, null],
[null, null, null],
[1, 6, null],
[null, null, null],
[3, 6, null],
[null, null, null],
[4, 5, null],
[null, null, null],
[7, 9, null],
[null, null, null],
[9, 3, null],
// Y2 data
// make (4, 4) and (8, 6) adjacent in the DataTable
[4, null, 4],
[8, null, 6],
// split all others with nulls
[null, null, null],
[0, null, 5],
[null, null, null],
[1, null, 6],
[null, null, null],
[2, null, 9],
[null, null, null],
[3, null, 5],
[null, null, null],
[7, null, 2],
[null, null, null],
[9, null, 7]
]);
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, {
height: 400,
width: 600,
series: {
0: {
// connect the points in Y1 with a line
lineWidth: 1
},
1: {
// connect the points in Y2 with a line
lineWidth: 1
}
}
});
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
That should get you started on connecting points with lines in ScatterCharts.