If you don't mind some more suggestions: I would replace (+/)@:(+/)@: with +/@,@: (though in this case you don't need @: at all and +/@,@ works fine).
I would also use /~ thrice, yielding +/@,@(%/~ * ~:/~ * 0 = |~/~) Also, since you're going to be using +/ anyways, it's tempting to remove the +/@ from that expression - but since you're using it on each line, there is a good case for leaving it in place (cuts down on intermediate storage space). I'm not sure if this is an actual improvement, but I try to avoid "0 on expressions of primitives which have rank 0. Thanks, -- Raul On Sat, Dec 2, 2017 at 3:20 PM, Joe Bogner <[email protected]> wrote: > A slightly cleaner version of my day2b > > day2b =: (+/) @: (+/) @: ((% * ~: *. 0&=@|~)"0/~) > > +/ day2b"1 (". every LF cut input) > > > > thanks Raul & Henry for helping with the rank question on the other thread > > On Sat, Dec 2, 2017 at 9:21 AM, Joe Bogner <[email protected]> wrote: > >> I only have a few minutes this morning but here is my unrefined solutions >> to partA and partB >> >> day2a =: +/ @: ([: (>./ - <./) @:". every LF cut ]) >> >> input =: 0 : 0 >> 5 1 9 5 >> 7 5 3 >> 2 4 6 8 >> ) >> >> day2a input >> >> >> >> day2b =: ([: +/ (+/ @: (%/~ * (~:/~ *. ( (0&=@|~))/~) ))) >> >> +/ day2b"1 (". every LF cut input) >> >> >> >> On Sat, Dec 2, 2017 at 6:12 AM, Raul Miller <[email protected]> wrote: >> >>> What people like to do depends on the person. I tend to prefer compact >>> expressions, but other people have different preferences (and some >>> people prefer ([: f g) forms. >>> >>> Generally speaking, if f and g represent verbs, then ([: f g) is >>> equivalent to f@:g and if g has infinite rank you can go f@g. >>> However... if f and g represent verb *definitions* then for the >>> general case you need (f)@:(g) -- you get a free parenthesis effect >>> with every name, so if you are removing the name you might need the >>> parenthesis that it provided. That said, if f was not a verb train >>> then you can go f@:(g) and if g has infinite rank you can go f@(g). >>> You can only eliminate the parenthesis from f@:(g) if it's g is a >>> single word -- this gets back to whether f and g represent verbs or >>> verb definitions ... or something else. >>> >>> That said, note that if f and g represent something other than verbs >>> then ([: f g) might be an error, though there's a couple notable >>> exceptions to that rule which involve certain conjunctions. To see >>> this, note that @: is a conjunction. You can have f OR g be @: and the >>> other one be a verb. The result will always generate errors when given >>> a noun. However, if you instead use the : conjunction, surprisingly, >>> there will be cases where the result can be evaluated (though one of >>> the cases will not be the most compact form and will need another verb >>> before the result is a verb. Also that form is something that you >>> don't see used a lot (though it does have its uses - it's a "free >>> parenthesis" case that doesn't get a lot of attention). >>> >>> Anyways... advent of code... >>> >>> +/@(>./ - <./) is how I originally expressed the day two problem. I'd >>> ignore reading from a file, because I wouldn't use files here. >>> >>> That said, I went and tried it - I put the example data in a ".;._2]0 >>> :0 definition like this: >>> >>> ss=:".;._2]0 :0 >>> 5 1 9 5 >>> 7 5 3 >>> 2 4 6 8 >>> ) >>> >>> This raises an issue - the rows are "ragged". There's two ways of >>> dealing with this - one is you can put each row in a box, the other >>> (which works in this case) is to remove the fill values from the rows >>> before using them. I went with the latter approach and my solution >>> became +/@:(>./"1 - (<./@-.&0)"1) >>> >>> For the second part, the sample data they gave was not ragged, and I >>> didn't read ahead to notice that I'd be using the same dataset there >>> (I skipped out on day 1). So my initial solution looked like this: >>> >>> require'stats' >>> allpairs=: {~ 2 comb # >>> cks=: [: +/((>./ % <./)@,@(#~ +./@(e. *./)"1)@allpairs)"1 >>> >>> Then changed it to allpairs=: ({~ 2 comb #)@-.&0"1 though on >>> reflection that's not necessary. >>> >>> Not quite as compact as your approach, nor as efficient for the data >>> we are working with here, but it works. >>> >>> Thanks, >>> >>> -- >>> Raul >>> >>> >>> On Sat, Dec 2, 2017 at 1:31 AM, Daniel Lyons <[email protected]> >>> wrote: >>> > Thanks to everyone for sharing solutions yesterday and especially to >>> those with advice for me, I really appreciate it! >>> > >>> > Today's problem has to do with computing checksums. Like yesterday, the >>> first part and the second part bear some kind of family resemblance that >>> you can probably leverage; my first solution doesn't really help with my >>> second, but oh well. >>> > >>> > Part one is basically to examine a matrix comparing items row-by-row, >>> finding the differences between the largest and smallest elements of each, >>> and then summing those differences. My solution: >>> > >>> > a =. ".&.>cutLF fread '~/Desktop/input' >>> > checksum =. monad def '+/> (>./ - <./) &.> y' >>> > >>> > There's a fair amount of boxing and unboxing going on here. The actual >>> input file is a rectangular matrix, but the example input in the problem is >>> not, so I assumed the input wasn't either. This could certainly be >>> simplified. The tacit version is also not too bad: >>> > >>> > [: +/ [: > (>./ - <./)&.> >>> > >>> > As a beginner I am kind of suspicious of tacits with a lot of cap. It >>> looks to me like humans usually generate tacits with @: or @ instead, and >>> while it seems to me that "[: f g" ought to transform into "f @: g" 100% of >>> the time, it doesn't seem to be quite right when I try it. >>> > >>> > For part two, the conditions change to finding two values such that one >>> divides the other and then taking the result of that division for each row, >>> summing up the result of the divisions. >>> > >>> > My first thought was to form the cross product of the divisors, but you >>> get spurious results along the diagonal arising from checking values >>> against themselves. So then I was building the identity matrix to mask that >>> out and then using the (shape shape) #: , I. trick to convert the result >>> back into coordinates, so I could use { to obtain the values, so I could >>> then … and it just felt a bit like a Rube Goldberg device, so I did some >>> chores. >>> > >>> > When I came back I had realized that I could avoid a great deal of that >>> work by just multiplying the division result by my conditions (x and y not >>> being equal, x and y being divisors) and then discard the zeros, so I came >>> up with this: >>> > >>> > checksum2 =. monad def '+/ 0 -.~ ,y ((0=|) *. ~: *. (% >. %~))"(0 1) >>> y' >>> > >>> > The tacit (% >. %~) is standing in for "do the division whichever way >>> works". So you can see the conditions inside that largeish tacit. I could >>> probably put a reflex operator on there and not pass y in again on the x >>> side, I'm realizing right now. 0 -.~ is discarding the zeros and then I sum >>> up the difference. >>> > >>> > Unlike the first, this one is expecting a rectangular matrix rather >>> than a list of boxes, and I obviously profited from that decision and >>> should go back and revisit my first solution. >>> > >>> > It still feels a bit like more code than there is work to do, but I'm >>> pleased that I got to the solution. >>> > >>> > Tacit version of checksum2 is >>> > >>> > 13 : '+/ 0 -.~ ,y ((0=|) *. ~: *. (% >. %~))"(0 1) y' >>> > [: +/ 0 -.~ [: , ((0 = |) *. ~: *. % >. %~)"0 1~ >>> > >>> > Ah, see it threw a reflex on the end. >>> > >>> > Very fun! Thanks for reading, >>> > >>> > -- >>> > Daniel Lyons >>> > >>> > >>> > >>> > >>> > ---------------------------------------------------------------------- >>> > 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
