I decided to give your code a go on my machine, it took about 144 seconds. The
reason it's slow though is because it creates a quite wild number of string and
sequence allocations, along with not having any caching of already computed
cards. When running your code as I was [streaming my
solution](https://www.youtube.com/live/kb-DrWCb_VE?si=zUTPYutrd_702WZ5&t=7427)
it used up about 10Gb of RAM before my stream crashed (you can find part two of
my stream [here](https://www.youtube.com/watch?v=SmdsucF4jkQ)). Actually a bit
surprised that it manages to do all that in 24 seconds. Compare it for example
to my solution where I converted the inputs into more reasonable data types
during the parsing step and the simple caching of cards. On my machine it runs
in about 2ms with a release build, and about 14ms with a debug build. I talk a
bit about why you might be able to use these patterns in other languages like
twinBasic, but it basically boils down to Nims default data structures being
optimized for other things. When you use them in a way that abuses their design
you can get very detrimental performance. Some languages optimize instead for
okay speed for any way of using a data structure, with the penalty that it
can't be made to go as fast as languages which require a bit more care.