[Question]
  [
Getting the area covered by a rectangle is really easy; just multiply its height by its width. However in this challenge we will be getting the area covered by multiple rectangles. This is equally easy ... so long as the rectangles don't overlap.
If the rectangles don't overlap the total area covered is the sum of the areas of each individual rectangle. However if they do overlap this method will double count the area they intersect.
For example, in the following picture we have 2 rectangles: A rectangle with opposite corners at \$(3,7)\$ and \$(9,3)\$ and a rectangle with opposite corners at \$(8,10)\$ and \$(14,4)\$. On their own they cover \$24\$ and \$36\$ square units respectively. However they have an overlap area of 3 units so the total area covered by the both of them is \$24 + 36 - 3 = 57\$
[![2 Overlapping rectangles](https://i.stack.imgur.com/yZIYB.png)](https://i.stack.imgur.com/yZIYB.png)
# Task
Your task is to take a list of positive integer rectangles as input and output the total area covered by those rectangles.
You may take a rectangle as a pair of pairs representing opposite corners, or as a flattened 4-tuple. You may assume a particular pair of corners in a certain order will be given if you please.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so answers will be scored in bytes with fewer bytes being the goal.
## Test cases
```
[((3,7),(9,3))] -> 24
[((8,10),(14,4))] -> 36
[((3,7),(9,3)),((8,10),(14,4))] -> 57
[((8,10),(14,4)),((3,7),(9,3)),((5,8),(10,3))] -> 61
[((1,1),(8,8)),((2,3),(3,5))] -> 49
```
  
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~60~~ 59 bytes
```
->r,*w{r.map{|a,b,c,d|w|=[*a...c].product [*d...b]};w.size}
```
[Try it online!](https://tio.run/##PcpLCsIwFEbhuavoOPxeLK1okbqRyx3kYcGBGGJLsE3Xnj4Ep985YTDf3LX5eA9QcQr00n5KGgYWLsXUstJEZIV8eLvB9gUrt4KR@Rbp8xwfc/ZFx8wVLmhQicjhB1eUJ5Q1asE/gs/YffvyAg "Ruby – Try It Online")
**Input**: array of array of coordinates: [left, top, right, bottom]
Convert every rectangle to a set of cells, and calculate the size of the union of the sets.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 10 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
r/Ḋ€p/)ẎQL
```
A monadic Link that accepts a list of rectangles each composed of a list of opposing corner coordinates as specified.
**[Try it online!](https://tio.run/##y0rNyan8/79I/@GOrkdNawr0NR/u6gv0@f//f3R0tLGOeaxOtKWOcSyQirbQMTQA0oYmOiaxsbEA "Jelly – Try It Online")**
### How?
Constructs the coordinates of a corner of each unit square of each rectangle, and counts the unique values found in the resulting collection.
```
r/Ḋ€p/)ẎQL - Link: integer rectagle corner coordinates, R
      )    - for each rectangle, r in R:
 /         -   reduce by:
r          -     inclusive range
  Ḋ€       -   dequeue each (we exclude one edge, consistently, from each dimension, as we
                             want "fences", rather than "fence-posts")
     /     -   reduce by:
    p      -     Cartesian product -> all the coordinates we want for the rectangle
       Ẏ   - tighten -> all coordinates used by all rectangles
        Q  - deduplicate
         L - length
```
[Answer]
# [Python 3](https://docs.python.org/3/), ~~76~~ ~~74~~ 73 bytes
```
lambda l:len({(x,y)for*a,b,c in l for x in range(*a)for y in range(b,c)})
```
[Try it online!](https://tio.run/##bVDbboMwDH3nK/xGXHlSuZW2EvsRykOAsKJmFEEmwRDfzpxoVbdpeTo@F8d2P5vrvYu2JrtsWr6XtQR91qoTi5hoxuY@7CSVVEHbgQYuYbJwkN2bEjtpDTA/GXbiiptRoxkhA5ELEVGKJE4UIRYETBwp2DMTxBQ/qB8e@tfwi6K/gYSOVtw//wgcwymnhywQZxKW0VNTryqjajtfGBNEB4IkJTgEBPEJveqqqpsarOxfPsI0rnwCh4LIR89ubEjZnT/bXrhVCR5N8ewBP53lQlJFNZX2RIxLnoBr5JgpnMceqBEaXdEPbWdE4y9mhZdXWMYVlu9BcpVlY7H6uH0B "Python 3 – Try It Online")
*Saved 2 bytes thanks to [att](https://codegolf.stackexchange.com/users/81203/att)!!!*  
*Saved a byte thanks to [Jitse](https://codegolf.stackexchange.com/users/87681/jitse)!!!*
Inputs a list of rectangles as flattened 4-tuples - `(left, right, bottom, top)`.  
Returns the area.
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 30 bytes
```
Area[RegionUnion@@Cuboid@@@#]&
```
[Try it online!](https://tio.run/##bY5La8MwEITv@hVCLcWGNYkT50WIUWhz6K0k7UnooLpKKnAsIysQcP3b3RUJgT4uYndmvh0dlf/UR@VNofr9ql87rcRWH4yt3ip8OH88vVvzwTm/kw/9kxWkNWA7uqKlqfSSGJxe7eZcO900Adh5Z6rDVtelKrQwQFsWsy8mWZKzjgGLcBFhaVknr7xTVVPbRouddX7Ab3vopANOzZK84FUvTJLvuQFGIwYW8LAE0oaPwKV2c/ZOFV7c7wpnav9c1Sd/cYARLF2XJcJJTi@z7GQvomgMsxiiBYzjWAZzlBFU55AOUU4zyK76eEp@puG/1GT2h4bf1ATmwRzeKqdpgFJIUZ6jGUIjdAHByTWTLb4B "Wolfram Language (Mathematica) – Try It Online")
Input a list of `{bottom left, top right}` pairs.
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), 22 bytes
```
#?,/{+a+!(|/x)-a:&/x}'
```
[Try it online!](https://ngn.bitbucket.io/k#eJxtkEsKg0AMQPc5RUqhdTCicTIfHWh7j9pFN55B6OfsjSJWbHcz770QSN/uz1Q+8nu+y57lYIp7eyiH1xGglnd/ocxiSA1aA9ZP/4hcJRYUAy4oyZYirZwBz5P8orQKHcbElT4NSDN1jJwiRnU12mTRqYKuA7jqAgqGsoY0v2FxwlpGGokrxSwkM7d+U9O/yoWfadpOOYqjrJaVnschJlYcVY5RrVbvQ25upPkAZcBBFQ==)
Or, if we can take corners as (lower-left, upper-right) pairs:
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~18~~ 15 bytes
```
#?,/{+x+!y-x}/'
```
[Try it online!](https://ngn.bitbucket.io/k#eJxtkEsKwjAQQPdzihEXJnRKO83fgHoP67ZnqIie3UkoWqq75L03Gch03J+pezRzs7u387M7AAz2NV1IGTQ5YNJgfL1HtJktcq/BBSGqFgmDziunwXOVX5RXoZMT9xils6l2jJyjgKwGcQadKBhHgKssoKBJJTJa37A94WALjSSPkmJLduHGb2r6V7nwM03bKUexyP6z0nMZYmLBUWSJBrHyP+SWxqY3RYQ/cA==)
[Answer]
# JavaScript (ES6), 96 bytes
A very basic solution that tests whether each cell in the grid belongs to at least one rectangle.
Expects a list of flattened 4-tuples.
```
a=>eval(`for(t=0,x=q=Math.max(${a});x--;)for(y=q;y--;)t+=a.some(([a,b,c,d])=>x<a^x<c&&y<b^y<d)`)
```
[Try it online!](https://tio.run/##fY9JDoJAEEX3nMKFId2xQJpBMdDcwBMQCCWDQ9BWIaaJ8ezYGhfGgapVDe//qh1esMnP22NrHERR9hXvkUflBWuSVeJMWm6B5Ce@xHZj7lGS8RVvNJCGEdDHvOOnoHsU7YSj2Yh9SUiMsIIcioTySIaYyjDX9S5cpV1Y0Iz2uTg0oi7NWqxJReLYgTkswEkSSkf/Yjod2a72SfrALGAuuAOsIp2Z9s8TBjQU6c0HPOFNxYNn//WEImfsi2TA1Javtm1wVHo/rlaku@jv "JavaScript (Node.js) – Try It Online")
### How?
When coerced to a string, an array is always turned into a flattened list of values separated with commas. For instance, `[[3,7,9,3],[8,10,14,4]]` is turned into the string `"3,7,9,3,8,10,14,4"`.
As a consequence, `eval(`q = Math.max(${a})`)` loads in `q` the highest value that can be found in `a[]`, no matter the encapsulation depth of any sub-arrays in there.
For each position \$(x,y),\:0\le x<q,\:0\le y<q\$ and each rectangle tuple \$(a,b,c,d)\$, we increment the final result if:
$$((x < a)\operatorname{XOR}(x < c)) \operatorname{AND} ((y < b)\operatorname{XOR}(y < d))$$
Note that \$((x < a)\operatorname{XOR}(x < c))\$ is true iff we have either \$x\in[a,c[\$ or \$x\in[c,a[\$ (ditto for \$y\$, \$b\$ and \$d\$). This means that the corners can be passed in any order, as suggested by the test cases (it turns out that it's actually not a strict requirement).
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 13 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
εøεŸ¨}`â}€`Ùg
```
[Try it online](https://tio.run/##yy9OTMpM/f//3NbDO85tPbrj0IrahMOLah81rUk4PDP9///o6GgLHUODWJ1oQxMdk1ggHW2sYw6kLHWMwTxTHQuQpAGIGwsA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfeX/c1sP7zi39eiOQytqEw4vqn3UtCbh8Mz0/zr/o4HAWMc8VifaUsc4NjZWRwEoYKFjaAAUMTTRMYEJIanRwaoARUgHXYOpjgVI0gBhh6GOIVDEAigOkjcCSugA9ZgCpWMB).
**Explanation:**
```
ε      # Map over each pair of coordinates in the (implicit) input-list:
 ø     #  Zip/transpose; swapping rows/columns
       #  (so we'll have a list [[Xa,Xb],[Ya,Yb]]
  ε    #  Map both to:
   Ÿ   #   Pop the pair, and push a list in this range
    ¨  #   Remove the last item, so the range is [a,b)
  }`   #  After the inner map: pop and push both lists separated to the stack
    â  #  Get the cartesian product of these two lists
}€`    # After the outer map: flatten this list of list of pairs one level down
   Ù   # Uniquify this list of cell-coordinates
    g  # And pop and push its length
       # (after which the result is output implicitly)
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 11 bytes
```
Luṁ(ΠmhṁẊ…T
```
[Try it online!](https://tio.run/##yygtzv7/36f04c5GjXMLcjOA9MNdXY8aloX8//8/OjraWMc8VifaUsc4FkhFW@gYGgBpQxMdk9jYWAA "Husk – Try It Online")
```
Lu              # length of uniqe elements from
  ṁ(            # mapping over input:
    Π           #  cartesian product of:
       ṁ        #   for each coordinate pair
          T     #    transpose
        Ẋ…      #    and get the range,
     mh         #    (removing the last element)
```
[Answer]
# [Julia 1.0](http://julialang.org/), ~~55~~ 52 bytes
```
!t=length(∪([a:~-c.=>(b:d-1)' for(a,b,c,d)=t]...))
```
[Try it online!](https://tio.run/##bY5NboMwEIX3nMJZZUYaUBwgIZFA6gF6AsTCgNu6chwEbpVuuu5ZeqxehI4jFKk/sxp9772Z9/xijZKXeV750mr36J/g6@MTanV8j7ukrKA99rHEtXg4j6CopY56LH2TJAnizFBYYZwYteqtcXoCjASPEqWYBms8WKxlc2WemX5VFu61V8mgxkmDQrxpd@6thpNx/KZDCkvLv@ikLgvhJRAMXQSENkgQ@oRC1zPDaJy3DvhcJVYeI@36uQZIac/WA6WIjYgrsc0ipgXJDWOZUbbwdBf9dNN/rnz/J02/UzkVQdzcXu5kCEmSjAsWg2nLKnEwXzzZ4Rs "Julia 1.0 – Try It Online")
* input is an array of flattened 4-tuples in the order `(left,bottom,right,top)`
* for each rectangle, we create all their points in the form `x=>y` with `(a:c-1).=>(b:d-1)'`
example with `(1,2),(4,6)`:
```
julia> (1:4-1).=>(2:6-1)'
3×4 Matrix{Pair{Int64, Int64}}:
1=>2  1=>3  1=>4  1=>5
2=>2  2=>3  2=>4  2=>5
3=>2  3=>3  3=>4  3=>5
```
* then `∪` (`union`) removes duplicates
* `length` is self-explanatory I think
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~42~~ 40 bytes
```
ＩΣＥ⌈Ｅθ⌈ιΣＥ⌈Ｅθ⌈λ⊙θ∧››§ν²ι›§ν⁰ι››§ν³λ›§ν¹λ
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z@gKDOvRMM5sbhEI7g0V8M3sQCIKzJzoexCHQXHEs@8lNQKjUwdBSNNTU0dBQLqcnQUjMHqHPMqweJ5KRruRamJJalFcBqmNg9kpo5CJhBjkTIASyHJYVFjDJTOwa7dECwFB9b//0dHR1vomOgYApFBrE60sY6xjqWOOZBlCmQZGuhYxMbG/tctywEA "Charcoal – Try It Online") Link is to verbose version of code. Takes input as a list of 4-tuples (bottom, left, top, right). Edit: Saved 2 bytes after reading @Arnauld's answer. Explanation:
```
    Ｅθ                                      Map over input list
      ⌈ι                                    Get maximum co-ordinate
   ⌈                                        Take the maximum
  Ｅ                                         Map over implicit range
           Ｅθ                               Map over input list
             ⌈λ                             Get maximum co-ordinate
          ⌈                                 Take the maximum
         Ｅ                                  Map over implicit range
                θ                           Input list
               ⊙                            Does any rectangle match
                       ι    ι               Current y value
                  ››§ν² ›§ν⁰                Inside rectangle bounds
                                  λ    λ    Current x value
                             ››§ν³ ›§ν¹     Inside rectangle bounds
                 ∧                          Logical And
        Σ                                   Take the sum
 Σ                                          Take the sum
Ｉ                                           Cast to string
                                            Implicitly print
```
A coordinate `x` is within a half-open range `[a, b)` if it is less than `b` but not less than `a`. In normal logic, this is written `(b>x)&&!(a>x)`, however the `&&!` operator works out as equivalent to the `>` operator so the result is simply `(b>x)>(a>x)`.
[Answer]
# Scala, 72 bytes
```
_.map{(?,<,c,d)=>Set(?to c-1*)flatMap(d+1 to<map _.->)}.reduce(_|_).size
```
[Try it in Scastie!](https://scastie.scala-lang.org/zwsNlmexS3mDBgUCawJD7Q)
Does it the simple, stupid way: by making sets of all the points each rectangle contains and then finding the size of their union. Input is a list of flattened 4-tuples, with the top left corner first and the bottom right corner second.
[Answer]
# [Python 3](https://docs.python.org/3/), 83 bytes
```
lambda a:len({*chain(*[product(*map(range,*x))for x in a])})
from itertools import*
```
[Try it online!](https://tio.run/##bY9BDoIwEADvvKLHbbMHayEiiS9BDhWoNIG2qTXBGN9eKwlGjXvbmdnDulsYrBFRHY5xlNOpk0RWY2/gztpBagOsdt521zYAm6QDL825RzZTqqwnM9GGyIY@aKa8nYgOvQ/WjheiJ2d9YPFd1TWAQEER9rijtMEsgRLzBHiOfLOijwb/Bl8Ifw@KZeMbLNeeI0@kfIHkt4sXWCTdVBlJ47w2ARSkn@IT "Python 3 – Try It Online")
-3 thanks to pxeger.
[Answer]
# [Gaia](https://github.com/splcurran/Gaia), 11 bytes
```
N†⊢×⊢
↑¦|⊢l
```
[Try it online!](https://tio.run/##S0/MTPz/3@9Rw4JHXYsOTwcSXI/aJh5aVgNk5fxPBbP/RytER0cbK5jHKkRbKhjHxsaC@BYKhgZAhqGJgglUBEmFAjZ5FBEFdPWmChYgSQO4BYYKhkDaAigM4hoBxRWAWkxBsrEA "Gaia – Try It Online")
```
N†⊢×⊢  -- helper function to convert rectangle corners to coordinate list
N†⊢    -- reduce rows by vectorized half-inclusive range
   ×⊢  -- reduce the two ranges by cartesian product
↑¦     -- map the helper function over each rectangle
  |⊢   -- reduce by set union
    l  -- take the length
```
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 77 bytes
```
x=>x.map(([i,b,c,d])=>{for(;i++<c;)for(j=b;j++<d;)x[y=[i,j]]=s+=!x[y]},s=0)|s
```
[Try it online!](https://tio.run/##fY7NDoIwEITvPgXe2rACFRAIlhdpesAiBqKUUGMw6rPXJV6MP2z2MJPMN7tteSmNGpr@vOp0tbc1tyMvRu9U9oSIBnagoJKUF7daDyRvXHercjrplu/yFm2V01FcOWZbKblx@RKtfIDhAb0bq3Rn9HHvHfWB1ESIEELIIJGSUuff@L6zjhafZAoRMNxghkUy3Cz@3YSZDiTjZOYmvLXEqFgA6asEyQ37IhkwSDECYg0TGf/4Gskos08 "JavaScript (Node.js) – Try It Online")
]