I came to this a bit late,  partly because I was singing Advent & Christmas
Carols!

There was a spiral constructor that around in an old script;  it serves
its purpose!   Best to call it with an odd argument,  so that it ends nicely on
an odd square lower right corner.  It's slower and fatter than Raul's verb.

Using the "spiral" function merely to study the part 1 question,  I came up with a fairly algorithmic answer rather than seeking the coordinates of the required
point,  see "steps" below,  so its time and space are small.

I _did_ use spiral for part 2,  rather than seek a formula.  Called "part2", it's listed below.  The optional left argument specifies the size of the spiral
whose maximum entry we hope exceeds the search value.

It's quite fast and slim.

Mike


ring     =: <.@>:@-:@>.@%:   NB. which "ring"?
    ring 1 12 23 1024

1 3 3 17

NB. yval is a misnomer - I assumed the value was on
NB. a vertical side,  and this is the displacement
NB. from the row containing 1
yval =: (] (] |@- (+:@]) | (- *:@>:@+:)) <:@ring)
NB. Manhattan distance...
steps =: yval <:@+ ring

NB.    steps 312051      NB. my problem...
NB. 430


NB. for pedestrian spirallers
NB. with default lhs,  rhs is an appropriate odd
NB. square root of a bottom right-hand corner
spiral    =: 3 : 0
(1 1$1) spiral y
:
n2    =. *: n =. y
old   =. x
new   =. (>: i. n2 ) -. , old
rotate=. |."1 @ |:
if. * # new do.
 for. i. 4 do.
  old  =. rotate old,. |. (nadd =. #old) {. new
  new  =. nadd }. new
 end.
 old spiral n
else. old
end.
)

NB.  part 2 - I assumed (or perhaps knew) that spiral ending in
NB. position 121 would suffice
part2 =: 3 : 0
11 part2 y
:
v     =. y
s     =. spiral x    NB. spiral matrix
NB. coordinates relative to the centre,  1
c     =. (}. -~"1 {.) (1, >:i.*:x) (#@] #. inv (i.~,))s

NB. 8 coordinate offsets for any neighbour are coords of second ring
m     =. }.9{. c     NB. assumes at least two rings!

NB. indices of every set of 8 neighbours
NB. - wrong for outside ring, but who cares?
n     =. (<:*:x) <. c i. c +"1 / m

NB. initialise "memory"
vals  =. 1{.~ *:x
for_i. }. i.*:x do.   NB. just loop through positions 2 3 ... !
   ni   =. i{n
   add  =. +/ vals{~ ni
   vals =. add i} vals
   if. add > y do.
      ii =. i
   break. end.
end.
ii; (ring ii); add    NB. add is the required entry value
)

NB.    10 part2 312051
NB. ┌──┬─┬──────┐
NB. │60│5│312453│
NB. └──┴─┴──────┘











---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to