14
\$\begingroup\$

The smallest code that gives the area between the curve p(x) = a0 + a1*x + a2*x2 + ..., the line y = 0, the line x = 0 and the line x = C

(i.e. something like this:

wanted area)

You can assume that p(x) >= 0 for x < C (bonus points if your code works for negative values of p(x)).

Input

C, a0, a1, ...

Output

a real number - the area

Example 1:

input: 2, 0, 1
output: 2.0

Examlpe 2:

input: 3.0, 0, 0.0, 2
output: 18

UPDATE:

  • C > 0 is also assumed
  • the area is between the curve, y=0, x=C and x = 0
  • the input can be a list of any form; not necessarily comma separated.
  • the output can be a real of any form (thus, '18' is a valid output, as is '18.0')
\$\endgroup\$
12
  • 1
    \$\begingroup\$ Since the answer is going to be "infinite" for almost any input, I think you've misstated the problem. \$\endgroup\$ Feb 3, 2011 at 21:37
  • \$\begingroup\$ Should the input be read from standard input as a comma-separated string? Or can we write a function which takes a list of floats as an argument? \$\endgroup\$
    – sepp2k
    Feb 3, 2011 at 21:47
  • \$\begingroup\$ Do you mean between x=0, x=C, y=0, and the curve? \$\endgroup\$ Feb 3, 2011 at 22:06
  • 2
    \$\begingroup\$ @Peter: I don't think so. He shows a picture of an inverse (the integral of which would diverge), but the function he specifies is a polynomial. The definite integral over [0,C) should be well defined and finite for finite coefficients. \$\endgroup\$ Feb 4, 2011 at 1:20
  • 1
    \$\begingroup\$ @dmckee, I had noticed that, but my point was more that he was integrating a polynomial from -\infty to C, and for any non-trivial polynomial that diverges. The question has now been amended to fix this. \$\endgroup\$ Feb 4, 2011 at 7:11

9 Answers 9

10
\$\begingroup\$

APL (Dyalog Unicode), 9 bytes

⊃⊥∘⌽⊢÷⍳∘≢

Try it online!

A tacit function that takes C, a0, a1, ... as a single vector argument.

12 bytes if a full program is needed. Note that, while the default representation for a numeric vector is the numbers separated by spaces (no comma or anything), it accepts comma-separated ones since evals the input and , is the "concatenate" function.

(⊃⊥∘⌽⊢÷⍳∘≢)⎕

Try it online!

Uses ⎕IO←0 and ⎕DIV←1, so that the range generation is 0-based and division by zero gives 0.

Because the polynomial is nonnegative and the integral starts at 0, it suffices to evaluate the antiderivative of the given polynomial at C.

The antiderivative of \$a_0 + a_1x + a_2x^2 + \dots\$ is \$a_0x + \frac{a_1}{2} x^2 + \frac{a_2}{3} x^3 + \dots\$. Because we have C attached to the start of the vector, we simply divide the entire array by their 0-based indexes:

       C  a0   a1   a2
input: 3  0    0    2
div  : 0  1    2    3
res  : 0  0    0    2/3
       0  a0/1 a1/2 a2/3

Then we simply evaluate the resulting polynomial at C.

How it works: the code

⊃⊥∘⌽⊢÷⍳∘≢  ⍝ Input: single array of C, a0, a1, a2, ...
      ⍳∘≢  ⍝ 0-based range 0, 1, 2, 3, ...
    ⊢÷     ⍝ Divide self by above
  ∘⌽       ⍝ Reverse
⊃⊥         ⍝ Convert from base C to real number
           ⍝ i.e. evaluate the polynomial, lowest term given last
\$\endgroup\$
5
\$\begingroup\$

Python - 71 63 chars:

a=input()
print sum(1.*a[i]*a[0]**i/i for i in range(1,len(a)))

It's a simple integration of a polynomial function between 0 and C. And I haven't tested it, but I'm quite sure it works for negative values.

\$\endgroup\$
1
  • \$\begingroup\$ Learned something new about input() today:) \$\endgroup\$
    – st0le
    Feb 4, 2011 at 4:39
4
\$\begingroup\$

J, 26 characters

f=:3 :'((1}.y)&p.d._1)0{y'

e.g.

   f 2 0 1
2
   f 3 0 0 2
18
\$\endgroup\$
2
  • \$\begingroup\$ Neat! I can't find a way to make it more tacit. That d. being a conjunction doesn't make it very easy to my novice J skills. \$\endgroup\$
    – J B
    Feb 12, 2011 at 15:13
  • \$\begingroup\$ @J-B: Yes, that d. is a "problem" for me too. :) \$\endgroup\$
    – Eelvex
    Feb 12, 2011 at 15:21
3
\$\begingroup\$

Mathematica: 48 Chars

.

Sum[#[[i+1]]#[[1]]^i/i,{i,Length@#-1}]&@Input[]
\$\endgroup\$
1
  • \$\begingroup\$ -1 byte: Length@# -> Tr[1^#]. Also, you could omit @Input[] and make a function. \$\endgroup\$ Jan 26, 2017 at 16:34
3
\$\begingroup\$

Haskell, 85 characters

f(c:l)=sum.map(\(i,x)->x*c**i/i)$zip[1..]l
main=getLine>>=print.f.read.('[':).(++"]")
\$\endgroup\$
1
  • 1
    \$\begingroup\$ The question isn't as strict as you treat it. You could definitely simplify the input code, and possibly do away with explicit I/O altogether. \$\endgroup\$
    – J B
    Feb 12, 2011 at 15:19
3
\$\begingroup\$

APL(NARS), 8 chars, 16 bytes

∘{⍵⊥⌽⍺}∫

The new NARS2000 function integrate, ∫.

it seems f∫b is integrate(f, 0..b)=∫_0^b f Here i don't know if can be ok, the right argument is the max of interval of integration [0, max] and the left argument is the list of numbers represent polinomy...

  f←∘{⍵⊥⌽⍺}∫
  0 1 f 2
2 
  0 0 2 f 3
18 
  1 2 3 4 5 6 f 7
137256 
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I don't know NARS, but if is a monadic operator and can bind two functions like Dyalog does, I guess {⊥∘⌽∘⍵∫⍺} could work at 9 chars. \$\endgroup\$
    – Bubbler
    Jul 6, 2020 at 10:15
  • \$\begingroup\$ @Bubbler so can be pheraps, less of 8 chars \$\endgroup\$
    – user58988
    Jul 6, 2020 at 10:28
2
\$\begingroup\$

Ruby, 65 chars

i=s=0
c=gets(q=",").to_f
$<.each(q){|a|s+=a.to_f*c**(i+=1)/i}
p s

The code reads until the end of input, not the end of the line. So you need to hit Ctrl+D to terminate input. (Pipe the input in using echo or from a file.)

\$\endgroup\$
2
  • 1
    \$\begingroup\$ i think assigning the "," to a variable will help...how about this c=gets(q=",").to_f and $<.each(q){|a|s+=a.to_f*c**(i+=1)/i}, saves one char.... \$\endgroup\$
    – st0le
    Feb 4, 2011 at 4:31
  • \$\begingroup\$ Assigning "," (or ?,, which is even shorter) to $/ allows you to omit the argument to $<.each. And $<.map is one character shorter than $<.each. ;) \$\endgroup\$
    – Ventero
    Feb 12, 2011 at 19:58
2
\$\begingroup\$

C GCC 186 182 bytes

f(){i=0,l=1;float *d,s=0.0;d=malloc(sizeof(float)*50);scanf("%f",&d[0]);while(getchar()!='\n'){scanf("%f",&d[l]);l++;}for(i=0;i<l;i++)s+=d[i+1]*pow(d[0],(i+1))/(i+1);printf("%f",s);}

This program gives an output (area) for any curve between the curve, y=0, x=C and x=0. It can take coefficients (float as well) from a0 to a48. The first accepted input is C followed by coefficients. Press Ènter after the last coefficient.

void f()
{
  int i=0,l=1;
  float *d,s=0.0;
  const int sz=100;
  d=malloc(sizeof(float)*sz);

  scanf("%f",&d[0]);
  while(getchar()!='\n')
  {
    scanf("%f",&d[l]);
    l++;
  }

  for(i=0;i<l;i++)
    s+=d[i+1]*pow(d[0],(i+1))/(i+1);

   printf("%f",s);
}
\$\endgroup\$
1
\$\begingroup\$

Mathematica, 48 bytes

Try it online!

f[a_]:=Sum[a[[i+1]]*a[[1]]^i/i,{i,1,Length@a-1}]
\$\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.