[Jprogramming] AoC 2016 day 10
'Jon Hough' via Programming
programming at jsoftware.com
Mon Dec 12 12:29:48 UTC 2016
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 <moon.aka.sun at gmail.com> wrote:
Subject: [Jprogramming] AoC 2016 day 10
To: "programming" <programming at jsoftware.com>
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
More information about the Programming
mailing list