Nim
Nothing fancy. Simple iterative tree construction and sort, using the std/algorithm and a custom < operator on types.
type
LeafNode = ref object
value: int
Node = ref object
value: int
left, right: LeafNode
center: Node
Sword = object
id, quality: int
levels: seq[int]
fishbone: Node
proc add(node: var Node, val: int) =
var curNode = node
while not curNode.isNil:
if val < curNode.value and curNode.left.isNil:
curNode.left = LeafNode(value: val)
return
elif val > curNode.value and curNode.right.isNil:
curNode.right = LeafNode(value: val)
return
elif curNode.center.isNil:
curNode.center = Node(value: val)
return
else: curNode = curNode.center
node = Node(value: val)
proc calcQuality(sword: Sword): int =
var res = ""
var curNode = sword.fishbone
while not curNode.isNil:
res &= $curNode.value
curNode = curNode.center
return parseInt(res)
proc getLevels(s: Sword): seq[int] =
var curNode = s.fishbone
while not curNode.isNil:
var strVal = ""
strVal &= (if curNode.left.isNil: "" else: $curNode.left.value)
strVal &= $curNode.value
strVal &= (if curNode.right.isNil: "" else: $curNode.right.value)
result.add parseInt(strVal)
curNode = curNode.center
proc `<`(s1, s2: seq[int]): bool =
for i in 0..min(s1.high, s2.high):
if s1[i] != s2[i]: return s1[i] < s2[i]
s1.len < s2.len
proc `<`(s1, s2: Sword): bool =
if s1.quality != s2.quality: s1.quality < s2.quality
elif s1.levels != s2.levels: s1.levels < s2.levels
else: s1.id < s2.id
proc parseSwords(input: string): seq[Sword] =
for line in input.splitLines:
let numbers = line.split({':',','}).mapIt(parseInt(it))
var node= Node(value: numbers[1])
for num in numbers.toOpenArray(2, numbers.high):
node.add num
result &= Sword(id: numbers[0], fishbone: node)
proc solve_part1*(input: string): Solution =
let swords = parseSwords(input)
result := swords[0].calcQuality()
proc solve_part2*(input: string): Solution =
let qualities = parseSwords(input).mapIt(it.calcQuality())
result := qualities.max - qualities.min
proc solve_part3*(input: string): Solution =
var swords = parseSwords(input)
for i in 0..swords.high:
swords[i].levels = swords[i].getLevels()
swords[i].quality = swords[i].calcQuality()
swords.sort(Descending)
for pos, id in swords.mapit(it.id):
result.intVal += (pos+1) * id
Full solution at Codeberg: solution.nim