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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
#!/usr/bin/ruby -w
# ch-2.rb
# https://theweeklychallenge.org/blog/perl-weekly-challenge-146/
#
# ## Task 2 > Curious Fraction Tree
# =================================
#
# Consider the following `Curious Fraction Tree`:
#
# ```
# __________1/1__________
# / \
# ___1/2___ ___2/1___
# / \ / \
# 1/3 3/2 2/3 3/1
# / \ / \ / \ / \
# 1/4 4/3 3/5 5/2 2/5 5/3 3/4 4/1
# ```
#
# You are given a fraction, member of the tree created similar to the above
# sample.
#
# Write a script to find out the parent and grandparent of the given member.
#
# **Example 1:**
#
# ```
# Input: $member = '3/5';
# Output: parent = '3/2' and grandparent = '1/2'
# ```
#
# **Example 2:**
#
# ```
# Input: $member = '4/3';
# Output: parent = '1/3' and grandparent = '1/2'
# ```
################################################################################
# PWC Solution #################################################################
################################################################################
def get_curious_parent(member)
num, den = member.split(%r{/}, 2).map(&:to_i)
val = num.to_f / den.to_f
return nil unless val != 1.0
return "#{num - den}/#{den}" unless val < 1
return "#{num}/#{den - num}" unless val > 1
end
def get_curious_tree(member)
parents = []
child = member
until child.nil?
parents.push child
child = get_curious_parent(child)
end
parents
end
def get_curious_generations(tree, generations = 2)
return [tree[1]] unless tree.length > 2
tree.slice(1, generations)
end
################################################################################
# Utilities ####################################################################
################################################################################
def color_str(color, str)
colors = {
green: "\e[32m",
red: "\e[31m",
reset: "\e[0m",
yellow: "\e[33m"
}
colors[color] + str + colors[:reset]
end
def format_results(tree, results = '')
tree.each_with_index do |member, idx|
length = tree.length
results += color_str(:yellow, 'parent') unless idx > 0
results += color_str(:yellow, 'great-' * (idx - 1)) unless idx < 2
results += color_str(:yellow, 'grandparent') unless idx < 1
results += ' = ' + color_str(:green, member)
results = length == 2 && idx.zero? ? results + ' and ' : results
results = idx == length - 2 && length != 2 ? results + ', and ' : results
results = length > 2 && idx < length - 2 ? results + ', ' : results
end
results
end
def assert_root(tree)
last = tree[-1]
last != '1/1' && color_str(:yellow, 'Curious fraction tree rooted at ') +
color_str(:red, last) +
color_str(:yellow, ' and not at ') +
color_str(:green, '1/1')
end
################################################################################
# Main #########################################################################
################################################################################
prompt =
'Enter a fraction (i.e.: "' +
color_str(:green, '3/5') +
'") or type "' +
color_str(:yellow, 'exit') +
'" to quit /> '
more_prompt =
'Enter "' +
color_str(:yellow, 'more') +
'" to see more details, or enter a fraction (i.e.: "' +
color_str(:green, '3/5') +
'") to continue /> '
banner = 'A Curious Fraction Tree'
puts color_str(:yellow, banner)
puts color_str(:yellow, '=' * banner.length)
current_tree = nil
generations = nil
asserted_root = nil
print prompt
loop do
input = gets.chomp
input.strip!
case input
when %r{\A1\/1\z}
puts color_str(:green, input) + ' is root.'
print prompt
when %r{\A\d+\/\d+\z}
current_tree = get_curious_tree(input)
generations = get_curious_generations(current_tree)
asserted_root = assert_root(current_tree)
puts format_results(generations)
print more_prompt
when /\Amore\z/i
tree = current_tree.slice(1, current_tree.size - 1)
puts format_results(tree)
puts asserted_root if asserted_root
current_tree = nil
generations = nil
asserted_root = nil
print prompt
when /exit|quit|q/i
puts color_str(:yellow, 'Goodbye.')
exit
else puts "I don't understand #{color_str(:yellow, input)}"
end
end
|