Taking tentative steps into nim coming from VBA by having a go at Advent of Code 2020
I have an OrderedTable[ int, seq[ int ] ]
what is the most nimy (minish, nithonic?) way to get the value of the last item of the last sequence in the table when you don't now the specific indeces.
At the moment I've got to
myTable[ myTable.len ][ myTable[ myTable.len ].len ]
which looks profoundly ugly for nim.
The equivalent (using my libraries) for VBA would be
WrappedScriptingDIctionary.getlast.value.getlast.value
which for VBA is 'wonderfully eloquent'
NB getlast returns a key/value pair ,so in the first instance returns an index vs WrappedScriptingDIctionary ,and is a method I added to a wrapping of the Scripting.DIctionary object)
I didn't see it mentioned, but mySeq.high also exists. That is: let lastElement = mySeq[mySeq.high]. That can be useful sometimes, eg: for i in 0..mySeq.high: ...
That doesn't help in the OrderedTable example though, you still need to know the key. I'm a little surprised that there isn't an access by index in the OrderedTable. I feel like I remember encountering such a structure in the nimble directory, but I'm blanking on it right now. Worst case you could do something like: toSeq(myOTable.values)[^1]
for the specifics of Day 15 problem I think that most people (including myself) did not use an OrderedTable, instead they used a standard Table[int, int] with key as number and value as turn last seen. You would also keep track separately of the last element.
As far as I know the use case for OrderedTable is not to be able to extract elements given an index (like last index) but to be able to have a reproducible and consistent ordering when looping over keys.
they used a standard Table[int, int] with key as number and value as turn last seen. You would also keep track separately of the last element.
This.
The keys for the Orderedtable arrive in a random sequence and may be repeated.
The sequence associated with each key stores the step number on which the key arrives.
If I get Keys of 3,2,5,9,2,3, the sequences for key 3 and 2 would have two items each (1,6) and (2,5) for Keys 2 and 3.
If I ask for the last key in the ordered table I expect to be given the value 9.
If I ask for the last item in the sequence attached to Key 3 I expect to get 5.
Coming from VBA where this expectation was met exactly, I may be making unknown assumptions about how nim works.
Is an orderedTable populated with seq a reasonable approach?
@hyl - you may be thinking of adix/lptabz.nthKey (or nthPair) in compact, insertion-ordered mode. (Maybe I should make that be [] for positional access and {} for keyed access, but this seems unpopular.)
That mode is active when sentinel type Z is notin {K,void}) for generic params [K,V,Z;z:static[int]]). I agree it could be documented better with more example code.
Araq did reply not exactly unfavorably to having an API for this this in std/tables.OrderedTable. { His response was more just factual, but usually he is pretty up front if he thinks things are a terrible idea and should never happen. :-) So, it's a bit ambiguous. } The way the stdlib currently does ordered tables, it would be O(N) linked list hops to get the Nth element which could be very slow. The adix/lptabz method is a more efficient two level store.
All said, I have no idea if this is a good idea for the advent of code algo.
I stored the last at most two turns per number, so Table[int, seq[int]]. If number 37 appeared in the past two times, and the new spoken 37 comes out several turns later, you need to subtract those last two in the table. (My solution.)
How did you manage to solve it with Table[int, int]?