RosettaCodeData/Task/Functional-coverage-tree/Phix/functional-coverage-tree.phix

109 lines
4.4 KiB
Plaintext

-- demo\rosetta\Functional_coverage_tree.exw
with javascript_semantics
constant data = """
NAME_HIERARCHY | WEIGHT | COVERAGE |
cleaning | | |
house1 |40 | |
bedrooms | |0.25 |
bathrooms | | |
bathroom1 | |0.5 |
bathroom2 | | |
outside_lavatory | |1 |
attic | |0.75 |
kitchen | |0.1 |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | |1 |
basement | | |
garage | | |
garden | |0.8 |
house2 |60 | |
upstairs | | |
bedrooms | | |
suite_1 | | |
suite_2 | | |
bedroom_3 | | |
bedroom_4 | | |
bathroom | | |
toilet | | |
attics | |0.6 |
groundfloor | | |
kitchen | | |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | | |
wet_room_&_toilet | | |
garage | | |
garden | |0.9 |
hot_tub_suite | |1 |
basement | | |
cellars | |1 |
wine_cellar | |1 |
cinema | |0.75 |
"""
sequence lines = split(data,"\n"),
pi = {}, -- indents (to locate parents)
pdx = {}, -- indexes for ""
children
string desc, weights, covers
integer parent, child
atom weight, coverage, childw = 0
enum DESC, WEIGHT, COVERAGE, PARENT, CHILDREN, CHILDW
lines[DESC] &= " SHARE OF RESIDUE"
for i=2 to length(lines) do
-- decode text to useable data, link up parents & children
{desc,weights,covers} = split(lines[i],"|")
-- (nb this assumes /totally/ consistent indenting)
integer indent = length(desc)-length(trim_head(desc)),
k = find(indent,pi)
if k=0 then
pi = append(pi,indent)
pdx = append(pdx,0)
k = length(pi)
end if
pdx[k] = i
parent = 0
if k>1 then
parent = pdx[k-1]
-- lines[parent][CHILDREN] &= i
lines[parent][CHILDREN] = deep_copy(lines[parent][CHILDREN]) & i
end if
children = {}
weight = to_number(trim(weights),1)
coverage = to_number(trim(covers),0)
lines[i] = {desc, weight, coverage, parent, children, childw}
end for
for i=length(lines) to 2 by -1 do
-- calculate the parent coverages, and save child weight sums
children = lines[i][CHILDREN]
if length(children) then
coverage = 0
childw = 0
for c=1 to length(children) do
child = children[c]
atom w = lines[child][WEIGHT]
coverage += lines[child][COVERAGE]*w
childw += w
end for
lines[i][COVERAGE] = coverage/childw
lines[i][CHILDW] = childw -- (save for next loop)
end if
end for
for i=length(lines) to 2 by -1 do
-- calculate the share of residue, and format lines
child = i
{desc, weight, coverage, parent} = lines[i]
atom residue = 1-coverage
while parent do
residue *= lines[child][WEIGHT]/lines[parent][CHILDW]
{child, parent} = {parent, lines[parent][PARENT]}
end while
lines[i] = sprintf("%-32s| %6d | %-8g | %g",{desc,weight,coverage,residue})
end for
puts(1,join(lines,"\n")&"\n")
{} = wait_key()