Language: C++

# ALDS1_7_B: Binary Tree

class Node
  class << self
    def bind(parent, left, right)
      parent.set_children(left, right)
      left.set_parent(parent, :left)
      right.set_parent(parent, :right)
    end
  end

  attr_accessor :id, :left, :right
  attr_reader :depth, :height

  def initialize(id)
    @id = id
    @depth = @height = 0
  end

  def update_tree
    update_depths
    update_heights
  end

  def parent
    root? ? NIL : @parent
  end

  def sibling
    return NIL if root?
    on_left? ? @parent.right : @parent.left
  end

  def children
    [@left, @right].select { |n| not n.nil_node? }
  end

  def degree
    children.size
  end

  def type
    case
    when root? then 'root'
    when degree == 0 then 'leaf'
    else 'internal node'
    end
  end

  def root?
    @parent.nil?
  end

  def nil_node?
    self == NIL
  end

  def on_left?
    @position == :left
  end

  def set_children(left, right)
    @left  = left
    @right = right
  end

  def set_parent(parent, position)
    @parent   = parent
    @position = position
  end

  protected
    attr_writer :depth, :height

    def update_depths(depth = 0)
      return if self.nil_node?
      @depth = depth
      @left.update_depths @depth + 1
      @right.update_depths @depth + 1
    end

    def update_heights
      return -1 if self.nil_node?
      lh = @left.update_heights
      rh = @right.update_heights
      @height = [lh, rh].max + 1
    end
end

Node.const_set :NIL, Node.new(-1)

n_nodes = gets.to_i
tree = Array.new(n_nodes).map.with_index do |_, i|
  Node.new(i)
end

n_nodes.times do
  id, left_id, right_id = gets.split.map &:to_i
  left  = left_id  == -1 ? Node::NIL : tree[left_id]
  right = right_id == -1 ? Node::NIL : tree[right_id]
  Node.bind tree[id], left, right
end

tree.find { |node| node.root? }.update_tree

tree.each do |n|
  puts "node #{n.id}: parent = #{n.parent.id}, " <<
       "sibling = #{n.sibling.id}, " <<
       "degree = #{n.degree}, depth = #{n.depth}, " <<
       "height = #{n.height}, #{n.type}"
end

Compiler output:
a.cc:1:3: error: invalid preprocessing directive #ALDS1_7_B
    1 | # ALDS1_7_B: Binary Tree
      |   ^~~~~~~~~
a.cc:16:5: error: stray '@' in program
   16 |     @id = id
      |     ^
a.cc:17:5: error: stray '@' in program
   17 |     @depth = @height = 0
      |     ^
a.cc:17:14: error: stray '@' in program
   17 |     @depth = @height = 0
      |              ^
a.cc:26:19: error: stray '@' in program
   26 |     root? ? NIL : @parent
      |                   ^
a.cc:31:16: error: stray '@' in program
   31 |     on_left? ? @parent.right : @parent.left
      |                ^
a.cc:31:32: error: stray '@' in program
   31 |     on_left? ? @parent.right : @parent.left
      |                                ^
a.cc:35:6: error: stray '@' in program
   35 |     [@left, @right].select { |n| not n.nil_node? }
      |      ^
a.cc:35:13: error: stray '@' in program
   35 |     [@left, @right].select { |n| not n.nil_node? }
      |             ^
a.cc:44:21: warning: multi-character character constant [-Wmultichar]
   44 |     when root? then 'root'
      |                     ^~~~~~
a.cc:45:27: warning: multi-character character constant [-Wmultichar]
   45 |     when degree == 0 then 'leaf'
      |                           ^~~~~~
a.cc:46:10: warning: multi-character literal with 13 characters exceeds 'int' size of 4 bytes
   46 |     else 'internal node'
      |          ^~~~~~~~~~~~~~~
a.cc:51:5: error: stray '@' in program
   51 |     @parent.nil?
      |     ^
a.cc:59:5: error: stray '@' in program
   59 |     @position == :left
      |     ^
a.cc:63:5: error: stray '@' in program
   63 |     @left  = left
      |     ^
a.cc:64:5: error: stray '@' in program
   64 |     @right = right
      |     ^
a.cc:68:5: error: stray '@' in program
   68 |     @parent   = parent
      |     ^
a.cc:69:5: error: stray '@' in program
   69 |     @position = position
      |     ^
a.cc:77:7: error: stray '@' in program
   77 |       @depth = depth
      |       ^
a.cc:78:7: error: stray '@' in program
   78 |       @left.update_depths @depth + 1
      |       ^
a.cc:78:27: error: stray '@' in program
   78 |       @left.update_depths @depth + 1
      |                           ^
a.cc:79:7: error: stray '@' in program
   79 |       @right.update_depths @depth + 1
      |       ^
a.cc:79:28: error: stray '@' in program
   79 |       @right.update_depths @depth + 1
      |                            ^
a.cc:84:12: error: stray '@' in program
   84 |       lh = @left.update_heights
      |            ^
a.cc:85:12: error: stray '@' in program
   85 |       rh = @right.update_heights
      |            ^
a.cc:86:7: error: stray '@' in program
   86 |       @height = [lh, rh].max + 1
      |       ^
a.cc:4:9: error: expected identifier before '<<' token
    4 |   class << self
      |         ^~
a.cc:4:9: error: expected unqualified-id before '<<' token
a.cc:36:3: error: 'end' does not name a type
   36 |   end
      |   ^~~
a.cc:104:32: error: expected unqualified-id before '.' token
  104 | tree.find { |node| node.root? }.update_tree
      |                                ^