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\$
  • 1
    \$\begingroup\$ Since the answer is going to be "infinite" for almost any input, I think you've misstated the problem. \$\endgroup\$ – Peter Taylor Feb 3 '11 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 '11 at 21:47
  • \$\begingroup\$ Do you mean between x=0, x=C, y=0, and the curve? \$\endgroup\$ – Keith Randall Feb 3 '11 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\$ – dmckee --- ex-moderator kitten Feb 4 '11 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\$ – Peter Taylor Feb 4 '11 at 7:11
3
\$\begingroup\$

Mathematica: 48 Chars

.

Sum[#[[i+1]]#[[1]]^i/i,{i,Length@#-1}]&@Input[]
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ -1 byte: Length@# -> Tr[1^#]. Also, you could omit @Input[] and make a function. \$\endgroup\$ – JungHwan Min Jan 26 '17 at 16:34
9
\$\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
| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Learned something new about input() today:) \$\endgroup\$ – st0le Feb 4 '11 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
| improve this answer | |
\$\endgroup\$
  • \$\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 '11 at 15:13
  • \$\begingroup\$ @J-B: Yes, that d. is a "problem" for me too. :) \$\endgroup\$ – Eelvex Feb 12 '11 at 15:21
3
\$\begingroup\$

Haskell, 85 characters

f(c:l)=sum.map(\(i,x)->x*c**i/i)$zip[1..]l
main=getLine>>=print.f.read.('[':).(++"]")
| improve this answer | |
\$\endgroup\$
  • 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 '11 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 
| improve this answer | |
\$\endgroup\$
  • 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 at 10:15
  • \$\begingroup\$ @Bubbler so can be pheraps, less of 8 chars \$\endgroup\$ – user58988 Jul 6 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.)

| improve this answer | |
\$\endgroup\$
  • 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 '11 at 4:31
  • \$\begingroup\$ @st0le: Very nice. Thanks. \$\endgroup\$ – sepp2k Feb 4 '11 at 4:32
  • \$\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 '11 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);
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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