-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtax_nr.rb
executable file
·77 lines (55 loc) · 1.28 KB
/
tax_nr.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env ruby
require 'pp'
# K#Bacteria(100);P#Bacteroidetes(100);C#Bacteroidia(100);O#Bacteroidales(100);F#Prevotellaceae(100);G#Prevotella(100)
# Usage: tax_nr.rb < tax.txt > tax_nr.txt
class Node
attr_reader :level, :orig, :parent, :children
def initialize(level, name, orig, parent)
@level = level
@name = name
@orig = orig
@parent = parent
@children = {}
end
def empty?
@children.empty?
end
def [](key)
@children[key]
end
def []=(key, val)
@children[key] = val
end
def to_s
names = []
node = self
until node.nil?
names << "#{node.level}##{node.orig}"
node = node.parent
end
names[0..-2].reverse.join(';')
end
def each
nodes = traverse([], self)
nodes.each { |node| yield node if node.empty? }
end
def traverse(nodes, node)
node.children.each_value { |child| traverse(nodes, child) }
nodes << node
end
end
tree = Node.new('R', 'root', 'root', nil)
STDIN.each_line do |line|
node = tree
line.chomp.split(';').each do |field|
level, orig = field.split('#')
name = orig.gsub(/\([^)]+\)/, '')
unless node[name]
node[name] = Node.new(level, name, orig, node)
end
node = node[name]
end
end
tree.each do |node|
puts node
end