Skip to content

Instantly share code, notes, and snippets.

@ryankert01
Created April 20, 2022 09:31
Show Gist options
  • Save ryankert01/476f10ebae1a980d1f3299597bf6fa79 to your computer and use it in GitHub Desktop.
Save ryankert01/476f10ebae1a980d1f3299597bf6fa79 to your computer and use it in GitHub Desktop.
// HugeInteger test program.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::ostream;
#include <iomanip>
using std::setw;
using std::setfill;
#include <cstring>
using std::strlen;
template< typename BidIt >
class ReverseIterator // wrap iterator to run it backwards
{
public:
using value_type = typename BidIt::value_type;
using difference_type = typename BidIt::difference_type;
using pointer = typename BidIt::pointer;
using reference = typename BidIt::reference;
// construct with value-initialized wrapped iterator
ReverseIterator() = default;
// construct wrapped iterator from right
ReverseIterator( BidIt right )
: current( right )
{
}
ReverseIterator( const ReverseIterator &right )
: current( right.current ) // initialize with compatible base
{
}
// assign from compatible base
ReverseIterator& operator=( const ReverseIterator &right )
{
current = right.current;
return *this;
}
BidIt base() const // return wrapped iterator
{
return current;
}
reference operator*() const // return designated value
{
BidIt tmp = current;
return *--tmp;
}
pointer operator->() const // return pointer to class object
{
BidIt tmp = current;
--tmp;
return tmp.operator->();
}
ReverseIterator& operator++() // preincrement
{
--current;
return *this;
}
ReverseIterator operator++( int ) // postincrement
{
ReverseIterator tmp = *this;
--current;
return tmp;
}
ReverseIterator& operator--() // predecrement
{
++current;
return *this;
}
ReverseIterator operator--( int ) // postdecrement
{
ReverseIterator tmp = *this;
++current;
return tmp;
}
// increment by integer
ReverseIterator& operator+=( const difference_type off )
{
current -= off;
return *this;
}
// return this + integer
ReverseIterator operator+( const difference_type off ) const
{
return ReverseIterator( current - off );
}
// decrement by integer
ReverseIterator& operator-=( const difference_type off )
{
current += off;
return *this;
}
// return this - integer
ReverseIterator operator-( const difference_type off ) const
{
return ReverseIterator( current + off );
}
// subscript
reference operator[]( const difference_type off ) const
{
return current[ static_cast< difference_type >( -off - 1 ) ];
}
protected:
BidIt current{}; // the wrapped iterator
};
template< typename BidIt1, typename BidIt2 >
bool operator==( const ReverseIterator< BidIt1 > &left,
const ReverseIterator< BidIt2 > &right )
{
return left.base() == right.base();
}
template< typename BidIt1, typename BidIt2 >
bool operator!=( const ReverseIterator< BidIt1 > &left,
const ReverseIterator< BidIt2 > &right )
{
return !( left == right );
}
template< typename BidIt1, typename BidIt2 >
bool operator<( const ReverseIterator< BidIt1 > &left,
const ReverseIterator< BidIt2 > &right )
{
return right.base() < left.base();
}
template< typename BidIt1, typename BidIt2 >
bool operator>( const ReverseIterator< BidIt1 > &left,
const ReverseIterator< BidIt2 > &right )
{
return right < left;
}
template< typename BidIt1, typename BidIt2 >
bool operator<=( const ReverseIterator< BidIt1 > &left,
const ReverseIterator< BidIt2 > &right )
{
return !( right < left );
}
template< typename BidIt1, typename BidIt2 >
bool operator>=( const ReverseIterator< BidIt1 > &left,
const ReverseIterator< BidIt2 > &right )
{
return !( left < right );
}
// CLASS TEMPLATE VectorConstIterator
template< typename MyVec >
class VectorConstIterator
{
public:
using value_type = typename MyVec::value_type;
using difference_type = typename MyVec::difference_type;
using pointer = typename MyVec::const_pointer;
using reference = const value_type &;
using TPtr = typename MyVec::pointer;
VectorConstIterator()
: ptr()
{
}
VectorConstIterator( TPtr parg )
: ptr( parg )
{
}
reference operator*() const
{
return *ptr;
}
pointer operator->() const
{
return ptr;
}
VectorConstIterator& operator++()
{
++ptr;
return *this;
}
VectorConstIterator operator++( int )
{
VectorConstIterator temp = *this;
++ *this;
return temp;
}
VectorConstIterator& operator--()
{
--ptr;
return *this;
}
VectorConstIterator operator--( int )
{
VectorConstIterator temp = *this;
-- *this;
return temp;
}
VectorConstIterator& operator+=( const difference_type off )
{
ptr += off;
return *this;
}
VectorConstIterator operator+( const difference_type off ) const
{
VectorConstIterator temp = *this;
return temp += off;
}
VectorConstIterator& operator-=( const difference_type off )
{
return *this += -off;
}
VectorConstIterator operator-( const difference_type off ) const
{
VectorConstIterator temp = *this;
return temp -= off;
}
difference_type operator-( const VectorConstIterator &right ) const
{
return ptr - right.ptr;
}
reference operator[]( const difference_type off ) const
{
return *( *this + off );
}
bool operator==( const VectorConstIterator &right ) const
{
return ptr == right.ptr;
}
bool operator!=( const VectorConstIterator &right ) const
{
return !( *this == right );
}
bool operator<( const VectorConstIterator &right ) const
{
return ptr < right.ptr;
}
bool operator>( const VectorConstIterator &right ) const
{
return right < *this;
}
bool operator<=( const VectorConstIterator &right ) const
{
return !( right < *this );
}
bool operator>=( const VectorConstIterator &right ) const
{
return !( *this < right );
}
TPtr ptr; // pointer to element in vector
};
// CLASS TEMPLATE VectorIterator
template< typename MyVec >
class VectorIterator
{
public:
using value_type = typename MyVec::value_type;
using difference_type = typename MyVec::difference_type;
using pointer = typename MyVec::const_pointer;
using reference = value_type &;
using TPtr = typename MyVec::pointer;
VectorIterator()
: ptr()
{
}
VectorIterator( TPtr parg )
: ptr( parg )
{
}
reference operator*() const
{
return *ptr;
}
pointer operator->() const
{
return ptr;
}
VectorIterator& operator++()
{
++ptr;
return *this;
}
VectorIterator operator++( int )
{
VectorIterator temp = *this;
++ *this;
return temp;
}
VectorIterator& operator--()
{
--ptr;
return *this;
}
VectorIterator operator--( int )
{
VectorIterator temp = *this;
-- *this;
return temp;
}
VectorIterator& operator+=( const difference_type off )
{
ptr += off;
return *this;
}
VectorIterator operator+( const difference_type off ) const
{
VectorIterator temp = *this;
return temp += off;
}
VectorIterator& operator-=( const difference_type off )
{
return *this += -off;
}
VectorIterator operator-( const difference_type off ) const
{
VectorIterator temp = *this;
return temp -= off;
}
difference_type operator-( const VectorIterator &right ) const
{
return ptr - right.ptr;
}
reference operator[]( const difference_type off ) const
{
return *( *this + off );
}
bool operator==( const VectorIterator &right ) const
{
return ptr == right.ptr;
}
bool operator!=( const VectorIterator &right ) const
{
return !( *this == right );
}
bool operator<( const VectorIterator &right ) const
{
return ptr < right.ptr;
}
bool operator>( const VectorIterator &right ) const
{
return right < *this;
}
bool operator<=( const VectorIterator &right ) const
{
return !( right < *this );
}
bool operator>=( const VectorIterator &right ) const
{
return !( *this < right );
}
TPtr ptr; // pointer to element in vector
};
// CLASS TEMPLATE VectorVal
template< typename ValueType >
class VectorVal
{
public:
using value_type = ValueType;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = value_type *;
using const_pointer = const value_type *;
using reference = value_type &;
using const_reference = const value_type &;
VectorVal()
: myFirst(),
myLast(),
myEnd()
{
}
pointer myFirst; // pointer to beginning of array
pointer myLast; // pointer to current end of sequence
pointer myEnd; // pointer to end of array
};
// CLASS TEMPLATE vector
template< typename Ty >
class vector // varying size array of values
{
public:
using value_type = Ty;
using pointer = value_type *;
using const_pointer = const value_type *;
using reference = Ty &;
using const_reference = const Ty &;
using size_type = size_t;
using difference_type = ptrdiff_t;
private:
using ScaryVal = VectorVal< Ty >;
public:
using iterator = VectorIterator< ScaryVal >;
using const_iterator = VectorConstIterator< ScaryVal >;
using reverse_iterator = ReverseIterator< iterator >;
using const_reverse_iterator = ReverseIterator< const_iterator >;
vector()
: myData()
{
}
vector( const size_type count )
: myData()
{
myData.myFirst = new value_type[count]();
myData.myLast = myData.myEnd = myData.myFirst + count;
}
vector( const vector &right )
: myData()
{
myData.myFirst = new value_type[right.size()]();
for (int i = 0; i < right.size(); i++)
{
myData.myFirst[i] = right.myData.myFirst[i];
}
myData.myLast = myData.myEnd = myData.myFirst + right.size();
}
~vector()
{
if( myData.myFirst != nullptr )
delete[] myData.myFirst;
}
void push_back( const Ty &val )
{
size_type originalSize = size();
resize( originalSize + 1 );
myData.myFirst[ originalSize ] = val;
}
vector& operator=( const vector &right )
{
if( this != &right ) // avoid self-assignment
{
size_type rightSize = right.size();
if( rightSize > capacity() )
{
size_type newCapacity = capacity() * 3 / 2;
if( newCapacity < rightSize )
newCapacity = rightSize;
if (myData.myFirst != nullptr)
delete[] myData.myFirst;
myData.myFirst = new value_type[newCapacity]();
myData.myEnd = myData.myFirst + newCapacity;
}
for (int i = 0; i < rightSize; i++)
myData.myFirst[i] = right.myData.myFirst[i];
myData.myLast = myData.myFirst + rightSize;
}
return *this; // enables x = y = z, for example
}
void resize( const size_type newSize )
{
size_type originalSize = size();
if (newSize > originalSize)
{
if (newSize > capacity())
{
size_type newCapacity = capacity() * 3 / 2;
if (newCapacity < newSize)
newCapacity = newSize;
pointer temp = myData.myFirst;
myData.myFirst = new value_type[newCapacity]();
for (int i = 0; i < originalSize; i++)
myData.myFirst[i] = temp[i];
delete[] temp;
myData.myEnd = myData.myFirst + newCapacity;
}
for (size_t i = originalSize; i < newSize; i++)
myData.myFirst[i] = 0;
}
myData.myLast = myData.myFirst + newSize;
}
void pop_back()
{
if( size() > 0 )
--myData.myLast;
}
void clear()
{
myData.myLast = myData.myFirst;
}
iterator begin()
{
return iterator( myData.myFirst );
}
iterator end()
{
return iterator( myData.myLast );
}
reverse_iterator rbegin()
{
return reverse_iterator( end() );
}
reverse_iterator rend()
{
return reverse_iterator( begin() );
}
bool empty() const
{
return myData.myFirst == myData.myLast;
}
size_type size() const
{
return static_cast< size_type >( myData.myLast - myData.myFirst );
}
size_type capacity() const
{
return static_cast< size_type >( myData.myEnd - myData.myFirst );
}
value_type& front()
{
return *myData.myFirst;
}
const value_type& front() const
{
return *myData.myFirst;
}
value_type& back()
{
return myData.myLast[ -1 ];
}
const value_type& back() const
{
return myData.myLast[ -1 ];
}
private:
ScaryVal myData;
};
// determine if two vectors are equal and return true, otherwise return false
template< typename Ty >
bool operator==( vector< Ty > &left, vector< Ty > &right )
{
if (left.size() != right.size())
return false; // vectors of different number of elements
typename vector< Ty >::iterator it1 = left.begin();
typename vector< Ty >::iterator it2 = right.begin();
for (; it1 != left.end(); ++it1, ++it2)
if (*it1 != *it2)
return false; // vector contents are not equal
return true; // vector contents are equal
}
// inequality operator; returns opposite of == operator
template< typename Ty >
bool operator!=( vector< Ty > &left, vector< Ty > &right )
{
return !( left == right );
}
// CLASS TEMPLATE ListConstIterator
template< typename MyList >
class ListConstIterator
{
public:
using nodePtr = typename MyList::nodePtr;
using value_type = typename MyList::value_type;
using difference_type = typename MyList::difference_type;
using pointer = typename MyList::const_pointer;
using reference = const value_type &;
ListConstIterator()
: ptr()
{
}
ListConstIterator( nodePtr pNode )
: ptr( pNode )
{
}
reference operator*() const
{
return ptr->myVal;
}
ListConstIterator& operator++()
{
ptr = ptr->next;
return *this;
}
ListConstIterator operator++( int )
{
ListConstIterator temp = *this;
ptr = ptr->next;
return temp;
}
ListConstIterator& operator--()
{
ptr = ptr->prev;
return *this;
}
ListConstIterator operator--( int )
{
ListConstIterator temp = *this;
ptr = ptr->prev;
return temp;
}
bool operator==( const ListConstIterator &right ) const
{
return ptr == right.ptr;
}
bool operator!=( const ListConstIterator &right ) const
{
return !( *this == right );
}
nodePtr ptr; // pointer to node
};
// CLASS TEMPLATE ListIterator
template< typename MyList >
class ListIterator
{
public:
using nodePtr = typename MyList::nodePtr;
using value_type = typename MyList::value_type;
using difference_type = typename MyList::difference_type;
using pointer = typename MyList::const_pointer;
using reference = value_type &;
ListIterator()
: ptr()
{
}
ListIterator( nodePtr pNode )
: ptr( pNode )
{
}
reference operator*() const
{
return ptr->myVal;
}
ListIterator& operator++()
{
ptr = ptr->next;
return *this;
}
ListIterator operator++( int )
{
ListIterator temp = *this;
ptr = ptr->next;
return temp;
}
ListIterator& operator--()
{
ptr = ptr->prev;
return *this;
}
ListIterator operator--( int )
{
ListIterator temp = *this;
ptr = ptr->prev;
return temp;
}
bool operator==( const ListIterator &right ) const
{
return ptr == right.ptr;
}
bool operator!=( const ListIterator &right ) const
{
return !( *this == right );
}
nodePtr ptr; // pointer to node
};
template< typename ValueType >
struct ListNode // list node
{
using nodePtr = ListNode *;
nodePtr next; // successor node, or first element if head
nodePtr prev; // predecessor node, or last element if head
ValueType myVal; // the stored value, unused if head
};
// CLASS TEMPLATE ListVal
template< typename Ty >
class ListVal
{
public:
using node = ListNode< Ty >;
using nodePtr = node *;
using value_type = Ty;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = value_type *;
using const_pointer = const value_type *;
using reference = value_type &;
using const_reference = const value_type &;
ListVal() // initialize data
: myHead(),
mySize( 0 )
{
}
nodePtr myHead; // pointer to head node
size_type mySize; // number of elements
};
// CLASS TEMPLATE list
template< typename Ty >
class list // bidirectional linked list
{
using node = ListNode< Ty >;
using nodePtr = node *;
using ScaryVal = ListVal< Ty >;
public:
using value_type = Ty;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = value_type *;
using const_pointer = const value_type *;
using reference = value_type &;
using const_reference = const value_type &;
using iterator = ListIterator< ScaryVal >;
using const_iterator = ListConstIterator< ScaryVal >;
using reverse_iterator = ReverseIterator< iterator >;
using const_reverse_iterator = ReverseIterator< const_iterator >;
list()
: myData()
{
myData.myHead = new node;
myData.myHead->myVal = Ty();
myData.myHead->prev = myData.myHead->next = myData.myHead;
}
explicit list( size_type count ) // construct list from count * Ty()
: myData()
{
myData.myHead = new node;
myData.myHead->myVal = Ty();
myData.myHead->prev = myData.myHead->next = myData.myHead;
if( count > 0 )
for( size_type i = 0; i < count; ++i )
// insert( cend(), Ty() );
push_back( Ty() );
}
list( const list &right )
: myData()
{
myData.myHead = new node;
myData.myHead->myVal = Ty();
myData.myHead->prev = myData.myHead->next = myData.myHead;
for (iterator it = right.myData.myHead->next; it != right.myData.myHead; it++)
push_back(it.ptr->myVal);
}
~list()
{
clear();
delete myData.myHead;
}
list& operator=( const list &right )
{
if( this != &right )
{
while (size() < right.size())
push_back(Ty());
while (size() > right.size())
pop_back();
iterator it1 = begin();
for (iterator it = right.begin(); it != right.end(); it = it->next, it1 = it1->next)
it1->myVal = it->myVal;
}
return *this;
}
iterator begin()
{
return iterator( myData.myHead->next );
}
iterator end()
{
return iterator( myData.myHead );
}
reverse_iterator rbegin()
{
return reverse_iterator( end() );
}
reverse_iterator rend()
{
return reverse_iterator( begin() );
}
void resize( size_type newSize )
{
if( myData.mySize < newSize ) // pad to make larger
{
size_type difference = newSize - myData.mySize;
for( size_type i = 0; i < difference; i++ ) // create newSize - myData.mySize elements
push_back( Ty() );
}
else
{
while( newSize < myData.mySize )
pop_back();
}
}
size_type size() const
{
return myData.mySize;
}
bool empty() const
{
return myData.mySize == 0;
}
reference front()
{
return myData.myHead->next->myVal;
}
const_reference front() const
{
return myData.myHead->next->myVal;
}
reference back()
{
return myData.myHead->prev->myVal;
}
const_reference back() const
{
return myData.myHead->prev->myVal;
}
void push_back( const Ty &val )
{
myData.myHead->prev->next = new node;
myData.myHead->prev->next->prev = myData.myHead->prev;
myData.myHead->prev = myData.myHead->prev->next;
myData.myHead->prev->myVal = val;
myData.mySize++;
myData.myHead->prev->next = myData.myHead;
}
void pop_back()
{
if( myData.mySize > 0 )
{
myData.myHead->prev = myData.myHead->prev->prev;
delete myData.myHead->prev->next;
myData.myHead->prev->next = myData.myHead;
myData.mySize--;
}
}
void clear() // erase all
{
if( myData.mySize != 0 ) // the list is not empty
{
iterator itPrev;
for (iterator it = myData.myHead->next; it != myData.myHead; )
{
itPrev = it;
it++;
delete itPrev.ptr;
}
myData.myHead->next = myData.myHead->prev = myData.myHead;
myData.mySize = 0;
}
}
private:
ScaryVal myData;
};
// determine if two lists are equal and return true, otherwise return false
template< typename Ty >
bool operator==( list< Ty > &left, list< Ty > &right )
{
if (left.size() != right.size())
return false;
typename list< Ty >::iterator it = left.begin();
typename list< Ty >::iterator it1 = right.begin();
for (; it != left.end(); it++, it1++)
if (it.ptr->myVal != it1.ptr->myVal)
return false;
return true;
}
// inequality operator; returns opposite of == operator
template< typename Ty >
bool operator!=( list< Ty > &left, list< Ty > &right )
{
return !( left == right );
}
template< typename T >
class HugeInteger
{
template< typename U >
friend ostream& operator<<( ostream &output, HugeInteger< U > hugeInteger );
public:
using value_type = typename T::value_type;
using size_type = typename T::size_type;
HugeInteger( unsigned int n = 0 ); // constructor; construct a zero HugeInteger with size n
// copy constructor; constructs a HugeInteger with a copy of each of the elements in integerToCopy
HugeInteger( const HugeInteger &integerToCopy );
// constructs a HugeInteger with a copy of each of the elements in integerToCopy
HugeInteger( const T &integerToCopy );
~HugeInteger(); // destructor; destroys the HugeInteger
bool operator==( HugeInteger &right ); // less than or equal to
bool operator<( HugeInteger &right ); // less than
bool operator<=( HugeInteger &right ); // less than or equal to
HugeInteger square( value_type powerTwo ); // the square of HugeInteger
HugeInteger squareRoot( value_type powerTwo ); // the square root of HugeInteger
bool isZero(); // return true if and only if all digits are zero
private:
T integer;
}; // end class HugeInteger
// constructor; construct a zero HugeInteger with size n
template< typename T >
HugeInteger< T >::HugeInteger( unsigned int n )
: integer( ( n == 0 ) ? 1 : n )
{
}
// copy constructor; constructs a HugeInteger with a copy of each of the elements in integerToCopy
template< typename T >
HugeInteger< T >::HugeInteger( const HugeInteger &integerToCopy )
: integer( integerToCopy.integer )
{
}
// copy constructor; constructs a HugeInteger with a copy of each of the elements in integerToCopy
template< typename T >
HugeInteger< T >::HugeInteger( const T &integerToCopy )
: integer( integerToCopy )
{
}
// destructor; destroys the HugeInteger
template< typename T >
HugeInteger< T >::~HugeInteger()
{
}
// function that tests if two HugeIntegers are equal
template< typename T >
bool HugeInteger< T >::operator==( HugeInteger &right )
{
return ( integer == right.integer );
} // end function operator==
// function that tests if one HugeInteger is less than another
template< typename T >
bool HugeInteger< T >::operator<( HugeInteger &right )
{
if (integer.size() != right.integer.size())
return integer.size() < right.integer.size();
typename T::iterator it1 = integer.end(); it1--;
typename T::iterator it2 = right.integer.end(); it2--;
for (; it1 != --integer.begin() ;it1--, it2--)
{
if (*it1 != *it2)
return *it1 < *it2;
}
return false;
} // end function operator<
// function that tests if one HugeInteger is less than or equal to another
template< typename T >
bool HugeInteger< T >::operator<=( HugeInteger &right )
{
return ( *this == right || *this < right );
}
template< typename T >
HugeInteger< T > HugeInteger< T >::square( value_type powerTwo )
{
HugeInteger zero;
if( isZero() )
return zero;
size_t squareSize = 2 * integer.size();
HugeInteger square1( squareSize );
typename T::iterator it1 = integer.begin();
typename T::iterator it2 = integer.begin();
typename T::iterator sqIt = square1.integer.begin();
typename T::iterator temp = square1.integer.begin();
for (; it1 != integer.end(); it1++, temp++)
{
sqIt = temp;
for (it2 = integer.begin(); it2 != integer.end(); it2++, sqIt++)
{
*sqIt += *it1 * *it2;
}
}
temp = square1.integer.begin(); temp++;
for (sqIt = square1.integer.begin(); temp != square1.integer.end(); sqIt++, temp++)
if (*sqIt >= powerTwo)
{
*temp += *sqIt / powerTwo;
*sqIt %= powerTwo;
}
while (square1.integer.back() == 0)
square1.integer.pop_back();
return square1;
}
template< typename T >
HugeInteger< T > HugeInteger< T >::squareRoot( value_type powerTwo )
{
HugeInteger zero;
if( isZero() )
return zero;
size_type sqrtSize = ( integer.size() + 1 ) / 2;
HugeInteger sqrt( sqrtSize );
HugeInteger< T > low(sqrtSize);
HugeInteger< T > high(sqrtSize);
using iter1 = typename T::iterator;
iter1 lowIt = low.integer.end(); lowIt--;
iter1 highIt = high.integer.end(); highIt--;
iter1 sqrtIt = sqrt.integer.end(); sqrtIt--;
for (; highIt != --high.integer.begin(); highIt--, lowIt--, sqrtIt--)
{
*highIt = powerTwo;
*lowIt = 0;
while (*lowIt <= *highIt)
{
*sqrtIt = (*highIt + *lowIt) / 2;
HugeInteger< T > sqrtMiddle(sqrt.square(powerTwo));
if (sqrtMiddle == *this)
return sqrt;
else if (*this < sqrtMiddle)
{
*highIt = *sqrtIt;
continue;
}
else
*lowIt = *sqrtIt;
if ((*lowIt + 1) == *highIt)
{
*sqrtIt = *lowIt;
break;
}
}
}
return sqrt;
}
// function that tests if a HugeInteger is zero
template< typename T >
bool HugeInteger< T >::isZero()
{
typename T::iterator it = integer.begin();
for( ; it != integer.end(); ++it )
if( *it != 0 )
return false;
return true;
}
// overloaded output operator for class HugeInteger
template< typename T >
ostream& operator<<( ostream &output, HugeInteger< T > hugeInteger )
{
typename T::value_type numDigits = sizeof( typename T::value_type ) - 1;
typename T::reverse_iterator it = hugeInteger.integer.rbegin();
output << *it;
for( ++it; it != hugeInteger.integer.rend(); ++it )
output << setw( numDigits ) << setfill( '0' ) << *it;
return output; // enables cout << x << y;
}
template< typename T1, typename T2 >
void solution2()
{
char buf[ 1002 ];
int numCases;
cin >> numCases;
for( int i = 1; i <= numCases; ++i )
{
cin >> buf;
T2 digits[ 1001 ] = {};
size_t last = strlen( buf ) - 1;
for( size_t i = 0; i <= last; ++i )
digits[ i ] = static_cast< T2 >( buf[ last - i ] ) - '0';
T1 integer;
T2 powerTwo;
size_t numDigits = sizeof( T2 ) - 1;
for( size_t i = 0; i <= last; i += numDigits )
{
powerTwo = 1;
T2 bigDigit = 0;
for( size_t j = i; j < i + numDigits; ++j, powerTwo *= 10 )
bigDigit += digits[ j ] * powerTwo;
integer.push_back( bigDigit );
}
HugeInteger< T1 > hugeInteger( integer );
cout << hugeInteger.squareRoot( powerTwo ) << endl;
if( i < numCases )
cout << endl;
}
}
template< typename T >
void solution1()
{
int choice = 1;
switch( choice )
{
case 1:
solution2< vector< T >, T >();
break;
case 2:
solution2< list< T >, T >();
break;
default:
cout << "Program should never get here!";
}
}
int main()
{
int choice = 1;
switch( choice )
{
case 1:
solution2< vector< int >, int >();
break;
case 2:
solution2< vector< unsigned int >, unsigned int >();
break;
case 3:
solution1< long int >();
break;
case 4:
solution1< unsigned long int >();
break;
case 5:
solution1< long long int >();
break;
case 6:
solution1< unsigned long long int >();
break;
default:
cout << "Program should never get here!";
}
system( "pause" );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment