struct Node { at: i64, first: i64, next: i64 } struct Ctx<'a> { source: &'a [u8], nodes: &'a mut Vec, text: &'a mut Vec, scratch: &'a mut Vec, } fn walk(c: &mut Ctx<'_>, n: i64, depth: i64) -> i64 { let n = usize::try_from(n).unwrap(); let mark = c.scratch.len(); c.scratch.push(depth); let at = usize::try_from(c.nodes[n].at).unwrap(); c.text.push(c.source[at]); let mut total = c.scratch[mark]; let mut e = c.nodes[n].first; while e >= 0 { total += walk(c, e, depth + 1); e = c.nodes[usize::try_from(e).unwrap()].next; } c.scratch.truncate(mark); total } fn compile(source: &[u8]) -> i64 { let mut nodes=vec![Node {at:0,first:1,next:-1}, Node {at:1,first:-1,next:2}, Node {at:2,first:-1,next:-1}]; let mut text=Vec::new(); let mut scratch=Vec::new(); let mut c=Ctx {source,nodes:&mut nodes,text:&mut text,scratch:&mut scratch}; let r=walk(&mut c,0,1); use std::io::Write; let mut out=std::io::stdout().lock();out.write_all(&text).unwrap(); writeln!(&mut out," {}",scratch.len()).unwrap(); r } fn main() {assert_eq!(compile(b"abc"),5);}