Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "github.com/skorobogatov/input"
- )
- type Automat struct {
- enter int
- in [][]int
- out [][]string
- color []int
- r []int
- }
- type Pair struct {
- f, s int
- }
- func Union(arrIn []int, a, b int) {
- for i := 0; i < len(arrIn); i++ {
- if arrIn[i] == a {
- arrIn[i] = b
- }
- }
- }
- func Split1(aut *Automat) (l int, arrOut []int) {
- l = len(aut.in)
- lfix := l
- arrOut = make([]int, l)
- for i := 0; i < lfix; i++ {
- arrOut[i] = i
- }
- for i := 0; i < lfix; i++ {
- for j := i + 1; j < lfix; j++ {
- if arrOut[i] != arrOut[j] {
- b := true
- for k := 0; k < len(aut.in[aut.enter]); k++ {
- if aut.out[i][k] != aut.out[j][k] {
- b = false
- break
- }
- }
- if b {
- Union(arrOut, arrOut[i], arrOut[j])
- l--
- }
- }
- }
- }
- return
- }
- func Split(aut *Automat, arrIn []int) (l int, arrOut []int) {
- l = len(aut.in)
- lfix := l
- arrOut = make([]int, l)
- for i := 0; i < l; i++ {
- arrOut[i] = i
- }
- for i := 0; i < lfix; i++ {
- for j := i + 1; j < lfix; j++ {
- if arrIn[i] == arrIn[j] && arrOut[i] != arrOut[j] {
- b := true
- for k := 0; k < len(aut.in[aut.enter]); k++ {
- w1, w2 := aut.in[i][k], aut.in[j][k]
- if arrIn[w1] != arrIn[w2] {
- b = false
- break
- }
- }
- if b {
- Union(arrOut, arrOut[i], arrOut[j])
- l--
- }
- }
- }
- }
- return
- }
- func Search(arr []Pair, a int) (int, bool) {
- for i := 0; i < len(arr); i++ {
- if a == arr[i].f {
- return arr[i].s, true
- }
- }
- return 0, false
- }
- func Aufenkamp_Hohn(aut *Automat) (autMin *Automat) {
- /*for i := 0; i < len(aut.in); i++ {
- for j := 0; j < len(aut.in[i]); j++ {
- fmt.Printf("%d ", aut.in[i][j])
- }
- fmt.Printf("\n")
- }*/
- m, arrOut := Split1(aut)
- /*for i := 0; i < len(arrOut); i++ {
- fmt.Printf("%d ", arrOut[i])
- }
- fmt.Printf("\n")*/
- for {
- m2, arrOut2 := Split(aut, arrOut)
- if m == m2 {
- break
- }
- m, arrOut = m2, arrOut2
- }
- /*for i := 0; i < len(arrOut); i++ {
- fmt.Printf("%d ", arrOut[i])
- }
- fmt.Printf("\n")*/
- var arr []Pair
- var p Pair
- for i, v := range arrOut {
- u, b := Search(arr, v)
- if b {
- arrOut[i] = u
- } else {
- arrOut[i] = len(arr)
- p.f = v
- p.s = len(arr)
- arr = append(arr, p)
- }
- }
- /*for i := 0; i < len(arrOut); i++ {
- fmt.Printf("%d ", arrOut[i])
- }
- fmt.Printf("\n")*/
- var aut2 Automat
- z := len(aut.in[aut.enter])
- aut2.out = make([][]string, m)
- for i := 0; i < m; i++ {
- aut2.out[i] = make([]string, z)
- }
- aut2.in = make([][]int, m)
- for i := 0; i < m; i++ {
- aut2.in[i] = make([]int, z)
- }
- aut2.enter = 0
- autMin = &aut2
- for i := 0; i < len(aut.in); i++ {
- q := arrOut[i]
- if i == aut.enter {
- autMin.enter = q
- }
- for j := 0; j < len(aut.in[aut.enter]); j++ {
- autMin.in[q][j] = arrOut[aut.in[i][j]]
- autMin.out[q][j] = aut.out[i][j]
- }
- }
- /*for i := 0; i < len(autMin.in); i++ {
- for j := 0; j < len(autMin.in[i]); j++ {
- fmt.Printf("%d ", autMin.in[i][j])
- }
- fmt.Printf("\n")
- }*/
- return
- }
- var k int
- var out []int
- var counter = 0
- func VisitVertex(aut *Automat, a int) {
- if aut.color[a] == 0 {
- aut.color[a] = 1
- aut.r[a] = counter
- out = append(out, a)
- counter++
- for _, k := range aut.in[a] {
- VisitVertex(aut, k)
- }
- aut.color[a] = 2
- }
- }
- func main() {
- var n, m, q int
- input.Scanf("%d %d %d", &n, &m, &q)
- var aut Automat
- aut.in = make([][]int, n)
- for i := 0; i < n; i++ {
- aut.in[i] = make([]int, m)
- for j := 0; j < m; j++ {
- input.Scanf(" %d", &aut.in[i][j])
- }
- }
- aut.out = make([][]string, n)
- for i := 0; i < n; i++ {
- aut.out[i] = make([]string, m)
- for j := 0; j < m; j++ {
- input.Scanf(" %s", &aut.out[i][j])
- }
- }
- aut.enter = q
- autCon := Aufenkamp_Hohn(&aut)
- /*for i := 0; i < len(autCon.in); i++ {
- for j := 0; j < len(autCon.in[i]); j++ {
- fmt.Printf("%d ", autCon.in[i][j])
- }
- fmt.Printf("\n")
- }*/
- autCon.color = make([]int, len(autCon.in))
- autCon.r = make([]int, len(autCon.in))
- VisitVertex(autCon, autCon.enter)
- //fmt.Printf("%d --", autCon.enter)
- var autFinal Automat
- m = len(out)
- autFinal.in = make([][]int, m)
- for i, val1 := range out {
- autFinal.in[i] = make([]int, len(autCon.in[0]))
- for j, val2 := range autCon.in[val1] {
- autFinal.in[i][j] = autCon.r[val2]
- }
- }
- autFinal.out = make([][]string, m)
- for i, val1 := range out {
- autFinal.out[i] = make([]string, len(autCon.out[0]))
- for j, val2 := range autCon.out[val1] {
- autFinal.out[i][j] = val2
- }
- }
- counter = m
- fmt.Printf("digraph {\n")
- fmt.Printf("\trankdir = LR\n")
- fmt.Printf("\tdummy [label = \"\", shape = none]\n")
- for i := 0; i < counter; i++ {
- fmt.Printf("\t%d [shape = circle]\n", i)
- }
- fmt.Printf("\tdummy -> 0\n")
- for i := 0; i < counter; i++ {
- for j := 0; j < len(autCon.in[i]); j++ {
- fmt.Printf("\t%d -> %d [label = \"%c(%s)\"]\n", i, autFinal.in[i][j], 97+j, autFinal.out[i][j])
- }
- }
- fmt.Printf("}\n")
- }
- // 5 3 0 1 2 3 3 4 1 3 4 2 3 0 4 4 4 3 x x y y x x y x x x x y x y x
- // 9 3 1 2 3 0 2 3 1 7 6 4 8 5 4 4 4 4 8 6 4 7 5 4 7 7 8 8 8 7 x y x x y x x y x x y x x y x y x y y x y x y x x y x
- // 5 2 1 0 4 1 4 4 0 4 4 2 4 x z z z x z z x x z
Add Comment
Please, Sign In to add comment