7
\$\begingroup\$

In my last challenge, you were asked to find all rectangles given a m x n grid of them. However, it turned out to be very trivial as there actually was a mathematical formula I did not even know about to solve the problem! So now, for a little bit more of a challenge, how about calculating the number of unique rectangles, i.e. find the number rectangles that are all of different dimensions?

For example, consider 4 horizontal, or y lines at [-250,-50,50,250] and 4 vertical, or x lines at [-250,-70,70,250]. Graphing these on a coordinate plane with infinite dimensions results in the following 500 x 500 pixel closed grid, in which the length of each segment in pixels and the lines corresponding to their respected values from the arrays are shown:

Example

which contains the 16 unique rectangles shown in this animated GIF:

All unique Rectangles in Example

However, if the topmost line (y = 250) were to be removed, there would only be 12 unique rectangles, as the top 3 rectangles would be factored out since they each won't be fully closed without the y = 250 line.

Task

So, as shown above, the task is counting the number of rectangles rectangles with different dimensions. In other words, given an input of 2 arrays, with the first one containing all equations of all x lines, and the latter containing those of all y lines, output the total number of rectangles of different dimensions created when the lines corresponding to those equations are graphed on a coordinate plane.

Rules

  • The use of any built-ins that directly solve this problem is explicitly disallowed.

  • If either of the arrays have less than 2 elements, the output should be 0, since if there are less than 4 lines on the plane, there are no closed, 4 sided figures.

  • The input arrays are not guaranteed to be sorted.

  • You can assume that there are not any repeated values in either of the the input arrays.

  • A n x m rectangle is the same as a m x n rectangle. For example, a 300 x 200 rectangle is the same as a 200 x 300 one.

  • Standard loopholes are prohibited.

Test Cases

Given in the format Comma Separated Arrays Input -> Integer output:

[],[] -> 0
[-250,-50,50,250],[-250,-70,70,250] -> 16 (Visualized above)
[-250,-50,50,250],[-250,-70,70] -> 12
[-40, 40],[-80, 50] -> 1
[10],[10] -> 0
[60, -210, -60, 180, 400, -400], [250, -150] -> 12
[0,300,500],[0,300,500] -> 6
[0,81,90],[0,90,100] -> 9

Remember, this is , so shortest code wins!

asked Aug 3, 2016 at 5:15
\$\endgroup\$
5
  • \$\begingroup\$ [[0,300,500],[0,300,500]] should probably be a test case \$\endgroup\$ Commented Aug 3, 2016 at 5:43
  • \$\begingroup\$ @Sp3000 All right. I'll add that one as soon as possible. \$\endgroup\$ Commented Aug 3, 2016 at 5:44
  • \$\begingroup\$ @Sp3000 It's added. \$\endgroup\$ Commented Aug 3, 2016 at 7:00
  • \$\begingroup\$ @PeterTaylor Yeah, you're right. There are 6. I forgot to count the entire square itself! It's updated now. \$\endgroup\$ Commented Aug 3, 2016 at 7:57
  • \$\begingroup\$ @PeterTaylor Okay. Added. \$\endgroup\$ Commented Aug 3, 2016 at 10:02

5 Answers 5

6
\$\begingroup\$

JavaScript (ES6), 99

(X,Y,Z=new Set)=>X.map(v=>X.map(t=>t>v&&Y.map(w=>Y.map(u=>u>w&&Z.add([u-w,t-v].sort()+0)))))|Z.size

Note: sort is not numeric but lexicographic, but in this specific case I don't care

Less golfed

(X, Y, Z = new Set) =>
 X.map(
 v => X.map(
 t => t>v && Y.map(
 w => Y.map(
 u => u>w && Z.add([u-w, t-v].sort() + 0)
 )
 )
 )
 ) | Z.size

Test

F=(X,Y,Z=new Set)=>X.map(v=>X.map(t=>t>v&&Y.map(w=>Y.map(u=>u>w&&Z.add([u-w,t-v].sort()+0)))))|Z.size
 
;[
 [[],[], 0]
,[[-250,-50,50,250],[-250,-70,70,250], 16]
,[[-250,-50,50,250],[-250,-70,70], 12]
,[[-40, 40],[-80, 50], 1]
,[[10],[10], 0]
,[[60, -210, -60, 180, 400, -400], [250, -150], 12]
,[[0,300,500],[0,300,500], 6]
].forEach(t=>{
 var a=t[0],b=t[1],k=t[2],r=F(a,b)
 
 console.log(r==k?'OK':'KO','['+a+']','['+b+']',r)
})

answered Aug 3, 2016 at 8:48
\$\endgroup\$
3
\$\begingroup\$

Jelly, 13 bytes

ṢIẆS€μ€ŒpṢ€QL

Try it online!

A rectangle is uniquely defined by its height and its width.

ṢIẆS€μ€ŒpṢ€QL Main chain, argument: z
 μ€ For each subarray:
Ṣ sort
 I compute consecutive increments
 Ẇ yield all substrings
 S€ compute sum of each substring
 Œp Cartesian product
 Ṣ€ Sort each
 Q Remove duplicates
 L Length
answered Aug 3, 2016 at 5:19
\$\endgroup\$
4
  • \$\begingroup\$ Great job! +1 from me! :) \$\endgroup\$ Commented Aug 3, 2016 at 5:20
  • \$\begingroup\$ @PeterTaylor But it does work for that input... \$\endgroup\$ Commented Aug 4, 2016 at 17:52
  • \$\begingroup\$ @R.Kap, was this just because the test case was wrong? \$\endgroup\$ Commented Aug 4, 2016 at 18:01
  • \$\begingroup\$ Actually, it wasn't producing any output when I entered that test case at the time, but that was because I entered it in the wrong format. My bad. It works really well for that test case. Good job. \$\endgroup\$ Commented Aug 4, 2016 at 18:31
3
\$\begingroup\$

CJam (22 bytes)

q~{2m*::-:z0-}/m*:$_&,

Takes input as an array of arrays. Online demo, test suite

Dissection

q~ e# Parse input
{ e# For each of the two elements in the top-level array
 2m* e# Take its Cartesian self-product
 ::- e# Map fold subtraction, giving the separations between lines
 :z e# Map absolute value
 0- e# Remove 0, since trivial rectangles don't count
}/
m* e# Cartesian product of the two sets of separations
:$ e# Sort so that mxn === nxm
_& e# Deduplicate
, e# Count
answered Aug 3, 2016 at 7:25
\$\endgroup\$
3
\$\begingroup\$

MATL, 22 bytes

"@gd&Xfo!s|]Z*!S!Xuz2/

Try it online! Or verify all test cases.

Explanation

" % Implicitly input cell array of two numerical arrays. For each cell
 @g % Push cell contents
 d % Difference of its two entries
 &Xf % Cell array of all substrings
 o % Convert to numerical array, padding with zeros
 !s % Sum of each row. Gives a row vector
 | % Absolute value of each entry
] % End for
Z* % Cartesian product
!S! % Sort each row
Xu % Unique rows
z2/ % Number of unique rows excluding zeros. Implicitly display
answered Aug 3, 2016 at 9:49
\$\endgroup\$
0
\$\begingroup\$

Python, 208 bytes

import itertools as i
def h(x,y):
 s=[]
 k=[p for p in i.product(x,y)]
 for j,(v,w) in enumerate(k):
 for a,b in k[j+1:]:
 q=sorted([abs(a-v),abs(b-w)])
 if 0not in q and q not in s:s+=[q]
 return len(s)
answered Aug 3, 2016 at 13:43
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.