# Trapezoidal Riemann Sum

Given a list of coordinate pairs, output the Trapezoidal Riemann Sum of the values given between the first and last x-coordinates.

You will be given a sorted list of coordinate pairs, like this:

[
[1,2],
[3,5],
[5,11]
]


Note that x-coordinates will always be in increasing order, ys may not.

My way to do this is (you might find a different way):

Get pairs of coordinates:

[1,2],[3,5] and [3,5],[5,11]


• Take the average of the y-values: (2 + 5) / 2 = 7/2

• Take the difference of the x-values: 3 - 1 = 2

• Multiply the two together to get the area of that section, which is 7/2 * 2 = 7.

Do this for all pairs. Let's quickly go through the next, [3,5],[5,11].

Average of y values = (5 + 11) / 2 = 8 Difference of x values = (5 - 3) = 2 Product of the two = 2 * 8 = 16

Now take the sum of all the values, resulting in 16+7 = 23.

# Scoring

This is , shortest wins!

# Testcases

[ [1,2], [3,5], [5,11] ] => 23
[ [3,4], [4,1], [7,5] ] => 11.5
[ [0,0], [9,9] ] => 40.5
[ [1,1], [2,3], [3,1], [4,3] ] => 6


Note that input will always contain non-negative integers. Tell me if any of the testcases are wrong as I worked them out by hand.

You may take a flat list, or the list with x and y swapped.

• Are you sure the second case is 10.5? 1*2.5 + 3*3 seems to equal 11.5 Jun 16, 2021 at 6:40
• @hyper-neutrino That's why I said to check :p Jun 16, 2021 at 6:44
• I assume pairs can be given as [y, x]? Jun 16, 2021 at 6:48
• @dingledooper I assume that positive refers to nonnegative in this context.
– user100690
Jun 16, 2021 at 7:11
• @dingledooper Sorry for the confusion, I meant non-negative, as you can see from #3. Jun 16, 2021 at 9:30

# Ruby, 54 49 47 bytes

->l{(r,=l).sum{|a|x,y,z,w=r+r=a;(y+w)/2r*z-=x}}


Try it online!

# Husk, 11 bytes

ṁΠTzẊe-o½+T


Try it online!

A rare question where you get to use a list of functions!

## Explanation

ṁΠTzẊe-o½+T
T transpose
z        zipwith
e      list of 2 functions:
-      difference
o½+   average
Ẋ       using pairwise reduce
T         transpose back
ṁ           map to and sum:
Π           product


# Python 3, 56 bytes

lambda p:sum((b+d)*(c-a)/2for(a,b),(c,d)in zip(p,p[1:]))


Try it online!

• You can use (c-a) instead of abs(a-c) because "x-coordinates will always be in increasing order"
– G B
Jun 16, 2021 at 6:54
• @G B Missed that part, thanks! Jun 16, 2021 at 6:58

# Jelly, 9 bytes

ạ+ƭ"P¥ƝSH


Try it online!

ạ+ƭ"P¥ƝSH  Main Link
¥Ɲ    For each (overlapping) pair
"       Vectorize; apply to x coordinates then the y coordinates
ƭ        Tie:
ạ          - for the x coordinates, absolute difference
+         - for the y coordinates, sum
P      Product
S   Sum
H  Halve

• -1 if you move the H to the end Jun 16, 2021 at 7:13
• @UnrelatedString you have been ninja'd, my explanation is done already :P Jun 16, 2021 at 7:16
• ...ninjad by 4 minutes, no less hmm Jun 16, 2021 at 7:17

# Jelly, 9 bytes

Ḣ€IḋSƝF$H  Try it online! # and Jelly, 9 bytes ZIḋSƝ}ɗ/H  Try it online! # 05AB1E, 9 bytes I don't think there are as many 9-byters as in Jelly, but here is one: øü+;s¥*O  Try it online!  # implicit input [[1,2],[3,5],[5,11]] ø # tranpose and push x and y seperately to the stack [1,3,5], [2,5,11] ü+ # for y coordinates: sum adjacent numbers [1,3,5], [7,16] ; # halve each value to get means [1,3,5], [3.5,8.0] s # swap to x coordinates [3.5,8.0], [1,3,5] ¥ # get deltas, consecutive differences [3.5,8.0], [2,2] * # element-wise multiplication [7.0,16.0] O # take the sum 23.0  # R, 60 52 bytes function(l)diff(l[1,])%*%(c(l[,-1])+l)[2,-ncol(l)]/2  Try it online! # R, 55 45 bytes function(x,y)diff(x)%*%(y[-sum(x|1)]+y[-1])/2  Try it online! -6 bytes thanks to @Dominic For input as matrix: ### R, 50 bytes function(a)diff(a[1,])%*%(a[2,-ncol(a)]+a[2,-1])/2  Try it online! • If it's Ok to accept a list of xs & a list of ys, I think you can get even shorter... Jun 16, 2021 at 11:07 • Ah, yes, thanks. That lead to further golfing it down. Jun 16, 2021 at 11:42 # Jelly, 9 bytes ×Ø-+PʋƝSH  Try it online! Assumes the second test case is in fact meant to be 11.5. Although I did admit to trying this while it was still in the Sandbox like ten minutes ago, this contains absolutely none of the code I tried while it was there :P # JavaScript (Node.js), 61 bytes n=>n.reduce((z,[a,b],i)=>z+=i--&&(b+n[i][1])*(a-n[i][0])/2,0)  Try it online! Doing it with map is just as long: # JavaScript (Node.js), 61 bytes n=>n.map(([a,b],i)=>z+=i--&&(b+n[i][1])*(a-n[i][0])/2,z=0)&&z  Try it online! Thanks EliteDaMyth for saving 1 byte off both answers (was a general tip) • according to testing, i--&&(...)*(...)/2 is 1 byte shorter than i--?(...)*(...)/2:0 – user100752 Jun 16, 2021 at 7:03 # Python 3, 62 bytes lambda l:sum((y[0]-x[0])*(x[1]+y[1])/2for x,y in zip(l,l[1:]))  Try it online! -2 bytes thanks to @NahuelFouilleul • You can unpack each value of the sublists as well, although that would make your answer identical to dingledooper's. – user100690 Jun 16, 2021 at 7:09 # JavaScript (ES6), 52 bytes Given $$\n\$$ coordinate pairs, this computes $$\\sum_{i=0}^{n-2}(y_i+y_{i+1})/2\times(x_{i+1}-x_i)\$$ recursively. f=([[x,y],...a])=>a+a?([[X,Y]]=a,y+Y)/2*(X-x)+f(a):0  Try it online! # Octave / MATLAB, 6 bytes @trapz  Try it online! # Perl 5 (-p), 56 bytes s;(\d+),(\d+)(?= (\d+),(\d+));$\+=($3-$1)*($2+$4)/2;ge}{


Try it online!

-M5.01 option and say($\),$\=""if$\; header are needed only to run all tests otherwise the program works for one line. example: perl -pe 's;(\d+),(\d+)(?= (\d+),(\d+));$\+=($3-$1)*($2+$4)/2;ge}{' <<< '1,2 3,5 5,11'

trick: -p option with }{ at the end so that continue block is not executed on each iteration but at the end, and $_ is empty so only $\ is printed

deparse: perl -MO=Deparse -pe 's;(\d+),(\d+)(?= (\d+),(\d+));$\+=($3-$1)*($2+$4)/2;ge}{' # Vyxals, 11 bytes ÞT÷2lvṁ$¯ȧ*


Try it Online!

ÞT          # Transpose
÷         # Push each to stack (y is on top
2l       # Groups of 2
vṁ     # Averaged
$# Swap to get x coords ¯ȧ # Deltas * # Multiply the two # Sum that.  There's probably a better way :p # Retina, 63 bytes \d+ * |""L$vm^(_*),(_*)¶\1(_+),(_*)
$.3*$($2$4
^(__)*
$#1 _ .5  Try it online! Takes newline-separated pairs but link is to test suite that splits on semicolons for convenience. Explanation: \d+ *  Convert to unary. |""L$vm^(_*),(_*)¶\1(_+),(_*)


Match overlapping sets of four values from two lines.

$.3*$($2$4


Multiply the difference between the first and third value by the sum of the second and fourth value.

^(__)*
\$#1
_
.5


Divide by 2 and convert to decimal.

# Japt, 16 bytes

ÕÌä+ í*UÕÎäa)x÷2


Try it

ÕÌä+ í*UÕÎäa)x÷2     :Implicit input of array U
Õ                    :Transpose
Ì                   :Last element
ä+                 :Consecutive pairs, reduced by addition
í*              :Interleave with, reducing each pair by multiplication
UÕÎ           :  Last element of transposed U
äa         :  Consecutive pairs, reduced by absolute difference
)        :End interleave
÷2     :Divide by 2


# dc, 70 bytes

1k[sysxdly+2/syrdlxr-sxrlxly*lad1+sa:az4!>L]dsLxc[la1-ddsa;ar0<L+]dsLx


Try it online!

One decimal place of precision (1k) is sufficient because the longest fractional part we can have is 0.5. There could be better ways of twiddling the bits around.

# Charcoal, 24 bytes

Ｉ⊘ΣＥΦθκ×⁺§ι¹⊟§θκ⁻§ι⁰⊟§θκ


Try it online! Link is to verbose version of code. Explanation:

     θ                      Input array
Φ                       Filtered on
κ                     Current index
Ｅ                        Map over tail
§ι¹                Current Y-coordinate
⁺                   Plus
⊟§θκ            Previous Y-coordinate
×                    Multiplied by
§ι⁰        Current X-coordinate
⁻           Minus
⊟§θκ    Previous X-coordinate
Σ                         Take the sum
⊘                          Divide by 2
Ｉ                           Cast to string
Implicitly print


# C (gcc), 74 72 bytes

-2 thanks to @ceilingcat

a;r(int*x){for(a=0;~x[2];)a+=(x[2]-*x)*(*++x+x++[2]);printf("%f",a/2.);}


Takes input as a flat list terminated with -1 (e.g. {x1, y1, x2, y2, ..., -1})

Try it online!

# C (gcc), 78 75 bytes

-3 (indirectly) thanks to @ceilingcat

a;r(int*x,int*y){for(a=0;~*++x;)a+=(*x-x[-1])*(*y+++*y);printf("%f",a/2.);}


Try it online! Takes input as a list of xs and a list of ys, terminated with -1.