I wrote an Object Oriented implementation of a hashmap a while ago: https://github.com/jonghough/msgpack-j/blob/master/hashmap.ijs
It's not brilliant but I have used it for some things. e.g. hm =: '' conew 'HashMap' set__hm (1; 'hello') get__hm 1 It can also contain other hashmaps as values -- although I had to use a horrific workaround because J has no object introspection (that I know of), so you can't differentiate between a boxed literal and an object reference. -------------------------------------------- On Mon, 12/12/16, Moon S <[email protected]> wrote: Subject: [Jprogramming] AoC 2016 day 10 To: "programming" <[email protected]> Date: Monday, December 12, 2016, 1:53 AM 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
