Question

Is it possible to take an array filled with 2 digit numbers e.g.

[10,11,12,13,...]

and multiply each element in the list by 100^(position in the array) and sum the result so that:

mysteryFunction[10,11,12] //The function performs 10*100^0 + 11*100^1 + 12*100^3

= 121110

and also

mysteryFunction[10,11,12,13]

= 13121110

when I do not know the number of elements in the array?

(yes, the reverse of order is intended but not 100% necessary, and just in case you missed it the first time the numbers will always be 2 digits)

Just for a bit of background to the problem: this is to try to improve my attempt at an RSA encryption program, at the moment I am multiplying each member of the array by 100^(the position of the number) written out each time which means that each word which I use to encrypt must be a certain length.

For example to encrypt "ab" I have converted it to an array [10,11] but need to convert it to 1110 before I can put it through the RSA algorithm. I would need to adjust my code for if I then wanted to use a three letter word, again for a four letter word etc. which I'm sure you will agree is not ideal. My code is nothing like industry standard but I am happy to upload it should anyone want to see it (I have also already managed this in Haskell if anyone would like to see that). I thought that the background information was necessary just so that I don't get hundreds of downvotes from people thinking that I'm trying to trick them into doing homework for me. Thank you very much for any help, I really do appreciate it!

EDIT: Thank you for all of the answers! They perfectly answer the question that I asked but I am having problems incorporating them into my current program, if I post my code so far would you be able to help? When I tried to include the answer provided I got an error message (I can't vote up because I don't have enough reputation, sorry that I haven't accepted any answers yet).

#include <iostream>
#include <string>
#include <math.h>

int returnVal (char x)
{
    return (int) x;
}

unsigned long long modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
unsigned long long remainder;
int x = 1;

while (e != 0)
{
remainder = e % 2;
e= e/2;

if (remainder == 1)
x = (x * b) % m;
b= (b * b) % m;
}
return x;
}

int main()
{
    unsigned long long p = 80001;
    unsigned long long q = 70021;
    int e = 7;
    unsigned long long n = p * q;
    std::string foo = "ab";
    for (int i = 0; i < foo.length(); i++);

    {
        std::cout << modExp (returnVal((foo[0]) - 87) + returnVal (foo[1] -87) * 100, e, n);
    }
}
Was it helpful?

Solution

If you want to use plain C-style arrays, you will have to separately know the number of entries. With this approach, your mysterious function might be defined like this:

unsigned mysteryFunction(unsigned numbers[], size_t n)
{
  unsigned result = 0;
  unsigned factor = 1;

  for (size_t i = 0; i < n; ++i)
  {
    result += factor * numbers[i];
    factor *= 100;
  }

  return result;
}

You can test this code with the following:

#include <iostream>

int main()
{
  unsigned ar[] = {10, 11, 12, 13};

  std::cout << mysteryFunction(ar, 4) << "\n";
  return 0;
}

On the other hand, if you want to utilize the STL's vector class, you won't separately need the size. The code itself won't need too many changes.

Also note that the built-in integer types cannot handle very large numbers, so you might want to look into an arbitrary precision number library, like GMP.

EDIT: Here's a version of the function which accepts a std::string and uses the characters' ASCII values minus 87 as the numbers:

unsigned mysteryFunction(const std::string& input)
{
  unsigned result = 0;
  unsigned factor = 1;

  for (size_t i = 0; i < input.size(); ++i)
  {
    result += factor * (input[i] - 87);
    factor *= 100;
  }

  return result;
}

The test code becomes:

#include <iostream>
#include <string>

int main()
{
  std::string myString = "abcde";
  std::cout << mysteryFunction(myString) << "\n";
  return 0;
}

The program prints: 1413121110

OTHER TIPS

As benedek mentioned, here's an implementation using dynamic arrays via std::vector.

unsigned mystery(std::vector<unsigned> vect)
{
    unsigned result = 0;
    unsigned factor = 1;

    for (auto& item : vect)
    {
        result += factor * item;
        factor *= 100;
    }

    return result;
}

void main(void)
{
    std::vector<unsigned> ar;
    ar.push_back(10);
    ar.push_back(11);
    ar.push_back(12);
    ar.push_back(13);

    std::cout << mystery(ar);
}    

I would like to suggest the following solutions.

You could use standard algorithm std::accumulate declared in header <numeric>

For example

#include <iostream>
#include <numeric>


int main() 
{
    unsigned int a[] = { 10, 11, 12, 13 };

    unsigned long long i = 1;

    unsigned long long s = 
        std::accumulate( std::begin( a ), std::end( a ), 0ull,
            [&]( unsigned long long acc, unsigned int x )
            { 
                return ( acc += x * i, i *= 100, acc );
            } );

    std::cout << "s = " << s << std::endl;          

    return 0;
}

The output is

s = 13121110

The same can be done with using the range based for statement

#include <iostream>
#include <numeric>


int main() 
{
    unsigned int a[] = { 10, 11, 12, 13 };

    unsigned long long i = 1;

    unsigned long long s = 0; 

    for ( unsigned int x : a )
    { 
        s += x * i; i *= 100;
    } 

    std::cout << "s = " << s << std::endl;          

    return 0;
}

You could also write a separate function

unsigned long long mysteryFunction( const unsigned int a[], size_t n )
{
   unsigned long long s = 0;
   unsigned long long i = 1;

   for ( size_t k = 0; k < n; k++ )
   {
      s += a[k] * i; i *= 100;
   }

   return s;
} 

Also think about using std::string instead of integral numbers to keep an encrypted result.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top