The two boxes approach is not the only way to make it work. The two boxes approach is great for lots off small, temporary dictionaries, or mostly static dictionaries. If you instead want a small number of very large, persistent dictionaries with ongoing changes, there may be better (including explicit) approaches. Sometimes for the extreme cases it's even worth introducing some additional implementation to help manage some update-related performance issues.
-- Raul On Sun, Dec 11, 2016 at 4:24 PM, 'Pascal Jasmin' via Programming <[email protected]> wrote: > An excellent exercise is to write your own dictionary framework or class in J > > Framework (series of functions that take boxed structure as right arg, and > dict operation parameters as x)rather than class is more idiomatic. > > At its core, its a list of 2 (key, value) boxes, though it can also be > transposed. > > The important thing about the exercise is how short you can make the lookup > and modify functions, and then understand that just having a box structure > (if key and value really can be heterogeneous types), and then how you can > treat a box structure as a more flexible dictionary (for instance, many > values per key). Basically the J way is to create and access structures > similar enough to dictionaries. > > > > ----- Original Message ----- > From: Raul Miller <[email protected]> > To: Programming forum <[email protected]> > Sent: Sunday, December 11, 2016 3:06 PM > Subject: Re: [Jprogramming] AoC 2016 day 10 > > http://www.jsoftware.com/help/dictionary/dsco.htm might interest you... > > A "dictionary" winds up being a pair of arrays: a key array and a value array. > > Thanks, > > -- > Raul > > > On Sun, Dec 11, 2016 at 11:53 AM, Moon S <[email protected]> wrote: >> I won't lie, first I wrote that solution in Python. It's much easier and >> faster. Then the program was translated to J. The biggest problem was that >> J didn't have dictionaries. While even K has! And sparse arrays don't >> support strings or boxed values. Argh. And we are at the end of year 2016! >> Anyway, we deal with small numbers, it's quite suitable to grow an array >> when we need to insert some value there with an index a bit greater than >> the length of the array. We could also allocate some big arrays, or just >> bigger than input, or to calculate the sizes based on the input. Well, it's >> possible, yes. But pretending to deal with dictionaries looks more pleasant >> to me. So it was finally, the J solution for Day 10. >> >> t =: cutLF CR-.~fread '10.dat' >> >> 'E O B' =: 0 0 1 NB. empty value; what:Output, what:Bot >> b =: 0 6$0 NB. i-th bot: [lo-what lo-index hi-what hi-index slot1 slot2] >> o =: i.0 NB. outputs, empty vector at first >> >> NB. first we build the bot net >> 3 : 0 t >> for_s. y do. s =. ' 'cut >s >> if. -. 'bot'-:>{.s do. continue. end. NB. do only bots >> 'k lk hk' =.".>1 6 11{s NB. all numbers from string >> lo=.('bot'-:> 5{s){O,B >> hi=.('bot'-:>10{s){O,B >> if. k>:#b do. b =: b,((>:k-#b),{:$b)$0 end. NB. expand b if needed >> b =: (lo,lk,hi,hk,E,E) k}b >> end. >> ) >> >> pv =: 4 : 0 NB. pass value; x - value to set, y - pair what,index >> k=.{:y >> if. O={.y do. NB. output, set value in o >> if. k>:#o do. o =: o,(>:k-#o)$E end. NB. expand o if needed >> if. E~:k{o do. exit#echo 'output already set ',"k,k{o end. >> o =: x k}o >> else. NB. B - bot, set 1st slot, or 2nd slot and then propagate value >> if. k>:#b do. exit#echo 'no such bot ',":k end. >> 'lw lx hw hx s1 s2' =. k{b >> if. s1=E do. NB. both slots are empty, let's set the 1st >> b =: x (<k,4)}b >> else. >> if. s2~:E do. exit#echo 'no empty slot ',":k,v,s1,s2 end. >> b =: x (<k,5)}b >> lv =. x <. s1 >> hv =. x >. s1 >> if. 17 61 -: lv,hv do. echo k end. NB. part 1: catch what was asked! >> lv pv 0 1{k{b >> hv pv 2 3{k{b >> end. >> end. >> ) >> >> NB. then we spread values >> 3 : 0 t >> for_s. y do. s =. ' 'cut >s >> if. -. 'value'-:>{.s do. continue. end. NB. process only values >> v pv B,k [ 'v k' =.".>1 5{s >> end. >> ) >> >> echo */0 1 2{o NB. part 2: multiply outputs >> >> exit 0 >> >> It's rather long, but easy to understand, I hope. If you remove comments >> and rearrange some pieces of code, it'll be down to 720+ chars and will fit >> one screen. >> >> The idea of the solution was first to build the whole network of bots, i.e. >> to have them all with their connections to other bots, but without any real >> values yet; then we start to put values to the bots and propagate those >> values to other bots and to the output. Usually the puzzles of AoC allow >> such simple solutions - all the data is correct, no conflicts, no races in >> schemes, all will be perfect in the end. So such a solution works. >> >> Then it comes the challenge -- to make it all J-style, all tacit and magic >> :) >> Well, there's still left one explicit definition, I guess it would've been >> too complicated if it was tacit. >> >> The basic ideas are the same, to build the bot net and put the values >> there. On the second stage the reduce is used. J doesn't allow arbitrary >> types for '/' or an initial/state value of different type, but here boxes >> come to the rescue - we can put anything in the boxes and work with them as >> with simple values. >> >> t =: cutLF CR-.~fread '10.dat' >> NB. verbs ----------------------------------- >> onlybots =: #~ ('bot'-:3{.>)"0 >> onlyvals =: #~ ('val'-:3{.>)"0 >> parsebot =: [:".[:>1 4 5 8 9{[:cut('to output';'0';'to bot';'1')rplc~> >> parseval =: [:<[:".[:>1 5{[:cut > >> val2out =: ([:{.])`([:<_1,5<.[:{:])`[ } NB. save value to output = last >> bots item >> val2slot1 =: ([:{.])`([:<4,~[:{:])`[ } >> val2slot2 =: 4 : 0 >> if. 17 61 -: lh=./:~ ({.y),4{(k=.{:y){x do. echo {:y end. NB. part 1 >> answer >> ((({.y)(<k,5)}x)pv({.lh),0 1{k{x)pv({:lh),2 3{k{x NB. set slot2 and pass >> both values >> ) >> val2bot =: val2slot2`val2slot1 @. (0=4{([:{:]){[) NB. choose slot >> pv =: val2out`val2bot @.(1{]) NB. pass value >> av =: [:< ([:>]) pv 1j1 1#!.1[:>[ NB. apply value to bots >> NB. nouns ----------------------------------- >> bots =: (0 0,~}.)"1 /:~ parsebot"0 onlybots t NB. get all bots from input >> vals =: parseval"0 onlyvals t NB. get all vaules >> echo */3{.{:> av/ |.(bots,0);vals NB. apply values to bots; >> part 2 output >> exit 0 >> >> I don't know if it's really readable. Anyway it works. >> >> Enjoy :) >> >> P.S. what was interesting there: v1`v2 @. vt, v1`v2`v3 }, / over boxes, AjB >> #!.C. >> >> Georgiy Pruss >> ---------------------------------------------------------------------- >> For information about J forums see http://www.jsoftware.com/forums.htm > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
