Sha256: ad6c0f4902f86681547bbdf7e09468a9413f896b1bc2f0c94d4c547e0c98ba04

Contents?: true

Size: 1.8 KB

Versions: 274

Compression:

Stored size: 1.8 KB

Contents

package pov

import (
	"fmt"
	"log"
)

const testVersion = 2

type Graph struct {
	arcs   [][]int
	labels []string
	nodes  map[string]int
}

func New() *Graph { return &Graph{nodes: map[string]int{}} }

func (g *Graph) node(l string) int {
	if n, ok := g.nodes[l]; ok {
		return n
	}
	n := len(g.labels)
	g.labels = append(g.labels, l)
	g.arcs = append(g.arcs, nil)
	g.nodes[l] = n
	return n
}

func (g *Graph) AddNode(label string) {
	g.node(label)
}

func (g *Graph) AddArc(from, to string) {
	// use CI run to validate test cases
	if _, ok := g.nodes[to]; !ok {
		log.Println("AddArc from, to:", from, to)
		log.Fatal("test program promises bottom-up construction")
	}
	fr := g.node(from)
	g.arcs[fr] = append(g.arcs[fr], g.node(to))
}

func (g *Graph) ChangeRoot(oldRoot, newRoot string) *Graph {
	// use CI run to validate test cases
	if !g.isTree(oldRoot) {
		log.Println("not a tree, or", oldRoot, "not root")
		log.Fatal("test program promises to pass root of a tree")
	}
	nr := g.nodes[newRoot]
	var f func(int) bool
	f = func(n int) (found bool) {
		if n == nr {
			return true
		}
		a := g.arcs[n]
		for i, to := range a {
			if f(to) {
				last := len(a) - 1
				a[i] = a[last]
				g.arcs[n] = a[:last]
				g.arcs[to] = append(g.arcs[to], n)
				return true
			}
		}
		return false
	}
	f(g.nodes[oldRoot])
	return g
}

func (g *Graph) ArcList() (s []string) {
	for fr, to := range g.arcs {
		for _, to := range to {
			s = append(s, fmt.Sprintf("%s -> %s", g.labels[fr], g.labels[to]))
		}
	}
	return
}

func (g *Graph) isTree(root string) bool {
	a := g.arcs
	v := make([]bool, len(a))
	nv := 0
	var df func(int) bool
	df = func(n int) bool {
		if v[n] {
			return false
		}
		v[n] = true
		nv++
		for _, to := range a[n] {
			if !df(to) {
				return false
			}
		}
		return true
	}
	return df(g.nodes[root]) && nv == len(a)
}

Version data entries

274 entries across 274 versions & 1 rubygems

Version Path
trackler-2.2.1.56 tracks/go/exercises/pov/example.go
trackler-2.2.1.55 tracks/go/exercises/pov/example.go
trackler-2.2.1.54 tracks/go/exercises/pov/example.go
trackler-2.2.1.53 tracks/go/exercises/pov/example.go
trackler-2.2.1.52 tracks/go/exercises/pov/example.go
trackler-2.2.1.51 tracks/go/exercises/pov/example.go
trackler-2.2.1.50 tracks/go/exercises/pov/example.go
trackler-2.2.1.49 tracks/go/exercises/pov/example.go
trackler-2.2.1.48 tracks/go/exercises/pov/example.go
trackler-2.2.1.47 tracks/go/exercises/pov/example.go
trackler-2.2.1.46 tracks/go/exercises/pov/example.go
trackler-2.2.1.45 tracks/go/exercises/pov/example.go
trackler-2.2.1.44 tracks/go/exercises/pov/example.go
trackler-2.2.1.43 tracks/go/exercises/pov/example.go
trackler-2.2.1.42 tracks/go/exercises/pov/example.go
trackler-2.2.1.41 tracks/go/exercises/pov/example.go
trackler-2.2.1.40 tracks/go/exercises/pov/example.go
trackler-2.2.1.39 tracks/go/exercises/pov/example.go
trackler-2.2.1.38 tracks/go/exercises/pov/example.go
trackler-2.2.1.37 tracks/go/exercises/pov/example.go