Language: C++

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

type Node struct {
	id       int
	parent   int
	sibling  int
	children []int // index of node or -1
	depth    int
	height   int
	typ      string
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}
	nodes, err := nextNodes(n, sc)
	if err != nil {
		panic(err)
	}

	for _, node := range nodes {
		for _, childId := range node.children {
			childIndex := findById(childId, nodes)
			nodes[childIndex].parent = node.id
		}
	}

	root := findRoot(nodes)

	visit(root.id, 0, nodes)

	sort.Slice(nodes, func(i, j int) bool {
		return nodes[i].id < nodes[j].id
	})

	for _, node := range nodes {
		fmt.Printf("node %d: parent = %d, sibling = %d, degree = %d, depth = %d, height = %d, %s\n", node.id, node.parent, node.sibling, len(node.children), node.depth, node.height, node.typ)
	}
}

func findById(id int, nodes []Node) int {
	for i, v := range nodes {
		if v.id == id {
			return i
		}
	}
	return -1
}

func findRoot(nodes []Node) *Node {
	for _, v := range nodes {
		if v.parent == -1 {
			return &v
		}
	}
	return nil
}

func visit(rootInd int, depth int, nodes []Node) int {
	root := &nodes[rootInd]
	// typ
	if root.parent == -1 {
		root.typ = "root"
	} else if len(root.children) == 0 {
		root.typ = "leaf"
	} else {
		root.typ = "internal node"
	}
	// sibling
	if len(root.children) == 2 {
		leftInd := findById(root.children[0], nodes)
		rightInd := findById(root.children[1], nodes)
		nodes[leftInd].sibling = root.children[1]
		nodes[rightInd].sibling = root.children[0]
	}
	// depth
	root.depth = depth
	// height
	maxH := 0
	for _, v := range root.children {
		// childInd := findById(v, nodes)
		// child := nodes[childInd]
		h := visit(v, depth+1, nodes) + 1
		if h > maxH {
			maxH = h
		}
	}
	root.height = maxH
	return root.height
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

func nextInts(n int, sc *bufio.Scanner) ([]int, error) {
	rs := make([]int, n)
	for i, _ := range rs {
		x, err := nextInt(sc)
		if err != nil {
			return nil, err
		}
		rs[i] = x
	}
	return rs, nil
}

func nextNodes(n int, sc *bufio.Scanner) ([]Node, error) {
	rs := make([]Node, n)
	for i, _ := range rs {
		id, err := nextInt(sc)
		if err != nil {
			return nil, err
		}
		left, err := nextInt(sc)
		if err != nil {
			return nil, err
		}
		right, err := nextInt(sc)
		if err != nil {
			panic(err)
		}
		children := []int{}
		if left != -1 {
			children = append(children, left)
		}
		if right != -1 {
			children = append(children, right)
		}
		rs[i] = Node{id, -1, -1, children, 0, 0, "internal node"}
	}
	return rs, nil
}



Compiler output:
a.cc:1:1: error: 'package' does not name a type
    1 | package main
      | ^~~~~~~
a.cc:21:1: error: 'func' does not name a type
   21 | func main() {
      | ^~~~
a.cc:53:1: error: 'func' does not name a type
   53 | func findById(id int, nodes []Node) int {
      | ^~~~
a.cc:62:1: error: 'func' does not name a type
   62 | func findRoot(nodes []Node) *Node {
      | ^~~~
a.cc:71:1: error: 'func' does not name a type
   71 | func visit(rootInd int, depth int, nodes []Node) int {
      | ^~~~
a.cc:104:1: error: 'func' does not name a type
  104 | func nextInt(sc *bufio.Scanner) (int, error) {
      | ^~~~
a.cc:109:1: error: 'func' does not name a type
  109 | func nextInts(n int, sc *bufio.Scanner) ([]int, error) {
      | ^~~~
a.cc:121:1: error: 'func' does not name a type
  121 | func nextNodes(n int, sc *bufio.Scanner) ([]Node, error) {
      | ^~~~