2
$\begingroup$

I'm facing an informatics problem, math based.

Having this series:

1,  1, 2,  1, 2, 3,  1, 2, 3, 4,  1, 2, 3, 4, 5 ....

i have to efficiently find the value of element from position K;

for example, on position k = 5, element has the value 2

the way to solve this is to solve a square equation like this:

x^2 - x - 2*i

where i stands from k-1 to 1 and we downgrade k until we find a solution which satisfies this:

  • one root of the equation is higher than 0
  • it's a natural number

and the value of that element on position k will be k-i i did that on C++ and works 100%, with help from a friend;

for example, when k = 5 and our i iterator gets the value 3, the equation will be:

x^2 - x - 6

with positive root x1 = 3 and in final, the solution will be k-i -> 5-3 which is clearly 2, the value of the element from position K

i am trying to understand this for hours, but i dont get why the solution of that equation gives us the value from position K

if anybody knows the answer, i'm waiting for it!

Thanks!

1 Answers 1

0
Mon Feb 20 11:57:46 PST 2017
    1    1        1    1
    2    1        1    1
    3    2        2    3
    4    1        2    3
    5    2        2    3
    6    3        3    6
    7    1        3    6
    8    2        3    6
    9    3        3    6
   10    4        4   10
   11    1        4   10
   12    2        4   10
   13    3        4   10
   14    4        4   10
   15    5        5   15
   16    1        5   15
   17    2        5   15
   18    3        5   15
   19    4        5   15
   20    5        5   15
   21    6        6   21
   22    1        6   21
   23    2        6   21
   24    3        6   21
   25    4        6   21

========================================================

  system("date");

  for(int k = 1; k <= 25; ++k) 
  {
    int q = IntSqrt( 1 + 8 * k)  ;
    int n = ( q - 1) / 2 ;
    int t = n * ( n+1) / 2;
    int val = k - t;
    if( val == 0 )   val +=  n;
    cout << setw(5) << k  << setw(5) << val  << "    " << setw(5) << n  << setw(5) << t  << endl; 

  }

  system("date");

============================================

The triangular numbers are $$ 1, 3, 6, 10, 15, 21, $$ and by formula $$ T_n = \frac{n^2 + n}{2} $$ Your description says that the entry at position $k =T_n$ is $n$ itself. The next several entries are then $1, 2, 3, 4, \ldots, n, n+1.$

So, the first task is to (correctly!) find the largest $n$ such that $$ T_n = \frac{n^2 + n}{2} \leq k. $$ Then, if $T_n= k,$ the entry is $n.$ If $k > T_n$ but $k < T_{n+1},$ the entry is $$ k - T_n $$

All you need, as a separate item, is a C++ function that gives a correct value for $$ \lfloor \sqrt w \rfloor $$ when $w > 0$ is an integer. We want $$ n^2 + n - 2 k \leq 0, $$ $$ 4n^2 + 4n - 8 k \leq 0, $$ $$ 4n^2 + 4n + 1 - 1 - 8 k \leq 0, $$ $$ 4n^2 + 4n + 1 \leq 1 + 8 k, $$ $$ (2n+1)^2 \leq 1 + 8 k, $$ $$ 2n+1 \leq \sqrt { 1 + 8 k}, $$ $$ 2n \leq -1 + \sqrt { 1 + 8 k}, $$ $$ n \leq \frac{ -1 + \sqrt { 1 + 8 k}}{2}. $$ $$ n = \left\lfloor \frac{ -1 + \sqrt { 1 + 8 k}}{2} \right\rfloor $$ $$ n = \left\lfloor \frac{ -1 + \lfloor \sqrt { 1 + 8 k} \rfloor}{2} \right\rfloor $$

int IntSqrt(int i)
{
  // cerr << "called intsqrt  with   " << i << endl;
  if ( i <= 0 ) return 0;
  else if ( i <= 3) return 1;
  else if ( i >= 2147395600) return 46340;
  else
  {
    float r;
    r = 1.0 * i;
    r = sqrt(r);
    int root = (int) ceil(r);
    while ( root * root   <= i ) ++root;
    while ( root * root   > i ) --root;
    return  root ;
  }
} // IntSqrt
  • 0
    uhh, that's a good answer, thanks ! which is the relation between (n^2 + n) / 2 with that series? that's what i'm trying to reach.2017-02-20
  • 0
    got it! thanks a lot ;)2017-02-20
  • 0
    @GabiMMinimalART I added a short output at the beginning and the heart of main()2017-02-20
  • 0
    i have noticed it :) very well explained2017-02-20