Skip to content

Instantly share code, notes, and snippets.

@bradclawsie
Last active October 21, 2019 20:20
Show Gist options
  • Save bradclawsie/c157b2e98c1aee743ff2183eb1d95645 to your computer and use it in GitHub Desktop.
Save bradclawsie/c157b2e98c1aee743ff2183eb1d95645 to your computer and use it in GitHub Desktop.
tcc
package main
// run this: https://play.golang.org/p/lGEbAcNeVJr
import (
"fmt"
"log"
)
const (
Left = iota
Right
)
type direction int
type move struct {
Direction direction
Letter *string
}
func rotateLeft(letters []string, pos int) ([]move, []string) {
letter := letters[pos]
moves := make([]move, pos+1)
for i := 0; i < pos; i++ {
first := letters[0]
for j := 1; j < len(letters); j++ {
letters[j-1] = letters[j]
}
letters[len(letters)-1] = first
moves[i] = move{Direction: Left}
}
moves[pos] = move{Direction: Left, Letter: &letter}
return moves, letters[1:]
}
func rotateRight(letters []string, pos int) ([]move, []string) {
letter := letters[pos]
moves := make([]move, len(letters)-pos)
k := 0
for i := len(letters) - 1; i > pos; i-- {
last := letters[len(letters)-1]
for j := len(letters) - 2; j >= 0; j-- {
letters[j+1] = letters[j]
}
letters[0] = last
moves[k] = move{Direction: Right}
k++
}
moves[k] = move{Direction: Right, Letter: &letter}
return moves, letters[:len(letters)-1]
}
func findPos(letters []string, pat string) (direction, int, error) {
left := 0
right := len(letters) - 1
for left <= right {
if letters[left] == pat {
return Left, left, nil
}
if letters[right] == pat {
return Right, right, nil
}
left++
right--
}
return -1, -1, fmt.Errorf("%s not found", pat)
}
func printMoves(moves []move) {
for _, move := range moves {
if move.Direction == Left {
fmt.Printf("LEFT: ")
} else {
fmt.Printf("RIGHT: ")
}
if move.Letter != nil {
fmt.Printf(" %s\n", *move.Letter)
} else {
fmt.Printf(" nil\n")
}
}
}
func playGame(in []string, pat []string) ([]move, []string, error) {
board := make([]string, len(in))
copy(board, in)
moves := make([]move, 0)
for _, p := range pat {
//fmt.Printf("current board: %v\n", board)
dir, pos, err := findPos(board, p)
if err != nil {
return nil, nil, err
}
var turnMoves []move
if dir == Left {
turnMoves, board = rotateLeft(board, pos)
moves = append(moves, turnMoves...)
} else {
turnMoves, board = rotateRight(board, pos)
moves = append(moves, turnMoves...)
}
}
return moves, board, nil
}
func main() {
in := []string{"a", "z", "c", "t", "v", "b"}
pat := []string{"z", "b"}
fmt.Printf("input board: %v, pat: %v\n", in, pat)
moves, board, err := playGame(in, pat)
if err != nil {
log.Fatal(err)
}
printMoves(moves)
fmt.Printf("post-play working board %v\n", board)
in = []string{"a", "z", "c", "t", "v", "b"}
pat = []string{"c", "t"}
fmt.Printf("\ninput board: %v, pat: %v\n", in, pat)
moves, board, err = playGame(in, pat)
if err != nil {
log.Fatal(err)
}
printMoves(moves)
fmt.Printf("post-play working board %v\n", board)
in = []string{"a", "z", "c", "t", "v", "a"}
pat = []string{"c", "a", "t"}
fmt.Printf("\ninput board: %v, pat: %v\n", in, pat)
moves, board, err = playGame(in, pat)
if err != nil {
log.Fatal(err)
}
printMoves(moves)
fmt.Printf("post-play working board %v\n", board)
in = []string{"a", "z", "c", "t", "v", "a"}
pat = []string{"t", "v"}
fmt.Printf("\ninput board: %v, pat: %v\n", in, pat)
moves, board, err = playGame(in, pat)
if err != nil {
log.Fatal(err)
}
printMoves(moves)
fmt.Printf("post-play working board %v\n", board)
in = []string{"a"}
pat = []string{"a"}
fmt.Printf("\ninput board: %v, pat: %v\n", in, pat)
moves, board, err = playGame(in, pat)
if err != nil {
log.Fatal(err)
}
printMoves(moves)
fmt.Printf("post-play working board %v\n", board)
in = []string{"a"}
pat = []string{"b"}
fmt.Printf("\ninput board: %v, pat: %v\n", in, pat)
moves, board, err = playGame(in, pat)
if err == nil {
log.Fatal("should not be found")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment