MojoでProject Euler 59

https://projecteuler.net/problem=59

何を言っているのかわからない問題文ですが、キーが3文字と言っているので、キーがABCなら、1文字目と4文字目と…はAがキーで、2文字目と5文字目と…はBがキーで、などとなるのでしょう。そして、各グループで一番多いコードと"e"のコードでXORを取ればキーになるだろうと思ったらうまくいかない。グループのデータを見てみると、1個ずつかけ離れたコードがある。英小文字じゃなくてスペースだと気が付きました。
Listのスライシングはふつうにできるんですね。
DictのkeyとListのelementになり得るTraitはKeyEementというそうです。

from collections import Dict
import sys


#################### library ####################

fn frequency[T: KeyElement](v: List[T]) -> Dict[T, Int]:
    var freq = Dict[T, Int]()
    for e in v:
        freq[e[]] = freq.get(e[], 0) + 1
    return freq


#################### process ####################

fn read_csv(path: String) -> List[Int]:
    try:
        var ns = List[Int]()
        with open(path, "r") as f:
            var line = f.read()
            var v = line.split(",")
            for s in v:
                var n = atol(s[])
                ns.append(n)
        return ns
    except:
        return List[Int]()

fn determine_code(ns: List[Int]) -> Int:
    var freq = frequency(ns)
    var max_n = 0;
    var max_freq = 0;
    for e in freq.items():
        if e[].value > max_freq:
            max_freq = e[].value
            max_n = e[].key
    return max_n ^ ord(" ")

fn f_each(ns: List[Int]) -> Int:
    var code = determine_code(ns)
    var s = 0
    for n in ns:
        s += n[] ^ code
    return s

fn f(path: String) -> Int:
    var ns = read_csv(path)
    var ns1 = ns[::3]
    var ns2 = ns[1::3]
    var ns3 = ns[2::3]
    return f_each(ns1) + f_each(ns2) + f_each(ns3)

fn main() raises:
    var path = String("0059_cipher.txt")
    print(f(path))