Problem:
Problem B: Step Step Evolution

Japanese video game company has developed the music video game called Step Step Evolution.
The gameplay of Step Step Evolution is very simple. Players stand on the dance platform, and
step on panels on it according to a sequence of arrows shown in the front screen.

There are eight types of direction arrows in the Step Step Evolution: UP, UPPER RIGHT,
RIGHT, LOWER RIGHT, DOWN, LOWER LEFT, LEFT, and UPPER LEFT. These direction
arrows will scroll upward from the bottom of the screen. When the direction arrow overlaps the
stationary arrow nearby the top, then the player must step on the corresponding arrow panel
on the dance platform. The figure below shows how the dance platform looks like.

Figure 1: the dance platform for Step Step Evolution

In the game, you have to obey the following rule:

Except for the beginning of the play, you must not press the arrow panel which is not
correspond to the edit data.

The foot must stay upon the panel where it presses last time, and will not be moved until
it’s going to press the next arrow panel.

The left foot must not step on the panel which locates at right to the panel on which the
right foot rests. Conversely, the right foot must not step on the panel which locates at left
to the panel on which the left foot rests.

As for the third condition, the following figure shows the examples of the valid and invalid
footsteps.

Figure 2: the examples of valid and invalid footsteps

The first one (left foot for LEFT, right foot for DOWN) and the second one (left foot for LOWER
LEFT, right foot for UPPER LEFT) are valid footstep. The last one (left foot for RIGHT, right
foot for DOWN) is invalid footstep.

Note that, at the beginning of the play, the left foot and right foot can be placed anywhere at
the arrow panel. Also, you can start first step with left foot or right foot, whichever you want.

To play this game in a beautiful way, the play style called “ Natural footstep style” is commonly
known among talented players. “Natural footstep style” is the style in which players make steps
by the left foot and the right foot in turn. However, when a sequence of arrows is difficult,
players are sometimes forced to violate this style.

Now, your friend has created an edit data (the original sequence of direction arrows to be pushed)
for you. You are interested in how many times you have to violate “Natural footstep style” when
you optimally played with this edit data. In other words, what is the minimum number of times
you have to step on two consecutive arrows using the same foot?

Input

The input consists of several detasets. Each dataset is specified by one line containing a sequence
of direction arrows. Directions are described by numbers from 1 to 9, except for 5. The figure
below shows the correspondence between numbers and directions.

You may assume that the length of the sequence is between 1 and 100000, inclusive. Also, arrows
of the same direction won’t appear consecutively in the line. The end of the input is indicated
by a single “#”.

Figure 3: the correspondence of the numbers to the direction arrows

Output

For each dataset, output how many times you have to violate “Natural footstep style” when you
play optimally in one line.

Sample Input

1
12
123
369
6748
4247219123
1232123212321232
#

Output for the Sample Input

0
0
1
0
1
2
7

Solution in JAVA (judge verdict: Accepted)

import java.util.*;
import java.io.*;
import java.math.*;

import javax.xml.crypto.Data;

public class Main {
	static PrintWriter out = new PrintWriter(System.out);
	static FastScanner sc = new FastScanner();
	static Scanner stdIn = new Scanner(System.in);
	static int[] vx = new int[] {0,1,0,-1,1,1,-1,-1};
	static int[] vy = new int[] {1,0,-1,0,1,-1,1,-1};
	public static void main(String[] args) {
		while(true) {
			String in = sc.next();
			if(in.equals("#")) break;
			int ca = 10000000;
			int cb = 10000000;
			if(in.length() == 1) {
				out.println(0);
				continue;
			}
			int l = in.charAt(0) - '0';
			int r = in.charAt(1) - '0';
			
			boolean prfisr = true;
			if(check(l) <= check(r)) {
				ca = 0;
			for(int i = 2; i < in.length(); i++) {
				if(prfisr) {
					int tmpl = in.charAt(i) - '0';
					if(check(tmpl) > check(r)) {
						r = tmpl;
						ca++;
					}
					else {
						l = tmpl;
						prfisr = false;
					}
				}
				else {
					int tmpl = in.charAt(i) - '0';
					if(check(tmpl) < check(l)) {
						l = tmpl;
						ca++;
					}
					else {
						r = tmpl;
						prfisr = true;
					}
				}
			}
			}
			l = in.charAt(1) - '0';
			r = in.charAt(0) - '0';
			prfisr = false;
			if(check(l) <= check(r)) {
				cb = 0;
			for(int i = 2; i < in.length(); i++) {
				if(prfisr) {
					int tmpl = in.charAt(i) - '0';
					if(check(tmpl) > check(r)) {
						r = tmpl;
						cb++;
					}
					else {
						l = tmpl;
						prfisr = false;
					}
				}
				else {
					int tmpl = in.charAt(i) - '0';
					if(check(tmpl) < check(l)) {
						l = tmpl;
						cb++;
					}
					else {
						r = tmpl;
						prfisr = true;
					}
				}
			}
			}
			out.println(Math.min(ca,cb));
			
		}
		out.flush();
	}
	static int check(int a) {
		if(a == 7 || a == 4 || a == 1) return 1;
		if(a == 8 || a == 2 || a == 5) return 2;
		if(a == 9 || a == 6 || a == 3) return 3;
		
		return 1000;
	}
}

class MyComp implements Comparator<String> {

	@Override
	public int compare(String o1, String o2) {
		if(o1.length() < o2.length()) {
			return 1;
		}
		else if(o1.length() > o2.length()) {
			return -1;
		}
		return o1.compareTo(o2);
	}
	
}

//-----------------Template------------------//
class FastScanner {
	private final InputStream in = System.in;
	private final byte[] buffer = new byte[1024];
	private int ptr = 0;
	private int buflen = 0;
	private boolean hasNextByte() {
		if (ptr < buflen) {
			return true;
		}else{
			ptr = 0;
			try {
				buflen = in.read(buffer);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (buflen <= 0) {
				return false;
			}
		}
		return true;
	}
	private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	public String next() {
		if (!hasNext()) throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while(isPrintableChar(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}
	public long nextLong() {
		if (!hasNext()) throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b) {
			throw new NumberFormatException();
		}
		while(true){
			if ('0' <= b && b <= '9') {
				n *= 10;
				n += b - '0';
			}else if(b == -1 || !isPrintableChar(b)){
				return minus ? -n : n;
			}else{
				throw new NumberFormatException();
			}
			b = readByte();
		}
	}
	 
	public int nextInt() {
		 if (!hasNext()) throw new NoSuchElementException();
		 int n = 0;
		 boolean minus = false;
		 int b = readByte();
		 if (b == '-') {
			 minus = true;
			 b = readByte();
		 }
		 if (b < '0' || '9' < b) {
			 throw new NumberFormatException();
		 }
		 while(true){
			 if ('0' <= b && b <= '9') {
				 n *= 10;
				 n += b - '0';
			 }else if(b == -1 || !isPrintableChar(b)){
				 return minus ? -n : n;
			 }else{
				 throw new NumberFormatException();
			 }
			 b = readByte();
		 }
	}
	 
	public double nextDouble() {
		return Double.parseDouble(next());
	}
	 
 
}