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

Reply via email to