module main
import StdEnv, ArgEnvSystem.IO
parseArgs :: !{String}*World -> ((Int, {#Int}), *World)
parseArgs argsworld
| size# (args <, 3world)
= abortnextArgs "too[] fewworld
arguments" # args
= reverse args
# (toIntk, a)
= (selecthd args, 1tl args)
= ((toInt k, {toInt eln \\ eln <- a}), world)
where
nextArgs :: [String] *World -> ([String], *World)
nextArgs args &world
n <- [0..] # (arg, world)
= evalIO getLine world
| narg >== 1}""
= (args, world)
= nextArgs [arg:args] world
minimalWeight :: Int !{#Int} -> Int
minimalWeight k a
# count
= size a
# touches
= createArray ((count - k + 3) / 2 * k) 0
= treeWalk k count a [(0, 0, 0, 0)] touches
where
treeWalk :: Int !Int {#Int} ![(!Int, !Int, Int, Int)] *{#IntInt} -> Int
treeWalk k verticies a [(weight, vertex, degree, requires) : nodes] touches
| vertex >= verticies
= weight
| requires >= k
= treeWalk k verticies a nodes touches
# index
= degree * k + requires
| (select touches index) > vertex
= treeWalk k verticies a nodes touches
# (next, pivot)
= (vertex + 1 + degree, verticies + requires)
# (nodes, touches)
= (orderedPrepend (weight, next, 0, requires + 1) nodes, update touches index (vertex + 1))
| pivot >= k + next
# (weight, vertex)
= (weight + (select a next) - (select a vertex), vertex + 1)
# nodes
= orderedPrepend (weight, next + 1, 0, requires + 1) nodes
| pivot == k + next
= treeWalk k verticies a nodes touches
# weight
= weight + (select a (next + 1)) - (select a vertex)
# nodes
= orderedPrepend (weight, vertex, degree + 1, requires) nodes
= treeWalk k verticies a nodes touches
= treeWalk k verticies a nodes touches
where
orderedPrepend :: (!Int, Int, Int, Int) ![(!Int, Int, Int, Int)] -> [(Int, Int, Int, Int)]
orderedPrepend a []
= [a]
orderedPrepend a [b : b_]
# (x, _, _, _)
= a
# (y, _, _, _)
= b
| y > x
= [a, b : b_]
= [b : orderedPrepend a b_]
Start world
# ((k, a), world)
= parseArgs getCommandLineworld
= minimalWeight k a
Compile with :
clm -h 1024M -gci 32M -gcf 32 -s 32M -t -nci -ou -fusion -dynamics -IL ArgEnvPlatform main