I believe this problem requires checking every possible height of the
rectangle. I've come up with something like below, that seems to be an
improvement:

  6!:2 'a =: maxsq arr'
0.860414
   6!:2 'b =: >./,(+**@[)/\.|:(*<:/~) arr'
4.47701
   a -: b
1

NB.  maxsq: find the maximum square over the set of each unique height
NB.  nsq: max square of height x: mark positions where the height exceeds
the value, determine the maximum length of uninterrupted sequence by
subtracting adjacent positions, get square by multiplying to the height
chosen


ceilpos =:  ceilpos =: 0: , (I.@:>) , (#@:])
maxbitlen =: 13 : '<: >./ 2-~/\y'
nsq =: ([* maxbitlen@:ceilpos)"0 1
maxsq =:  ([:>./ ~.nsq])f.

arr =: 10000?.1000000


2017-06-20 23:43 GMT+03:00 Raul Miller <rauldmil...@gmail.com>:

> Hmm... maybe I should have just gone out and shown how I approached
> the problem...
>
> (but feel free to hold off on reading this post, or replies to it, if
> you are wanting to solve it on your own and you think you understand
> the problem description).
>
> And, perhaps, I should add that that drdobbs writeup is a more general
> problem than the one I'm proposed. There you start with a boolean
> array, instead of a list of bar lengths.
>
> So, anyways, we need some kind of representation of which bars are
> lower than which other bars. Something like this:
>
>    <:/~2 6 7 4 1 7
> 1 1 1 1 0 1
> 0 1 1 0 0 1
> 0 0 1 0 0 1
> 0 1 1 1 0 1
> 1 1 1 1 1 1
> 0 0 1 0 0 1
>
> Next, to calculate area, we'll need to know how high each of those bar
> representations are. We can get that by multiplying each length by the
> corresponding "relevant height" bits:
>
>    (* <:/~)2 6 7 4 1 7
> 2 2 2 2 0 2
> 0 6 6 0 0 6
> 0 0 7 0 0 7
> 0 4 4 4 0 4
> 1 1 1 1 1 1
> 0 0 7 0 0 7
>
> Now we just need to add them up, stopping when we hit a zero. We could
> use a rank 1 scan, but since our operation is going to be a bit
> complex maybe it makes more sense to work on the transpose of that
> array:
>
>    |: (* <:/~)2 6 7 4 1 7
> 2 0 0 0 1 0
> 2 6 0 4 1 0
> 2 6 7 4 1 7
> 2 0 0 4 1 0
> 0 0 0 0 1 0
> 2 6 7 4 1 7
>
> Now... when building up a scan, it's worth starting with a
> representative pair of arguments and figuring out what operation we
> want on them. In other words something to go in the parenthesis, here:
>
>    0 0 0 0 1 0 () 2 6 7 4 1 7
>
> Given our description of adding them up and stopping at zeros, I went
> with (+ * *@[)
>
>    0 0 0 0 1 0 (+ * *@[) 2 6 7 4 1 7
> 0 0 0 0 2 0
>
> In other words:
>
>    (+ * *@[)/\. |: (* <:/~)2 6 7 4 1 7
> 8  0 0  0 6 0
> 6 12 0 12 5 0
> 4  6 7  8 4 7
> 2  0 0  4 3 0
> 0  0 0  0 2 0
> 2  6 7  4 1 7
>
> We can see all the various rectangle areas here, and we just need to
> find the largest:
>
>    >./ , (+ * *@[)/\. |: (* <:/~)2 6 7 4 1 7
> 12
>
> Now... that works reasonably well up to a point, but time and space
> are proportional to the square length of the list of bar lengths.
>
> In other words, this is reasonably fast:
>
>    >./ , (+ * *@[)/\. |: (* <:/~) 1000?.1000000
> 7030779
>
> ... but this is not so fast:
>
>    >./ , (+ * *@[)/\. |: (* <:/~) 10000?.1000000
> 9694475
>
> Anyways, I believe that it should be possible to solve this quite a
> bit more quickly, but I have not worked out how yet.
>
> Thanks,
>
> --
> Raul
>
>
> On Tue, Jun 20, 2017 at 1:03 PM, Joe Bogner <joebog...@gmail.com> wrote:
> > possible spoiler -
> > http://www.drdobbs.com/database/the-maximal-rectangle-problem/184410529
> >
> > At a minimum, it help explains the problem
> >
> >
> >
> > On Tue, Jun 20, 2017 at 1:02 PM, Xiao-Yong Jin <jinxiaoy...@gmail.com>
> > wrote:
> >
> >> Brute force:
> >>
> >>     (\:*/"1);<@:((#,<./)\.)\2 6 7 4 1 7
> >> 2 6
> >> 3 4
> >> 4 2
> >> 2 4
> >> 1 7
> >> 1 7
> >> 1 6
> >> 3 2
> >> 6 1
> >> 5 1
> >> 5 1
> >> 2 2
> >> 1 4
> >> 4 1
> >> 4 1
> >> 3 1
> >> 3 1
> >> 1 2
> >> 2 1
> >> 2 1
> >> 1 1
> >>
> >> Though the complexity looks like n^3 to me.  There must be a more
> >> efficient algorithm.
> >>
> >> > On Jun 20, 2017, at 10:29 AM, Raul Miller <rauldmil...@gmail.com>
> wrote:
> >> >
> >> > Something I stumbled over today.
> >> >
> >> > If we have a series of bars of varying height, what's the largest
> >> > rectangle that can be drawn over the bars without covering any empty
> >> > space.
> >> >
> >> > For example:
> >> >
> >> >   '*'#"0~2 6 7 4 1 7
> >> > **
> >> > ******
> >> > *******
> >> > ****
> >> > *
> >> > *******
> >> >
> >> > I'll post a solution later, and I'll be interested in seeing if it's
> >> > basically the only obvious approach or if there's a variety of good
> >> > approaches. (I have reason to believe, though, that there's a better
> >> > way than what I came up with.)
> >> >
> >> > Thanks,
> >> >
> >> > --
> >> > Raul
> >> > ------------------------------------------------------------
> ----------
> >> > 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
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to