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

Reply via email to