package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

func main() {
	input := stdinToStringSlice()
	var press []rune
	keypad := initKeypad("diamond")
	pos := '5'
	for _, i := range input {
		for _, j := range i {
			pos = moveFinger(j, pos, keypad)
		}
		press = append(press, pos)
	}
	fmt.Println("Code: ", string(press))
}

func moveFinger(dir rune, start rune, keypad map[string]rune) rune {
	// Find the starting button
	var startX, startY int
	for k, v := range keypad {
		if v == start {
			// Found it
			strCoords := strings.Split(k, ";")
			startY = atoi(strCoords[0])
			startX = atoi(strCoords[1])
		}
	}
	switch dir {
	case 'U':
		newY := startY - 1
		if keypad[itoa(newY)+";"+itoa(startX)] != 0 {
			return keypad[itoa(newY)+";"+itoa(startX)]
		}
	case 'R':
		newX := startX + 1
		if keypad[itoa(startY)+";"+itoa(newX)] != 0 {
			return keypad[itoa(startY)+";"+itoa(newX)]
		}
	case 'D':
		newY := startY + 1
		if keypad[itoa(newY)+";"+itoa(startX)] != 0 {
			return keypad[itoa(newY)+";"+itoa(startX)]
		}
	case 'L':
		newX := startX - 1
		if keypad[itoa(startY)+";"+itoa(newX)] != 0 {
			return keypad[itoa(startY)+";"+itoa(newX)]
		}
	}
	return start
}

func initKeypad(tp string) map[string]rune {
	ret := make(map[string]rune)
	switch tp {
	case "diamond":
		ret["0;2"] = '1'
		ret["1;1"] = '2'
		ret["1;2"] = '3'
		ret["1;3"] = '4'
		ret["2;0"] = '5'
		ret["2;1"] = '6'
		ret["2;2"] = '7'
		ret["2;3"] = '8'
		ret["2;4"] = '9'
		ret["3;1"] = 'A'
		ret["3;2"] = 'B'
		ret["3;3"] = 'C'
		ret["4;2"] = 'D'
	case "square":
		currKey := 1
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				ret[itoa(i)+";"+itoa(j)] = rune(currKey)
				currKey++
			}
		}
	}
	return ret
}

func itoa(i int) string {
	return strconv.Itoa(i)
}

func atoi(i string) int {
	var ret int
	var err error
	if ret, err = strconv.Atoi(i); err != nil {
		log.Fatal("Invalid Atoi")
	}
	return ret
}

func stdinToStringSlice() []string {
	var input []string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = append(input, scanner.Text())
	}
	return input
}
