How to approach large numbers in programming puzzles

S

Surya

I am new to solving programming puzzles in contests like SPOJ where I thought to use C a while..

Often these puzzles throw very large numbers -- of order 1000000 digits which gets me crazy. When constructing algorithms I face trouble with handling these datasets and manipulating them.

It would be very nice if you can give me some pointers, tips or links for handling such situations.

Thanks
 
J

Joe Pfeiffer

Surya said:
I am new to solving programming puzzles in contests like SPOJ where I thought to use C a while..

Often these puzzles throw very large numbers -- of order 1000000 digits which gets me crazy. When constructing algorithms I face trouble with handling these datasets and manipulating them.

It would be very nice if you can give me some pointers, tips or links for handling such situations.

Try googling bignum -- a couple of the links it'll turn up that should
be especially useful are

en.wikipedia.org/wiki/Arbitrary-precision_arithmetic
gmplib.org/‎
 
P

Paul

Surya said:
I am new to solving programming puzzles in contests like SPOJ where I thought to use C a while..

Often these puzzles throw very large numbers -- of order 1000000 digits which gets me crazy. When constructing algorithms I face trouble with handling these datasets and manipulating them.

It would be very nice if you can give me some pointers, tips or links for handling such situations.

Thanks

GMP

http://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library

GMP is used here in the C++ example, but
you can recode that in C for fun. GMP
supports both.

http://rosettacode.org/wiki/Lucas-Lehmer_test#C

Paul
 
B

Ben Bacarisse

Surya said:
How to approach without using external libs..

Usually in progamming puzzles (say SPOJ), we don't have the luxury of
using high level libs!!

It looks like SPOJ accepts programs in lots of languages. Of those,
several have large integer types built in. For example, Haskell,
various Lisps, Python and Ruby.
 
C

Charlton Wilbur

S> It would be very nice if you can give me some pointers, tips or
S> links for handling [extremely large numbers]

One of the common programming problems set to undergraduates in my
degree program was to write an "infinite-precision" calculator that
operated on strings of decimal digits rather than on numeric types.

If you're a competent programmer, implementing such a library should
take an afternoon if you don't care too much about efficiency.

Charlton
 
G

glen herrmannsfeldt

S> It would be very nice if you can give me some pointers, tips or
S> links for handling [extremely large numbers]
One of the common programming problems set to undergraduates in my
degree program was to write an "infinite-precision" calculator that
operated on strings of decimal digits rather than on numeric types.

Usually called "multiple-precision" instead of infinite, but other
that that.
If you're a competent programmer, implementing such a library should
take an afternoon if you don't care too much about efficiency.

All except multiple precision divisor are pretty easy. You can speed it
up a little by doing a higher power of 10.

If you do it in binary, you also need a convert do decimal routine,
which is similar in complexity and time to multiple precision divisor.

-- glen
 
C

Charlton Wilbur

GH> Usually called "multiple-precision" instead of infinite, but
GH> other that that.

When I was an undergraduate, it was called "infinite-precision," but it
was understood that it was only theoretically infinite precision,
computers not having infinite memory and all.

Charlton
 
P

Phil Carmody

Charlton Wilbur said:
GH> Usually called "multiple-precision" instead of infinite, but
GH> other that that.

When I was an undergraduate, it was called "infinite-precision," but it
was understood that it was only theoretically infinite precision,
computers not having infinite memory and all.

Compromise: "Arbitrary precision".

Phil
 
T

Tim Rentsch

Surya said:
I am new to solving programming puzzles in contests like SPOJ
where I thought to use C a while..

Often these puzzles throw very large numbers -- of order 1000000
digits which gets me crazy. When constructing algorithms I face
trouble with handling these datasets and manipulating them.

It would be very nice if you can give me some pointers, tips or
links for handling such situations.

Most likely the problems you're looking at don't require the
full generality of arbitrary precision arithmetic. I suspect in
fact that is part of the point of the puzzle - to figure out how
to deal with limited operations on large integers, especially if
all the numbers involved are non-negative.

For example, here is one way to define a simple structure for
holding large non-negative integers:

typedef unsigned long Index;

typedef struct {
Index top_index;
unsigned digits[ 334000 ]; /* in 1,000's */
} LargeNumber;

This structure will hold numbers up to one million digits
(or just slightly larger), and on a typical implementation
where unsigned ints are four bytes will occupy approximately
1.34 MB. With these definition in hand, we could then write

static LargeNumber factorials[101];

static void
compute_factorials_up_to_100(){
Index i;
factorials[0].digits[0] = 1;
factorials[0].top_index = 0;
for( i = 1; i <= 100; i++ ){
factorials = factorials[i-1];
multiply_by( &factorial, i );
}
}

If you can now write the 'multiply_by()' function, which
multiplies a LargeNumber by a small integer argument (it should
be easy if the multiplier is less than 1000) -- and in the
process adjusting elements of the digits[] array member and
sometimes also the top_index member -- at that point it should be
easy to solve the "Small factorials" problem at SPOJ. Having
computed the table of factorials, for each input simply index
the pre-computed table and print out the answer.

Note that the numbers here are represented in units of 1,000's,
so three decimal digits per array element, and with the low
order digits having smaller indices. So to print out the
number you would first print the value for the element at
the high end, eg, if we are working on factorials[k], we
would start with

factorials[k].digits[ factorials[k].top_index ]

and work down from there, until we get to factorials[k].digts[0].
Hopefully this is about the right level of detail so you can
fill in the rest.

Incidentally, having a million digits available is way more than
is needed to deal with numbers only as large as 100 factorial.
But the amount of space used and the time needed should be well
within the limits of the SPOJ problems. (Disclaimer: I have no
experience submitting anything to SPOJ, so this remark may
reflect unrealistic assumptions on my part as to what is being
measured by the limits SPOJ states.)

Other large number problems may very well need different
representations. Figuring out which representations are
suitable for which problems is an important part of solving
the problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,811
Latest member
SaulFernan

Latest Threads

Top