95 lines
1.4 KiB
Go
95 lines
1.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type Prog struct {
|
||
|
Num int
|
||
|
Cx []*Prog
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
Progs map[int]*Prog
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
sc := bufio.NewScanner(os.Stdin)
|
||
|
Progs = make(map[int]*Prog)
|
||
|
for sc.Scan() {
|
||
|
fmt.Println(sc.Text())
|
||
|
parse(sc.Text())
|
||
|
}
|
||
|
nums := make([]int, 0, 0)
|
||
|
nums = walk(Progs[0], nums)
|
||
|
fmt.Println("result ", len(nums))
|
||
|
}
|
||
|
|
||
|
func appendUniq(nums []int, num int) ([]int, bool) {
|
||
|
for _, n := range nums {
|
||
|
if n == num {
|
||
|
return nums, false
|
||
|
}
|
||
|
}
|
||
|
nums = append(nums, num)
|
||
|
return nums, true
|
||
|
}
|
||
|
|
||
|
func walk(p *Prog, nums []int) []int {
|
||
|
var added bool
|
||
|
nums, added = appendUniq(nums, p.Num)
|
||
|
if added {
|
||
|
for _, pp := range p.Cx {
|
||
|
nums = walk(pp, nums)
|
||
|
}
|
||
|
}
|
||
|
return nums
|
||
|
}
|
||
|
|
||
|
func parse(in string) {
|
||
|
expr := strings.Split(in, " <-> ")
|
||
|
num, _ := strconv.Atoi(expr[0])
|
||
|
p1 := GetProg(num)
|
||
|
|
||
|
list := strings.Split(expr[1], ", ")
|
||
|
for _, l := range list {
|
||
|
nl, _ := strconv.Atoi(l)
|
||
|
p2 := GetProg(nl)
|
||
|
Pipe(p1, p2)
|
||
|
Pipe(p2, p1)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func NewProg(num int) *Prog {
|
||
|
return &Prog{
|
||
|
num,
|
||
|
make([]*Prog, 0, 0),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func GetProg(num int) *Prog {
|
||
|
p := Progs[num]
|
||
|
if p == nil {
|
||
|
p = NewProg(num)
|
||
|
Progs[num] = p
|
||
|
}
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func Pipe(p1, p2 *Prog) {
|
||
|
piped := false
|
||
|
for _, p := range p1.Cx {
|
||
|
if p1.Num == p.Num {
|
||
|
piped = true
|
||
|
}
|
||
|
}
|
||
|
if !piped {
|
||
|
p1.Cx = append(p1.Cx, p2)
|
||
|
fmt.Println("pipe", p1.Num, p2.Num)
|
||
|
}
|
||
|
}
|