Problem:
サイコロが以下の図のような向きで置かれている．

ここで使用するサイコロは，この図のように，上側に 1，南側に 2 があるときは，東側に 3 があるものとする．サイコロの向かいあう面の和は必ず 7 なので，見えない面はそれぞれ北側 5，西側 4，下側 6 になっている．

　この初期配置の状態から指示に従ってサイコロを動かしていく．ただし，指示は以下の 6 通りの操作を何回か行うものである．

North，East，South，West の各操作は指示された方向へサイコロを 90 度回転させる．
　Right，Left の 2 つの操作は上下の面はそのままで水平方向に 90 度回転させる．（回転させる向きに要注意．）

　初期配置で上の面に出ている目 1 を初期値とし， 1 回の操作が終わるたびに，上の面に出ている目の数を加算していき，指示にしたがってすべての操作を終えたときの合計値を出力するプログラムを作成しなさい.

　入力ファイルの 1 行目には総指示回数 n が書かれていて，続く n 行の各行には「North，East，South，West，Right，Left」のいずれか 1 つの指示が書かれているものとする．ただし， n ≦ 10000 とする．

入力例１

入力例２

5

8

North

West

North

North

East

Left

South

South

West

Right

North

Left

East

　

出力例１

出力例２

21

34

入力

入力は複数のデータセットからなる．n が 0 のとき入力が終了する．データセットの数は 5 を超えない．

出力

データセットごとに、合計値を１行に出力する．

入力例

5
North
North
East
South
West
8
West
North
Left
South
Right
North
Left
East
0

出力例

21
34

各データセットの出力（合計値）の後に改行を入れること。

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in Rust (judge verdict: Accepted)

use std::io::prelude::*;
use std::io;

#[derive(PartialEq)]
enum Direction {
  TOP,
  BOTTOM,
  NORTH,
  EAST,
  SOUTH,
  WEST,
}

struct Dice {
  one_d: Direction,
  two_d: Direction,
  three_d: Direction,
}

use Direction::*;
impl Dice {

  fn new() -> Dice {
    Dice { one_d: TOP, two_d: SOUTH, three_d: EAST }
  }
  
  fn top(&self) -> u32 {
    if self.one_d == TOP {
      1
    } else if self.one_d == BOTTOM {
      6
    } else if self.two_d == TOP {
      2
    } else if self.two_d == BOTTOM {
      5
    } else if self.three_d == TOP {
      3
    } else if self.three_d == BOTTOM {
      4
    } else {
      unreachable!()
    }
  }

  fn north(&mut self) {
    self.one_d = Dice::north_roll(&self.one_d);
    self.two_d = Dice::north_roll(&self.two_d);
    self.three_d = Dice::north_roll(&self.three_d);
  }
  
  fn north_roll(d: &Direction) -> Direction {
    match *d {
      TOP => NORTH,
      BOTTOM => SOUTH,
      NORTH => BOTTOM,
      EAST => EAST,
      SOUTH => TOP,
      WEST => WEST,
    }
  }
  
  fn east(&mut self) {
    self.one_d = Dice::east_roll(&self.one_d);
    self.two_d = Dice::east_roll(&self.two_d); 
    self.three_d = Dice::east_roll(&self.three_d);
  }
  
  fn east_roll(d: &Direction) -> Direction {
    match *d {
      TOP => EAST,
      BOTTOM => WEST,
      NORTH => NORTH,
      EAST => BOTTOM,
      SOUTH => SOUTH,
      WEST => TOP,
    }
  }

  fn south(&mut self) {
    self.one_d = Dice::south_roll(&self.one_d);
    self.two_d = Dice::south_roll(&self.two_d);
    self.three_d = Dice::south_roll(&self.three_d);
  }
  
  fn south_roll(d: &Direction) -> Direction {
    match *d {
      TOP => SOUTH,
      BOTTOM => NORTH,
      NORTH => TOP,
      EAST => EAST,
      SOUTH => BOTTOM,
      WEST => WEST,
    }
  }
  
  fn west(&mut self) {
    self.one_d = Dice::west_roll(&self.one_d);
    self.two_d = Dice::west_roll(&self.two_d);
    self.three_d = Dice::west_roll(&self.three_d);
  }
  
  fn west_roll(d: &Direction) -> Direction {
    match *d {
      TOP => WEST,
      BOTTOM => EAST,
      NORTH => NORTH,
      EAST => TOP,
      SOUTH => SOUTH,
      WEST => BOTTOM,
    }
  }

  fn right(&mut self) {
      self.one_d = Dice::right_roll(&self.one_d);
      self.two_d = Dice::right_roll(&self.two_d);
      self.three_d = Dice::right_roll(&self.three_d);
  }

  fn right_roll(d: &Direction) -> Direction {
    match *d {
      TOP => TOP,
      BOTTOM => BOTTOM,
      NORTH => EAST,
      EAST => SOUTH,
      SOUTH => WEST,
      WEST => NORTH,
    }
  }

  fn left(&mut self) {
      self.one_d = Dice::left_roll(&self.one_d);
      self.two_d = Dice::left_roll(&self.two_d);
      self.three_d = Dice::left_roll(&self.three_d);
  }

  fn left_roll(d: &Direction) -> Direction {
    match *d {
      TOP => TOP,
      BOTTOM => BOTTOM,
      NORTH => WEST,
      EAST => NORTH,
      SOUTH => EAST,
      WEST => SOUTH,
    }
  }
}

fn sum_dice_roll(handle: &mut std::io::StdinLock, times: u32) -> u32 {
  let mut sum: u32 = 0;
  let mut dice = Dice::new();
  sum += dice.top();
  let mut buffer = String::new();

  for _ in 0..times {
    buffer.clear();
    handle.read_line(&mut buffer).unwrap();
    let input = buffer.trim();

    match input {
      "North" => dice.north(),
      "East" => dice.east(),
      "South" => dice.south(),
      "West" => dice.west(),
      "Right" => dice.right(),
      "Left" => dice.left(),
      _ => unreachable!(),
    }

    sum += dice.top();
  }

  sum
}

fn main() {
  let stdin = io::stdin();
  let mut handle = stdin.lock();
  
  loop {
    let mut buffer = String::new();
    handle.read_line(&mut buffer).unwrap();
    let n = buffer.trim().parse::<u32>().unwrap();
    if n == 0 {
      break;
    } else {
      let result = sum_dice_roll(&mut handle, n);
      println!("{}", result);
    }
  }
}