That problem took a lot of reading!

Like you, Brian, I started with the boustrophedon cycles:
   example   NB. my data has 2 rows:   depth,: range:
0 1 4 6
3 2 4 4

(Brian forms the data into a simple vector of ranges
3 2 0 0 4 0 4  )

My verb, cycle, is used to assemble a look-up table of scan positions.

   (7$(delay |. cycle)) every <: 3 2 4 4  [ delay =. 0 NB. delay needed 
for part 2
0 1 2 1 0 1 2
0 1 0 1 0 1 0
0 1 2 3 2 1 0
0 1 2 3 2 1 0
Note that the period for a range of r is 2 * (r - 1),  and that the 
third and fourth
row (origin 1!) are identical.

My problem data had 40 odd pairs,  with depth between 0 and 92,  but 
only 12 distinct values for range,  so I set up 12 cycles of length 
93,  and
looked up the one I needed for each depth used in a make-once use-often
table. 

The function below does part 1 - and tries to do part 2 - with a 
negative
left argument repesenting the trial delay - its right argument is the 2 
row
representation of the given input.   (It grew rather more complicated 
than
necessary for part 1 in order to try to solve part 2.)

dostates=: 3 : 0
0 dostates y
:
if. x > 0 do. e =. echo else. e =. ] end.  NB. debugging stuff
'd r' =. y
s     =. 0#~#r
l     =. *./ +: <: r                                     NB. lcm of 
cycle lengths
if. x < 0 do.
   delay =. - 0 <. x
else.
   delay =. 0
end.
c     =. ((l <. 2 + >./d) $ (delay |. cycle)) every <: ur =. ~.r NB. 
look-up table of range-positions
e (;~$) c
t     =. 0
max   =. >:>./d
if. x > 0 do. max =. | x <. max end.
for_layer. i.max do.
   if. layer e. d do.
      id     =. d i. layer          NB.
      rlayer =. id{r                NB. which range
      rlu    =. ur i. rlayer        NB. where in nub of ranges
      scanid =. (<rlu, layer) { c   NB. scan position
      if. scanid = 0 do.
          e 'caught'; layer, rlayer
          t =. t + (delay~:0) + layer * rlayer * delay = 0
      end.
   end.
if. x * x < >:>./d do. e layer; d,: (ur i.r) { (l|layer) {"1  c end.
end.
t
)

It works ok, as does Brian's corrected function:
   ts'day13  datas'
0.0338706 8448
   ts'dostates  input13'
0.000846644 25728

But then I realised this does the job even better! :-
   13 : '+/*/y{"1~ I. 0 =|~/({.,: (2*(<:@{:)))y' input13
1580

That is,  the probe is detected by "scanners" for those pairs
where a range's cycle period divides the corresponding depth.
It is faster than both the above loopy functions,  uses
more space than Brian's,  less than mine.
   ts '13 : ''+/*/y{"1~ I. 0 =|~/({.,: (2*(<:@{:)))y'' input13'
5.18354e_5 12288

The following variant shows how I managed to do part 2,  albeit
very slowly!
   10 (13 : '+/*/y{"1~ I. 0 =|~/(0,~x) + ({.,: (2*(<:@{:)))y') example
0
ie,  you add the delay to the cycle period,  so that now
(a range's cycle-period plus the delay) divides the corresponding 
depth.
We seek the lowest delay such that for none of these modified pairs
is the period-plus-delay a divisor of the depth. 

I suspect there's a better way for part 2,  but haven't looked!

Cheers,

Mike



On 21/12/2017 12:08, Brian Schott wrote:
> I found my error.
> ud =: i. , }:@}.@i.@-  NB. added }:@
>
> Also, the approach is very inefficient, but works, now.
>
> On Wed, Dec 20, 2017 at 6:29 PM, Brian Schott <schott.brian@gmail.
com>
> wrote:
>
>> I am getting the wrong answer for part 1 of day 13.
>> Can someone give me a hint what I am misunderstanding?
>>
>> My main verb is day13, but it depends on the following simple verbs.
>>
>>    ud =: i.,}.@i.@-
>>    spos =: [{.@:|."0 1 ud@]
>>    (i. 6) spos"0/ ]3 2 0 0 4 0 4
>> 0 0 0 0 0 0 0
>> 1 1 0 0 1 0 1
>> 2 0 0 0 2 0 2
>> 1 0 0 0 3 0 3
>> 0 1 0 0 2 0 2
>> 0 0 0 0 1 0 1
>>
>>
>>    day13 =: verb define
>> ranges =. y
>> severity =. 0
>> for_secs. i. # ranges do.
>>    state =. secs spos"0 ranges
>>    if. 0 = secs { state do.
>>       if. secs{ ranges do.
>>          severity =. severity+secs*secs{ranges
>>       end.
>>    end.
>> end.
>> severity
>> )
>>    day13 3 2 0 0 4 0 4
>> 24
>>    day13 $.^:_1 datas
>> 2052
>>
>>
>>
>> For more completeness, my data collection used the following ideas.
>>
>> datam =: data rplc ':';' '
>> datas =: ({:|: ". ;._2 datam)({.|: ". ;._2 datam)} 1 $. 99
>>
>> TIA,
>>
>> --
>> (B=)
>>
>

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to