22
\$\begingroup\$

Here's a very simple little problem that I don't believe has been asked before.

Challenge

Write a program or a function that takes in four positive integers that represents the lengths of movable but unbreakable and unbendable straight fences. Output the area of the largest rectangular yard that can be fully encompassed with these fences.

The fences can be moved and rotated in increments of 90°, but can't overlap or be cut. Fences that just touch at a yard corner still count as encompassing the yard at that corner.

For example, given fence lengths 2, 8, 5, and 9, the best you can do is to make the 2 and 5 sides parallel, and the 8 and 9 sides parallel for a yard that is 2 by 8:

 888888885
2yyyyyyyy5
2yyyyyyyy5
9999999995
         5

Make any one side longer and the fences won't fully surround the yard. Thus the output here, the area of the yard, would be 16.

As another example, given 1, 1, 2, 2, the largest area yard that can be made is 2:

 22
1yy1
 22

A yard with area 1 like

22
1y1
 22

is a valid yard since it's perimeter is fully fenced, but 1 is an invalid output since it's not maximal.

This is so the shortest program wins!

You may not assume the 4 integer inputs to your program are in any particular order.

Here are some more test cases:

Inputs -> Output
1,1,1,1 -> 1
1,2,3,4 -> 3
4,3,2,1 -> 3
90,1,2,1 -> 2
1,90,1,1 -> 1
44,51,50,36 -> 1800
3,3,3,3 -> 9
3,3,3,4 -> 9
3,4,3,4 -> 12
4,4,3,4 -> 12
4,4,4,4 -> 16
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to the site! I suggest you add a few more test cases so we can check our answers \$\endgroup\$
    – Luis Mendo
    May 9 at 23:00
  • 1
    \$\begingroup\$ @LuisMendo That's a good idea. I can do that. \$\endgroup\$
    – blaketyro
    May 9 at 23:01
  • 2
    \$\begingroup\$ One could generalize the problem to allowing trapezoids, etc. Maybe that would be one for another day ... \$\endgroup\$ May 11 at 13:37

25 Answers 25

13
\$\begingroup\$

Python, 28 bytes

lambda*a:min(a)*sorted(a)[2]

It's an anonymous function that when called returns the answer, like func(2,8,9,5) -> 16 or func(1,1,2,2) -> 2.

Unless I'm totally misunderstanding my own problem, I believe it can be solved by sorting the 4 input numbers and taking the smallest times the second biggest, since those sides will be matched parallel with the second smallest and the biggest respectively.

Like if the sorted inputs are a <= b <= c <= d then the biggest rect you can make will have area a * c, where side a is parallel to b and c parallel to d, and some of the b and d fences may have to be wasted.

(I'm a new user here so I'd love to know if this Python can be shortened at all. Thanks!)

\$\endgroup\$
8
  • 4
    \$\begingroup\$ a.sort()or a[0]*a[2] seems to be shorter. Also under our rules for function submissions you don't need to name functions unless they're recursive. \$\endgroup\$
    – Neil
    May 9 at 23:49
  • 1
    \$\begingroup\$ Does this actually work? Isn't a a tuple and can't be sorted in-place? \$\endgroup\$
    – loopy walt
    May 10 at 0:39
  • 4
    \$\begingroup\$ I believe lambda*a:min(a)*sorted(a)[2] works and is shorter. \$\endgroup\$
    – loopy walt
    May 10 at 3:59
  • 2
    \$\begingroup\$ @loopywalt Sorry, I had forgotten that I had changed the input format to a list of four elements, not that it matters now that you have a shorter version. \$\endgroup\$
    – Neil
    May 10 at 7:12
  • 3
    \$\begingroup\$ For future reference, we recommend waiting a day or two to answer your own question, just to let others give it a try before "revealing" an answer you might already know. Obviously, there's no issue with this answer - in fact, the opposite, it's a very elegant approach to the challenge - but allowing others to give the challenge an attempt before posting a solution you've likely already found is a good move :) \$\endgroup\$ May 13 at 0:50
7
\$\begingroup\$

Vyxal g, 27 bitsv1, 3.375 bytes

sI÷*

Try it Online!

What I was thinking is that the side lengths can be split into two groups: those likely to be the long side of the rectangle and those likely to be the short side.

The long side of the rectangle will be the second most longest side, as it's guaranteed to be smaller or equal to than the other longer side.

The short side of the rectangle will be the shortest side, as it's guaranteed to be smaller than or equal to the other short side.

For example:

[2, 5, 8, 9]

The side length of 9 can't be the long side because there's no matching 9. But the side length of 8 can be because it's got that length in the 9. Hence, the second smallest length is the long side.

The side length of 5 can't be the short side, because there's no matching 5. But the side length of 2 can be because it's got that length in 5. Hence the smallest length is the short side.

Explained

sI÷*
s    # sort the list ascending. The idea here is that the sides that are more likely to be the longer sides go to the end of the list and the ones likely to be the shorter sides go to the front. 
 I    # split the list into two halves - [shorts, longs] 
  ÷*  # dump each item onto the stack and multiply each item in shorts by each item in long. 
# the g flag gets the smallest item of that list, which is also the first item. 
\$\endgroup\$
13
  • \$\begingroup\$ The word "bits" seems to point to a footnote, but I can't find it? \$\endgroup\$
    – Luis Mendo
    May 9 at 22:55
  • \$\begingroup\$ @LuisMendo that's not a footnote - that's the vyncode version used for scoring. I do admit it's a little confusing but it was what I came up with at the time. Would a subscript still lead to confusion? \$\endgroup\$
    – lyxal
    May 9 at 23:01
  • \$\begingroup\$ Yes, I think that's confusing, and the subscript would too. (Personally, I find scoring in bits already confusing). Perhaps it will be clearer if you put the link on the superscript, rather than on "bytes" \$\endgroup\$
    – Luis Mendo
    May 9 at 23:04
  • \$\begingroup\$ @LuisMendo So something like xx bits <sup>[v1](vyncode link)</sup>? \$\endgroup\$
    – lyxal
    May 9 at 23:06
  • \$\begingroup\$ Yes, that would be clearer, at least to me. I presume I cannot convince you that scoring in bits is a mess and we should stick to good old bytes, can I? :-) \$\endgroup\$
    – Luis Mendo
    May 9 at 23:07
7
\$\begingroup\$

Ly, 7 bytes

&napfp*

Try it online!

Similar to other solutions, this sorts the numbers the messes with the stack to get the smallest and second largest. Then it multiples them to get the answer.

&n       - read in all the numbers
  a      - sort
   p     - discard top (largest)
    f    - flip two entries (pushes 2nd largest down)
     p   - discard top (3rd largest)
      *  - multiple what's left (smallest and 2nd largest)
         - exits and prints what's on the stack as a number
      
\$\endgroup\$
7
\$\begingroup\$

Excel, 22 bytes

=MIN(A:A)*SMALL(A:A,3)

The SMALL() function finds the nth smallest number in a range.

ScreenshotA

ScreenshotB

\$\endgroup\$
6
\$\begingroup\$

Nekomata, 4 bytes

o;*ṁ

Attempt This Online!

o;*ṁ
o       Sort
 ;      Nondeterministically split the list into two parts
  *     Multiply; fails if the two parts have different lengths
   ṁ    Take the minimum
\$\endgroup\$
6
\$\begingroup\$

Julia, 24 21 bytes

-3 bytes: by @MarcMush

!a=(b=sort(a))[1]b[3]

Attempt This Online!

\$\endgroup\$
1
5
\$\begingroup\$

Arturo, 20 bytes

$->a[sort'a a\0*a\2]

Try it

Sort the lengths then multiply the first by the third. Same algorithm as blaketyro arrived at independently.

\$\endgroup\$
5
\$\begingroup\$

Bash + Linux utilities, 19

sort -n|dc -e??k?*p

Reads input from lines of STDIN.

Explanation

sort -n              # sort numerically
       |             # pipe to ...
        dc -e        # ... dc expression
             ??      # push [1] and [2]
               k     # pop [2] to precision register (unused)
                ?    # push [3]
                 *   # pop and multiply [1] and [3]
                  p  # print

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Jelly, 4 bytes

Ṣm2P

A monadic Link that accepts a list of the four fence lengths and yields the maximal yard area.

Try it online!

How?

Ṣm2P - Link: list of integers, F
Ṣ    - sort -> [a, b, c, d]
 m2  - modulo-2 slice -> [a, c]
   P - product -> a × c
\$\endgroup\$
5
\$\begingroup\$

R, 28 bytes

function(l)min(l)*sort(l)[3]

Try it online!

-2 bytes thanks to pajonk.

R, 30 bytes

function(l)prod(sort(l)[!0:1])

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ That's neat, but a straightforward approach is -2 bytes :-P \$\endgroup\$
    – pajonk
    May 31 at 9:52
  • \$\begingroup\$ @pajonk aw, nuts. \$\endgroup\$
    – Giuseppe
    May 31 at 13:30
4
\$\begingroup\$

J, 8 bytes

]`*/@\:~

Attempt This Online!

Sort down, then reduce from the right by alternatingly taking the right value and multiplying:

    \:~2 8 5 9
9 8 5 2
    ]`*/9 8 5 2
9]8*5]2 -> 9]8*2 -> 9]16 -> 16
\$\endgroup\$
1
  • \$\begingroup\$ Very clever application of gerund / \$\endgroup\$
    – Jonah
    Sep 11 at 19:31
4
\$\begingroup\$

Factor + math.unicode, 19 bytes

[ sort <evens> Π ]

Attempt This Online!

Sort the input, get the elements at even indices, then take the product.

\$\endgroup\$
3
\$\begingroup\$

Retina, 26 bytes

N`
.+¶.+¶(.+)¶.+
$.($&*$1*

Try it online! Takes input on separate lines but link is to test suite that splits on commas for convenience. Explanation: Port of @blaketyro's Python answer.

N`

Sort numerically.

.+¶.+¶(.+)¶.+
$.($&*$1*

Multiply the first number by the third.

\$\endgroup\$
3
\$\begingroup\$

Charcoal, 13 bytes

I×⌊θ⌈Φθ⁻κ⌕θ⌈θ

Try it online! Link is to verbose version of code. Takes input as a list of four elements. Explanation:

   θ            Input list
  ⌊             Take the minimum
 ×              Multiplied by
      θ         Input list
     Φ          Filtered where
        κ       Current index
       ⁻        Subtract i.e. is not equal to
            θ   Input list
           ⌈    Take the maximum
         ⌕      First index in
          θ     Input list
    ⌈           Take the maximum
I               Cast to string
                Implicitly print
\$\endgroup\$
3
\$\begingroup\$

Pyth, 5 bytes

*F%2S

Try it online!

Explanation

*F%2SQ    # implicitly add Q
          # implicitly assign Q = eval(input())
    SQ    # sort Q
  %2      # take every other element (so first and third)
*F        # reduce on multiplication
\$\endgroup\$
3
\$\begingroup\$

Scala, 25 bytes

Saved bytes thanks to the comments of @corvus_192 and @user


Golfed version (25 bytes). Try it online!

a=>a.min*a.sorted.tail(1)

Alternative:

//scala 3
import scala.util.chaining._
def f(a:Int*):Int = a.sorted.pipe(a=>a(0)*a(2))
\$\endgroup\$
2
3
\$\begingroup\$

Thunno 2 M, 4 bytes

Ṡz€p

Attempt This Online!

Explanation

Ṡz€p  # Implicit input
Ṡ     # Sort in ascending order
 z    # Uninterleave ([a, b, c, d] -> [[a, c], [b, d]])
  €p  # Product of each inner pair
      # Implicit output of minimum (M flag)
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 4 bytes

{ιPß

Try it online or verify all test cases.

Explanation:

{     # Sort the (implicit) input-quartet from lowest to highest
 ι    # Uninterleave it into two parts: [a,b,c,d]→[[a,c],[b,d]]
  P   # Get the product of both inner lists
   ß  # Get the minimum of this pair
      # (which is output implicitly as result)
\$\endgroup\$
2
\$\begingroup\$

Japt -g, 5 bytes

Íó Ë×

Try it or run all test cases

Íó Ë×     :Implicit input of array
Í         :Sort
 ó        :Uninterleave
   Ë      :Map
    ×     :  Reduce by multiplication
          :Implicit output of first element
\$\endgroup\$
2
\$\begingroup\$

Desmos, 19 bytes

f(l)=l.minl.sort[3]

Try It On Desmos!

Port of literally all the other answers here.

\$\endgroup\$
2
\$\begingroup\$

Perl 5 -pa, 30 bytes

$_=(@F=sort{$a-$b}@F)[0]*$F[2]

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Ruby, 21 bytes

->*l{l.sort![2]*l[0]}

Try it online!

Nothing particularly original here.

\$\endgroup\$
2
\$\begingroup\$

BQN, 7 bytes

×´0‿2⊏∧

Try it

      ∧ # ascending sort
  0‿2⊏  # select first and third elements
×´      # product
\$\endgroup\$
2
\$\begingroup\$

C (gcc), 59 bytes

g(a,b)int*a,*b;{b=*a-*b;}f(int*l){qsort(l,4,4,g);*l*=l[2];}

Try it online!

Takes a 4-element integer array as input and stores the result in the first element of that array. It can probably be shortened, but it's still one of my better submissions :)

Explanation:

// This will be used as a comparison function for qsort(), so that
// integers can be sorted in ascending order.
g(a,b)int*a,*b;
{
    b=*a-*b;
}

f(int*l)
{
    // Sort l, assuming it has 4 elements with element size 4 (which is usually 
    // the size of integers in bytes), and using g() as a comparator.
    qsort(l,4,4,g);
    
    // Stores the first (minimum) element of l times the second-largest element 
    // in the first element of l.
    *l*=l[2];
}

46-byte version using some complicated flag (-zexecstack), suggested by @ceilingcat:

f(int*l){qsort(l,4,4,"\x8b\7+\6ð");*l*=l[2];}

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

Lua, 35 bytes

table.sort(arg)print(arg[1]*arg[3])

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.