Latex / Tikz: draw a vertical line to a straight line - math

Maybe you can help me, I try to draw a line from a Point/Coordinate to a straight line. I use Tikz to draw.
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (-5,-5){};
\coordinate [label=right:$B$] (B) at (5,-5) {};
\coordinate [label=right:$C$] (C) at (5,1) {};
\coordinate [label=left:$D$] (D) at (-5,1) {};
\draw [thick] (A) -- node[midway] {$\parallel$} (B) -- node[sloped]{$\parallel$} (C) -- (D) -- cycle;
\coordinate (S1) at ($(D)!0.66!(C)$);
\coordinate (S2) at ($(A)!0.11!(B)$);
\draw [very thick] (S1) -- node[above]{x} (S2);
\draw [red!100, thick] (S1) -- node[above]{T} (A -| B );
\end{tikzpicture}
This where the red line should go
the red line should go from coordinate (S1) to the straight line (A -- B) vertically.
I tried it to draw it like this:
\draw [red!100, thick] (S1) -- node[above]{T} (A -| B );
But then he draw a line to coordinate A
Thank you,

You can do that by defining a new coordinate (say S3) for the point on AB:
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (-5,-5){};
\coordinate [label=right:$B$] (B) at (5,-5) {};
\coordinate [label=right:$C$] (C) at (5,1) {};
\coordinate [label=left:$D$] (D) at (-5,1) {};
\draw [thick] (A) -- node[midway] {$\parallel$} (B) -- node[sloped]{$\parallel$} (C) -- (D) -- cycle;
\coordinate (S1) at ($(D)!0.66!(C)$);
\coordinate (S2) at ($(A)!0.11!(B)$);
\coordinate (S3) at ($(A)!0.66!(B)$);
\draw [very thick] (S1) -- node[above]{x} (S2);
\draw [red!100, thick] (S1) -- node[left]{T} (S3);
\end{tikzpicture}

You don't need to define a new coordinate but you can use the projection identifiers from calc library.
In the last line you just need
\draw [red!100, thick] (S1) -- node[left]{T} ($(A)!(S1)!(B)$);
This mean along A--B take the point which S1 is projected onto A--B.

Your syntax is nearly correct, but the tee operators |- and -| take the x coordinate from one side and the y coordinate from other. When you write
A -| B you get the y coordinate of A and the x coordinate of B, but in your code A and B have the same x coordinate so this gives you the point A again. Instead you want A -| S1, or equivalently S1 |- A.
\draw [red!100, thick] (S1) -- node[left]{T} (S1 |- A);
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (-5,-5){};
\coordinate [label=right:$B$] (B) at (5,-5) {};
\coordinate [label=right:$C$] (C) at (5,1) {};
\coordinate [label=left:$D$] (D) at (-5,1) {};
\draw [thick] (A) -- node[midway] {$\parallel$} (B) -- node[sloped]{$\parallel$} (C) -- (D) -- cycle;
\coordinate (S1) at ($(D)!0.66!(C)$);
\coordinate (S2) at ($(A)!0.11!(B)$);
\draw [very thick] (S1) -- node[above]{x} (S2);
\draw [red!100, thick] (S1) -- node[left]{T} (S1 |- A);
\end{tikzpicture}
\end{document}

Related

I do not know how to create this graph with tikz in latex

I tried to create this graph
in latex but I didn't succeed. I tried this code :
\begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (2,0) circle (1.5pt);
\draw[fill=black] (1,3/2) circle (1.5pt);
%% vertex labels
\node at (-0.5,0) {$v_{1}$};
\node at (2.5,0) {$v_{2}$};
\node at (1,3.8/2) {$v_{3}$};
%%% edges
\draw[thick] (0,0) -- (2,0) -- (0,0) -- (1,3/2) -- (2,0) -- (1,3/2);
\end{tikzpicture}
You are definitely on the right way. What I suggest, is that you build a table which is containing your 8 slightly different Tikz graphics.
-------------------------------------
| graph1 | graph2 | graph3 | graph4 |
| text1 | text 2 | text3 | text4 |
-------------------------------------
| graph5 | graph6 | graph7 | graph8 |
| text5 | text 6 | text7 | text8 |
-------------------------------------
caption
In total you are going to have a 4 by 4 table with 3 horizontal lines (\hline)
It could be similiar to this:
---------------------- UPDATED SOLUTION:------------------------------
\begin{table}
\setlength{\tabcolsep}{1mm} % separator between columns
\def\arraystretch{1.0} % vertical stretch factor
\centering
\begin{tabular}{|c|c|c|c|}
\hline
\begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
\end{tikzpicture}
& \begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
%%% edges
\draw[thick] (3/2,0) -- (0.75,1.2);
\end{tikzpicture}
& \begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
%%% edges
\draw[thick] (0,0) -- (3/2,0) ;
\end{tikzpicture}
& \begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
%%% edges
\draw[thick] (0,0) -- (0.75,1.2);
\end{tikzpicture}
\\ \( (1-p)^3\) & \( p(1-p)^2\) & \( p(1-p)^2\) & \( p(1-p)^2\)
\\ \hline
\begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
%%% edges
\draw[thick] (0,0) -- (3/2,0) -- (0,0) -- (0.75,1.2);
\end{tikzpicture}
& \begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
%%% edges
\draw[thick] (0,0) -- (0.75,1.2) -- (3/2,0) -- (0.75,1.2);
\end{tikzpicture}
& \begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
%%% edges
\draw[thick] (0,0) -- (3/2,0) -- (0.75,1.2);
\end{tikzpicture}
& \begin{tikzpicture}
%% vertices
\draw[fill=black] (0,0) circle (1.5pt);
\draw[fill=black] (3/2,0) circle (1.5pt);
\draw[fill=black] (0.75,1.2) circle (1.5pt);
%% vertex labels
\node at (-0.2,-0.3) {$v_{3}$};
\node at (1.7,-0.3) {$v_{2}$};
\node at (0.75,1.5) {$v_{1}$};
%%% edges
\draw[thick] (0,0) -- (3/2,0) -- (0,0) -- (0.75,1.2) -- (3/2,0) -- (0.75,1.2);
\end{tikzpicture}
\\ \( p^2(1-p)\) & \( p^2(1-p)\) & \( p^2(1-p)\) & \( p^3\)
\\ \hline
\end{tabular}
\caption{$L'espace\,\,de\,\,probabilit\acute{e}\,\,G_{3,p}$}
\end{table}
A table as in the other answer works well with or without borders but, if you can avoid the borders, you may consider using scopes to position accordingly:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=.9]
\begin{scope}[border=5mm]
%\draw (0,0) -- (1,2) -- (2,0) -- (0,0);
\draw[fill=white] %
(1,2) circle (3pt) node[above] {$v_1$}
(2,0) circle (3pt) node[below right] {$v_2$}
(0,0) circle (3pt) node[below left] {$v_3$};
\node at (1,-.8) {text 1};
\end{scope}
%
\begin{scope}[xshift=40mm]
\draw %(0,0) --
(1,2) -- (2,0);% -- (0,0);
\draw[fill=white] %
(1,2) circle (3pt) node[above] {$v_1$}
(2,0) circle (3pt) node[below right] {$v_2$}
(0,0) circle (3pt) node[below left] {$v_3$};
\node at (1,-.8) {text 2};
\end{scope}
%
% ...
%
\begin{scope}[xshift=40mm,yshift=-40mm]
\draw (0,0) -- (1,2) -- (2,0);% -- (0,0);
\draw[fill=white] %
(1,2) circle (3pt) node[above] {$v_1$}
(2,0) circle (3pt) node[below right] {$v_2$}
(0,0) circle (3pt) node[below left] {$v_3$};
\node at (1,-.8) {text 6};
\end{scope}
%
% ...
%
\end{tikzpicture}
\end{document}

How to draw diagonal edges in Graphviz

How can I draw diagonal lines between two nodes in Graphviz (Dot Language).
I want to draw the following shape.
I tried:
graph G {
V[pos="0,0"];
N[pos="40,40!"];
V -- N [label="NSUBJ"]
}
But it draws orthogonal lines. besides I want to draw multiple subgraphs with an order number as above!
It's possible to use pos attribute, but in that case you'd have to use neato and set pos for every node:
graph G {
V [pos = "0,100"]
N [pos = "50,0"]
S [pos = "200,100"]
VPC [pos = "150,0"]
NPC [pos = "250,0"]
V -- N [label="NSUBJ"]
S -- VPC
S -- NPC
}
Then use the following:
neato -n -Tpng -o test.png test.gv
The output is the following:
Also it's possible to make lines diagonal if use invisible nodes:
graph G {
node [shape=plaintext]
labelloc="b"
pencolor=transparent
subgraph cluster_1 {
label="(1)"
S_1 [label="S"]
VPC_1 [label="VPC"]
NPC_1 [label="NPC"]
V_1 [label="V"]
invis_1 [style=invis]
N_1 [label="N"]
V_1 -- invis_1 [style=invis]
V_1 -- N_1 [label="NSUBJ"]
S_1 -- VPC_1
S_1 -- NPC_1
}
subgraph cluster_2 {
label="(2)"
VPC_2 [label="VPC"]
V_2_2 [label="V"]
NPC_2 [label="NPC"]
V_2 [label="V"]
invis_2 [style=invis]
N_2 [label="N"]
V_2 -- invis_2 [style=invis]
V_2 -- N_2 [label="COPCOMP"]
VPC_2 -- V_2_2
VPC_2 -- NPC_2
}
}
Running this sequence of commands produces the following output:
ccomps -Cx test.gv | dot | gvpack -array_1 | neato -n2 -Tpng > test.png

Drawing a line segment on a space that wraps toroidally

I have a 2D space of angles [0, 2pi] x [0, 2pi] which wraps around, with toroid like topology (the horizontal edges correspond to each other, as do the vertical ones). I have two points in this space, and I would like to draw a line segment between those two points.
In some cases, this line segment is the obvious line segment, from one point to the other. In other cases, the line segment is supposed to "go around the edge" instead of going "the long way, through the middle":
+--------+
| |
| A--B |
| |
+--------+
+--------+
| |
|-A B-|
| |
+--------+
While these cases are moderately easy to handle, there is one case that is really vexing for me and which my code so far does not handle correctly:
+-----------+
| / |
| B |
| |
| A /|
| / / |
+-----------+
I.e. if the line wraps around both directions, it sometimes wraps around the opposite corner. I'm not entirely sure if there are more of these tricky cases.
The only algorithm I've come up that works reliably so far is to calculate the midpoint as (A + B) / 2 while making appropriate use of the modulo arithmetics, draw a dot at this position, and then recursively subdivide the left and right intervals similarly, until the distance between the dots is less than a single pixel. Obviously, this is not going to be very fast.
My other approach was to detect (separately for x and y) whether the short distance is direct or around the edge, and then either draw one line segment or two. This does not handle the third case correctly, unless the line is divided in two and the midpoint lies on the segment that is in the lower-right corner in the example image. I'm not sure how to detect this efficiently, or how to calculate the position of the midpoint, as simply the point in the half does not always work, it might end up at the edge together with one of the endpoints, if their respective distance from the edge is not equal.
Is there a better algorithm? Is there an obvious solution that I'm not seeing? I'm not even sure how to google for this problem. I don't want to implement my own line rasterization algorithm, I would just like to break this problem to Euclidean straight lines and draw these using OpenGL or GDI or whatever.
My code so far is:
void Draw_WrappedSegment(float f_x0, float f_y0, float f_x1, float f_y1)
{
const float s = 2 * f_pi;
f_x0 = fmod(fmod(f_x0, s) + s, s);
f_y0 = fmod(fmod(f_y0, s) + s, s);
f_x1 = fmod(fmod(f_x1, s) + s, s);
f_y1 = fmod(fmod(f_y1, s) + s, s);
// make sure the coordinates end up being positive and modulo 2pi
float f_ydist0 = fabs(f_y0 - f_y1);
float f_ydist1 = fabs(fmod(f_y0 + s - f_y1, s));
float f_ydist2 = fabs(fmod(f_y1 - f_y0 + s, s));
float f_xdist0 = fabs(f_x0 - f_x1);
float f_xdist1 = fabs(fmod(f_x0 + s - f_x1, s));
float f_xdist2 = fabs(fmod(f_x1 - f_x0 + s, s));
// 0 2pi 4pi
//p1'' | p0 p1 | p0' p1' |
// <---f_dist0--->
// <-f_dist1->
// <-f_dist2->
const float f_epsilon = 1e-3f; // sometimes the modulo causes an error and even though the díst 0 and dist 2 should equal, dist 2 is slightly smaller
if(f_xdist0 <= f_xdist1 + f_epsilon && f_xdist0 <= f_xdist2 + f_epsilon) {
if(f_ydist0 <= f_ydist1 + f_epsilon && f_ydist0 <= f_ydist2 + f_epsilon) {
MoveTo(f_x0, f_y0);
LineTo(f_x1, f_y1); // the "short" way in both directions
} else {
float f_sign = (f_y0 < f_y1)? 1 : -1; // swap the lower and upper edge if the points are not sorted by y
MoveTo(f_x0, f_y0);
LineTo(f_x1, f_y1 - f_sign * s); // from point 0 to the lower edge
MoveTo(f_x1, f_y1);
LineTo(f_x0, f_y0 + f_sign * s); // from point 1 to the upper edge
}
} else {
if(f_ydist0 <= f_ydist1 + f_epsilon && f_ydist0 <= f_ydist2 + f_epsilon) {
float f_sign = (f_x0 < f_x1)? 1 : -1; // swap the left and right edge if the points are not sorted by x
MoveTo(f_x0, f_y0);
LineTo(f_x1 - f_sign * s, f_y1); // from point 0 to the left edge
MoveTo(f_x1, f_y1);
LineTo(f_x0 + f_sign * s, f_y0); // from point 1 to the right edge
} else {
float f_sign_x = (f_x0 < f_x1)? 1 : -1; // swap the left and right edge if the points are not sorted by x
float f_sign_y = (f_y0 < f_y1)? 1 : -1; // swap the lower and upper edge if the points are not sorted by y
MoveTo(f_x0, f_y0);
LineTo(f_x1 - f_sign_x * s, f_y1 - f_sign_y * s); // from point 0 to one edge
MoveTo(f_x1, f_y1);
LineTo(f_x0 + f_sign_x * s, f_y0 + f_sign_y * s); // from point 1 to the other edge
}
}
}
Instead of working with just the square [0, 2pi] x [0, 2pi], try tiling the space [-2pi,4pi] x [-2pi,4pi] with nine copies of this square (like a tic-tac-toe board). Place A in the center square, and then place copies of B (translating the coordinates by ±2pi as required ) in each of the nine squares. Choose the copy of B that is closest to A, and then draw the line from A to that copy of B. This line may have more than one segment as it travels through the squares. Just "untranslate" these segments back to the central square and you will have the diagram you want.

Interpolate point within a 3d triangle to a point within a 2d triangle

Could someone give me the algorithm to solve this:
Given a 3D Triangle (p0, p1, p2) and a 3D point inside/on this triangle (px) and a 2D Triangle (p0', p1', p2'), the function will return a 2D point such that:
if px == p0 then return p0'
if px == p1 then return p1'
if px == p2 then return p2'
and everything in between.
Basically, you want to project a 3D point to a 2D matrix, right?
There's many resources for that (check Wikipedia here http://en.wikipedia.org/wiki/3D_projection) but this one http://www.flipcode.com/archives/Plotting_A_3D_Point_On_A_2D_Screen.shtml is a nice introduction!
Edit: also this recent article is a very understandable introduction http://creativejs.com/2012/01/day-12-3d-pixel-particles/
I understand. Any point px on the plane of (p0,p1,p2) can represented by the BaryCentric coordinates a0,a1,a2 such that px = a0*p0 + a1*p1 + a2*p2 in all coordinates. If you know the values for a0,a1,a2 then you can apply them to (p0',p1',p2') in order to find px' = a0*p0' + a1*p1' + a2*p2'.
To get the BaryCentric coordinates you need to solve a 3x3 system of linear equations
| px[0] | | p0[0] p1[0] p2[0] | | a[0] |
| px[1] | = | p0[1] p1[1] p2[1] | | a[1] |
| px[2] | | p0[2] p1[2] p2[1] | | a[2] |
In C the solution is
d = p0[0]*p1[1]*p2[2]-p0[0]*p1[2]*p2[1]-p0[1]*p1[0]*p2[2]+p0[1]*p1[2]*p2[0]+p0[2]*p1[0]*p2[1]-p0[2]*p1[1]*p2[0];
a0 = (p1[0]*p2[1]*px[2]-p1[0]*p2[2]*px[1]-p1[1]*p2[0]*px[2]+p1[1]*p2[2]*px[0]+p1[2]*p2[0]*px[1]-p1[2]*p2[1]*px[0])/d;
a1 = -(p0[0]*p2[1]*px[2]-p0[0]*p2[2]*px[1]-p0[1]*p2[0]*px[2]+p0[1]*p2[2]*px[0]+p0[2]*p2[0]*px[1]-p0[2]*p2[1]*px[0])/d;
a2 = (p0[0]*p1[1]*px[2]-p0[0]*p1[2]*px[1]-p0[1]*p1[0]*px[2]+p0[1]*p1[2]*px[0]+p0[2]*p1[0]*px[1]-p0[2]*p1[1]*px[0])/d;
With the coordinates for the 2D point as:
px'[0] = a0*p0'[0] + a1*p1'[0] + a2*p2'[0]
px'[1] = a0*p0'[1] + a1*p1'[1] + a2*p2'[1]
px'[2] = a0*p0'[2] + a1*p1'[2] + a2*p2'[2]

Tower of Hanoi using recursion

I have no idea about Tower of Hanoi. I want to write a program on this using recursion.
Another homework assignment. Pass your teacher's A to me ;)
Source: http://www.soc.napier.ac.uk/~andrew/hanoi/rechelp.html
Bonus: a step-by-step YouTube video.
A little bit about the Tower of Hanoi
An analysis of this and a discussion of the (invented) mythology and of the four peg version can be found in the rec.puzzles FAQ look for induction/hanoi.s
The Tower of Hanoi problem has a nice recursive solution.
Working out recursive solutions
To solve such problems ask yourself: "if I had solved the n-1 case could I solve the n case?"
If the answer to this question is positive you proceed under the outrageous assumption that the n-1 case has been solved. Oddly enough this works, so long as there is some base case (often when n is zero or one) which can be treated as a special case.
How to move n rings from pole A to pole C?
If you know how to move n-1 rings from one pole to another then simply move n-1 rings to the spare pole - there is only one ring left on the source pole now, simply move it to the destination, then pile the rest of them from the spare pole onto the destination pole.
For example when n is 4...
First move three onto the spare pole (worry how to do this later).
Now move one ring from the source pole to the destination pole.
Now move three rings from the spare pole to the destination pole
(again, we can worry about how to do this later).
We have finished!
More succinctly...
To move n rings from A to C using B as spare:
if n is 1
just do it,
otherwise...
move n-1 rings from A to B using C as spare
move one ring from A to C
move n-1 rings from B to C using A as spare
As with most recursive solutions we have to treat some base case specially - here the base case occurs where we have only one ring to move.
How to do it in C
/* Tower of Hanoi - the answer */
/* How to move four rings from pin 1 to pin 3 using pin 2 as spare */
#include <stdio.h>
void move(n, A, C, B)
/* number to move, source pole, destination pole and
spare pole respectively */
int n, A, B, C; {
if (n == 1) {
printf("Move from %d to %d.\n", A, C);
} else {
move(n - 1, A, B, C);
move(1, A, C, B);
move(n - 1, B, C, A);
}
}
main() {
move(4, 1, 3, 2);
}
Here is a compact implementation in Lisp: http://www.kernelthread.com/projects/hanoi/html/gcl.html. It is certainly recursive, but I did not verify it's correctness.
From Wikipedia:
The Tower of Hanoi or Towers of Hanoi
(also known as The Towers of Brahma)
is a mathematical game or puzzle. It
consists of three rods, and a number
of disks of different sizes which can
slide onto any rod. The puzzle starts
with the disks neatly stacked in order
of size on one rod, the smallest at
the top, thus making a conical shape.
Check out the recursive solution.
#!/usr/bin/env python
discs = 3
T = [range(discs, 0, -1), [], []]
def show_towers():
"""Render a picture of the current state of the towers"""
def render_disc(t, y):
return ("-"*(t[y]*2-1) if y < len(t) else "|").center(discs*2)
for y in range(discs):
print " ".join(render_disc(t, discs-y-1) for t in T)
print "="*(discs*6+3)
def move(n, source, destination):
"""Recursively move n discs from source to destination"""
while n > 0:
temp = 3 - source - destination
move(n-1, source, temp)
T[destination].append(T[source].pop())
show_towers()
n, source = n-1, temp # Simulate tail recursion
show_towers()
move(discs, 0, 2)
output for discs = 3
- | |
--- | |
----- | |
=====================
| | |
--- | |
----- | -
=====================
| | |
| | |
----- --- -
=====================
| | |
| - |
----- --- |
=====================
| | |
| - |
| --- -----
=====================
| | |
| | |
- --- -----
=====================
| | |
| | ---
- | -----
=====================
| | -
| | ---
| | -----
=====================
The Structure and Interpretation of Computer Programs video lectures contain helpful tips on solving this problem and a wealth of knowledge besides.
See wikipedia towers of hanoi article for the description of recursive algorithm.
It goes something like this:
#include <iostream> // ostream
#include <algorithm> // for_each
#include <deque> // I can iterate over towers & print state,<stack> works as well
#include <boost/array.hpp> // just a wrapper for array
#include <boost/lambda/lambda.hpp> // easy one line for_each iterating
using namespace std;
typedef std::deque< int > tower_t; // stack works as well, deque for printing
typedef boost::array< tower_t ,3 > towers_t; // 3 towers
enum peg { A = 0, B = 1, C = 2 };
Printing:
ostream & show(ostream & os, const tower_t & t)
{
os << "[";
for_each (t.begin(), t.end(), os << boost::lambda::_1 );
return os << "]";
}
ostream & show(ostream & os, const towers_t & t)
{
show(os, t[0]); show(os, t[1]); show(os, t[2]);
return os;
}
Solve:
void move(peg from, peg to, towers_t & t)
{
// show move and state before move
cout << "mv: " << t[from].back() << " " << from << " --> " << to << "\t\t";
show(cout, t); cout << " --> ";
// the actual move: move top peg `from` stick `to` stick (and `pop` old top)
t[to].push_back(t[from].back());
t[from].pop_back();
// show state after move
show(cout, t); cout << endl;
}
// move n discs from A to B via C
void move(int n, peg from, peg to, peg via, towers_t & t)
{
if (n == 1) { move(from, to, t); return; }
move(n-1, from, via, to, t);
move(from, to, t);
move(n-1, via, to, from, t);
return;
}
Usage, solve tower with 4 pegs:
int main()
{
towers_t ttt;
tower_t & first_tower(ttt[0]);
first_tower.push_back(4);
first_tower.push_back(3);
first_tower.push_back(2);
first_tower.push_back(1);
move(first_tower.size(), A, C, B, ttt); // move n from A to C via B
}
Solved 3 towers with 4 pegs on the first tower, the biggest peg has the highest number, the smallest one is 1.
Output (mv: PegX FromTower ---> ToTower) followed by state before and after move, each tower from left to right showing pegs from bottom to top - top is on right:
mv: 1 0 --> 1 [4321][][] --> [432][1][]
mv: 2 0 --> 2 [432][1][] --> [43][1][2]
mv: 1 1 --> 2 [43][1][2] --> [43][][21]
mv: 3 0 --> 1 [43][][21] --> [4][3][21]
mv: 1 2 --> 0 [4][3][21] --> [41][3][2]
mv: 2 2 --> 1 [41][3][2] --> [41][32][]
mv: 1 0 --> 1 [41][32][] --> [4][321][]
mv: 4 0 --> 2 [4][321][] --> [][321][4]
mv: 1 1 --> 2 [][321][4] --> [][32][41]
mv: 2 1 --> 0 [][32][41] --> [2][3][41]
mv: 1 2 --> 0 [2][3][41] --> [21][3][4]
mv: 3 1 --> 2 [21][3][4] --> [21][][43]
mv: 1 0 --> 1 [21][][43] --> [2][1][43]
mv: 2 0 --> 2 [2][1][43] --> [][1][432]
mv: 1 1 --> 2 [][1][432] --> [][][4321]

Resources