package main

import "fmt"

//Prints the complete cayley table for the symmetric group S3
func main() {
	//Define S3
	type trans func([]int) []int
	e := func(x []int) []int {
		y := make([]int, 3)
		copy(y, x)
		return y
	}
	a := func(x []int) []int {
		y := make([]int, 3)
		copy(y, x)
		y[0], y[1] = y[1], y[0]
		return y
	}
	b := func(x []int) []int {
		y := make([]int, 3)
		copy(y, x)
		y[1], y[2] = y[2], y[1]
		return y
	}
	ab := func(x []int) []int { return a(b(x)) }
	ba := func(x []int) []int { return b(a(x)) }
	aba := func(x []int) []int { return a(b(a(x))) }

	s3 := []trans{e, a, b, ab, ba, aba}

	//Provides an easy way to print an element's name when applied to [1,2,3]
	tree := map[int]map[int]string{
		1: map[int]string{2: "e", 3: "b"},
		2: map[int]string{1: "a", 3: "ba"},
		3: map[int]string{1: "ab", 2: "aba"},
	}
	name := func(x []int) string { return tree[x[0]][x[1]] }

	//Print cayley table
	x := []int{1, 2, 3}
	for _, elem1 := range s3 {
		for _, elem2 := range s3 {
			p := elem1(x)
			q := elem2(x)
			r := elem1(q)
			fmt.Println(name(p), "*", name(q), "=", name(r))
		}
	}
}
