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 Rust (judge verdict: Accepted)

extern crate core;

use std::fmt;
use std::cmp::{Ordering, min, max};
use std::f32::MAX;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut, SubAssign};
use std::collections::{BTreeMap, VecDeque, BinaryHeap, BTreeSet};
use std::fmt::{Display, Formatter, Error};
use std::env::join_paths;

fn show<T: Display>(vec: &Vec<T>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        print!("[{}", vec[0]);
        for i in 1 .. vec.len() {
            print!(", {}", vec[i]);
        }
        println!("]");
    }
}
fn show2<T: Display>(vec: &Vec<Vec<T>>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        for l in vec {
            show(l);
        }
    }
}
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! read_value{
    () => {
        read_line!().trim().parse().ok().unwrap()
    }
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
macro_rules! let_mut_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let mut $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
fn min_step(history: &Vec<i32>, current: usize, prev_is_left: bool, left_pos: i32, right_pos: i32, memo: &mut Vec<Vec<Vec<Vec<i32>>>>) -> i32 {
    if current == history.len() {
        0
    }else if memo[current][if prev_is_left {0}else {1}][left_pos as usize][right_pos as usize] >= 0{
        memo[current][if prev_is_left{0}else {1}][left_pos as usize][right_pos as usize]
    }else {
        let left = if history[current] % 3 <= right_pos {min_step(history, current + 1, true, history[current] % 3, right_pos, memo) + if prev_is_left {1}else {0}} else {std::i32::MAX};
        let right = if history[current] % 3 >= left_pos {min_step(history, current + 1, false, left_pos, history[current] % 3, memo) + if prev_is_left {0}else {1}} else {std::i32::MAX};
        memo[current][if prev_is_left{0}else {1}][left_pos as usize][right_pos as usize] = min(left, right);
        min(left, right)
    }
}
fn main() {
    loop {
        let state: String = read_line!().trim().to_string();
        if &state[..] == "#" {
            return
        }
        let state: Vec<_> = state.chars().map(|x|x.to_digit(10).unwrap() as i32 - 1).collect();
        let mut memo = vec![vec![vec![vec![-1; 3]; 3]; 2]; state.len()];
        let from_left = min_step(&state, 0, false, 0, 2, &mut memo);
        let from_right = min_step(&state, 0, true, 0, 2, &mut memo);
        println!("{}", min(from_left, from_right));
    }
}