Calculate backtracking algorithm complexity - time-complexity

I'm having a hard time calculating the complexity of the best, mean and worst case n queens puzzle algorithm. Please help me, thanks
#include <stdio.h>
#include <math.h>
#define max 10
int n,x[max],count=0;
int check(int v,int i){
for(int j=1;j<i;j++){
if (v==x[j]||fabs(v-x[j])==fabs(i-j)) return 0;
}
return 1;
}
void solution(){
printf("\n Giai phap so %d la hang--cot",++count);
for(int m=1;m<=n;m++) printf(" %d--%d ",m,x[m]);
}
void Btrack(int i){
for(int v=1;v<=n;v++) //v co th la UCV
if(check(v,i)){
x[i]=v;
if(i==n) solution();
else Btrack(i+1);
}
}
int main(){
n=8;
Btrack(1);
return 0;
}
I try to calculate f(i) to f(i+1) with f(i) is complexity of Btrack(i)

Related

Threads indexing out of bounds in CUDA kernel

I am running a CUDA kernel which seems to be indexing out of bounds and I can not figure out why. I get error 8 write-of-size in cuda-memcheck.
I have tried to change the number of blocks and the number of threads in each block as well as only running a fraction of all iterations needed. Here is some usefull information as well as a replicable example which gives the error:
blockSize: 128
numBlocks: 512
Nvidia GTX 970
#include <iostream>
#include <cuda_runtime_api.h>
#include <cuda.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <vector>
#include <iterator>
#include <cuda_profiler_api.h>
#include <algorithm>
#include <cmath>
#include <numeric>
#include <stdio.h>
#include <fstream>
__host__
int NchooseK(const int &N, const int &K)
{
int result = 1;
for (int i = 1; i <= K; i++)
{
result *= N - (K - i);
result /= i;
}
return result;
}
__host__
inline int get_flatten_size(const unsigned int N){
int sum = 0;
for(int i=1; i<=N ; i++){
sum +=i*NchooseK(N,i);
}
return sum;
}
__host__
std::vector<int> comb(const int &N, const int &K, const int &length)
//void comb(int N, int K, int length)
{
int k;
std::vector<int> vec(K);
std::vector<int> flatten_vec(0);
std::string bitmask(K, 1); // K leading 1's
bitmask.resize(N, 0); // N-K trailing 0's
for (int j = 0; j < length; j++) {
k = 0;
for (int i = 0; i < N; ++i) // [0..N-1] integers
{
if (bitmask[i]) {
//std::cout << i << " ";
vec[k] = i;
k++;
}
//std::cout << std::endl;
}
std::prev_permutation(bitmask.begin(), bitmask.end());
flatten_vec.insert(flatten_vec.end(), vec.begin(),vec.end());
}
return flatten_vec;
}
__host__
void get_matrix_indices(const unsigned int N, int *sub_col, int *sub_size, int *cumulative_size)
{
int size, itterator = 0;
cumulative_size[0] = 0;
std::vector<int> size_i_columns;
std::vector<int> all_columns(0);
for(int i=1; i<=N; i++){
size = NchooseK(N,i);
size_i_columns = comb(N,i,size);
for(int j=0; j<size; j++){
sub_size[itterator]=i;
cumulative_size[itterator+1]=cumulative_size[itterator]+i;
itterator++;
}
all_columns.insert(all_columns.end(),size_i_columns.begin(),size_i_columns.end());
}
//sub_col = &all_columns[0];
for(int i = 0; i < all_columns.size(); i++) sub_col[i] = all_columns[i];
}
__global__
void comb_ols(const unsigned int M, const unsigned int N, int* sub_col, int *sub_size, int* cumulative_size, const unsigned int numberOfCalculations, const unsigned int max_size){
int size;
int start_index;
int index = blockIdx.x*blockDim.x+threadIdx.x;
int stride = blockDim.x*gridDim.x;
double *sub_matrix = new double[M*(1+max_size)];
for(int i = index; i < numberOfCalculations; i+=stride){
size = sub_size[i];
start_index = cumulative_size[i];
for(int j = 0; j < size; j++){
for(int k = 0; k<M; k++){
sub_matrix[k] = 1;
}
}
}
delete [] sub_matrix;
}
And then we the main function:
int main()
{
int N = 17;
int M = 263;
const unsigned int regressors = N-1;
const unsigned int numberOfCalculations = (int) (exp2((double) regressors) - 1);
const unsigned int size_sub_col = get_flatten_size(regressors);
int blockSize =128;
int numBlocks = (numberOfCalculations + blockSize-1)/blockSize;
std::cout << "\nblockSize :" << blockSize;
std::cout << "\nnumBlocks :" << numBlocks;
std::cout << "\nblockSize*numBlocks :" << blockSize*numBlocks;
std::cout << "\nregressors :" << regressors;
std::cout << "\nNumberOfCalculations :" << numberOfCalculations;
std::cout << "\nsize_sub_col :" << size_sub_col << '\n' ;
int *sub_size, *cumulative_size, *sub_columns;
cudaMallocManaged(&sub_size, numberOfCalculations*sizeof(int));
cudaMallocManaged(&cumulative_size, (numberOfCalculations+1)*sizeof(int));
cudaMallocManaged(&sub_columns, size_sub_col*sizeof(int));
get_matrix_indices(regressors,sub_columns, sub_size, cumulative_size);
const unsigned int max_size = N*M;
cudaProfilerStart();
comb_ols<<<numBlocks, blockSize>>>(M,N,sub_columns, sub_size, cumulative_size, numberOfCalculations, max_size);
cudaProfilerStop();
cudaDeviceSynchronize();
cudaFree(sub_size);
cudaFree(cumulative_size);
cudaFree(sub_columns);
return 0;
}
I fail to see why the threads would try to access illegal memory space. The way I understood is that the matrix sub_matrix will be initilized on each thread once and then the parallel for loop happens. Thus should each thread have the necessary memory space. Am I allocating too much memory on the GPU? How is "new sub_matrix" handled here?
If I read your code correctly, each thread is attempting to allocate M * (1 + M*N) doubles, which is 263 * ( 1 + 263*17) = ‭1,176,136‬ doubles, or 8.97Mb of heap memory per thread. You launch 128 * 512 threads. That would mean you require 588Gb of heap space for the kernel to run successfully.
Clearly your GPU lacks that amount of memory and the out of bounds memory access comes from failures in the new call (which you can check for, BTW).
Might I suggest that something in the size calculations for the heap memory you require is wrong. Otherwise you have an extremely unrealistic problem for the GPU and will require some other approach.
Note that even if you manage to redesign things to limit the code to a feasible malloc heap memory size, you will still need, in all likelihood, to resize the malloc heap to a suitable size before running the kernel. The cudaDeviceSetLimit API can be used for this.

BIG WEIRD ANSWER in a MATRIX multiplication program

this is a program to multiply 2 matrixes which comes in maths, but dont know why, am getting answers like "-1282230" or some weird numbers. I would like to know what is causing it and how could i fix it? THANK YOU!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
int m[3][3],m2[3][3],i,je,k,ans[3][3],sum;
// taking inputs from the user for matrix1
printf("Enter the numbers for first matrix");
je=0;
for(i=0;i<3;i++){
printf(" for row %d\n",i+1);
for(je=0;je<3;je++){
scanf("%d",&m[i][je]);
}
}
// taking inputs from the user for matrix2
printf("Enter the numbers for second matrix");
je=0;
for(i=0;i<3;i++){
printf(" for row = %d\n",i+1);
for(je=0;je<3;je++){
scanf("%d",&m2[i][je]);
}
}
// multiplication OR MATRIX CMS HERE;
sum = 0;
for(k=0;k<9;k++){
for(i=0;i<3;i++){
for(je=0;je<3;je++){
sum = m[k][je] * m2[je][i];
ans[i][je] = sum;
}
}
k++;
}
// it ENDS;
puts("ANSWER IS:: \n");
// Displaying answer, matrix;
for(i=0;i<3;i++){
for(je=0;je<3;je++){
printf("%d\t",ans[i][je]);
}
printf("\n");
}
return 0;
}
Here's a working solution. One of the problem with your code is that you aren't setting the sum to 0 after each multiplication.
#include <stdio.h>
int main() {
int m, n, p, q, c, d, k, sum = 0; int first[10][10], second[10][10], multiply[10][10];
printf("Enter number of rows and columns of first matrix\n"); scanf("%d%d", &m, &n); printf("Enter elements of first matrix\n");
for (c = 0; c < m; c++)
for (d = 0; d < n; d++)
scanf("%d", &first[c][d]);
printf("Enter number of rows and columns of second matrix\n"); scanf("%d%d", &p, &q);
if (n != p)
printf("The matrices can't be multiplied with each other.\n"); else {
printf("Enter elements of second matrix\n");
for (c = 0; c < p; c++)
for (d = 0; d < q; d++)
scanf("%d", &second[c][d]);
for (c = 0; c < m; c++) {
for (d = 0; d < q; d++) {
for (k = 0; k < p; k++) {
sum = sum + first[c][k]*second[k][d];
}
multiply[c][d] = sum;
sum = 0;
}
}
printf("Product of the matrices:\n");
for (c = 0; c < m; c++) {
for (d = 0; d < q; d++)
printf("%d\t", multiply[c][d]);
printf("\n");
}
}
return 0; }

Confusion about my QuickSort algorithm & Mergesort algorithm

I am currently conducting empirical studies to evaluate the run-time complexities of the quicksort, and mergesort algorithms. To do this I run a random number generator that stores whatever amount of numbers I specify in a binary file. The ranges of those numbers are from 1-1,000,000.I then run tests of each algorithm starting from 100,000 numbers, incrementing by 50,000 each time, until 1,000,000 numbers are sorted on the last run. So 20 tests each. I have successfully completed each algorithm but my results are kind of puzzingly. This is a graph showing my results.
I understand that quicksort has a worst case of O(n2) time, but typically O(n·lg(n)) time. Mergesort has Θ(n·lg(n)) time.
Also I would like to note that when I started the timer I just used clock() from time.h, and calculated the time elapsed. I started my timer one line of code before I called my sorting function.
What I dont understand is how my graph shows mergesort is always double the time, and reaching triple the time to sort numbers compared to quicksort.
My only thought is that for my mergesort algorithm every time I divide my array in half I use malloc to create a new integer array for each half. Of course this means a large amount of calls are made to malloc considering the number sizes I am sorting.
int* mergeSort(int* nums, int size){
int* left;
int* right;
int middle = size/2;
if(size <= 1)
return nums;
split(nums, size, &left, &right, middle);
//I dont understand why the code below wouldnt work in place of the split()
//when i run it, in main, nothing gets printed out. I guess i lose my pointer to the beginning of my array.
//left = nums;
//right = nums+middle;
left = mergeSort(left, middle);
right = mergeSort(right, size - middle);
merge(nums,left,right,middle,size - middle);
free(left);
free(right);
return nums;
}
void split(int* nums, int size, int** left, int** right, int middle){
int *lft = (int*) malloc ((sizeof(int) * middle));
int *rght = (int*) malloc ((sizeof(int) * size - middle));
int mid = middle;
int upMid = size - middle;
int i;
for(i=0; i < mid; i++)
lft[i] = nums[i];
for(i=0; i < upMid; i++)
rght[i] = nums[i+middle];
*left = lft;
*right = rght;
}
void merge(int* num, int* left, int* right, int sizeLeft, int sizeRight){
int i,j,k,n;
i=j=k=0;
n=sizeLeft + sizeRight;
while(k < n){
if(i< sizeLeft){
if(j<sizeRight){
insert(num,left,right,&i,&j,&k);
}
else{
append(num, left, sizeLeft, &i, &k);
}
}
else{
append(num,right,sizeRight,&j,&k);
}
}
}
void insert(int* num, int* left, int* right, int* i, int* j, int* k){
/*int i,j,k,n;*/
if(left[*i]<right[*j]){
num[*k] = left[*i];
(*i)++;
}
else{
num[*k] = right[*j];
(*j)++;
}
(*k)++;
}
void append(int* num, int* half, int sizeHalf, int* i, int* k){
while(*i < sizeHalf){
num[*k]= half[*i];
(*i)++; (*k)++;
}
}
I would greatly appreciate any feedback on this question of mine, and any advice on maybe making my mergesort function more efficient. Thanks!!
I have implemented a merge sort algorithm, you can have a look. I malloc a bak array at the beginning of mergeSort and every merge use the it afterwards.
#include <string>
#include <stdlib.h>
void _mergeSort(int *array, int *bakArray, int len) ;
void mergeSort(int *array, int len)
{
int *bak = (int *)malloc(sizeof(int)*len) ;
_mergeSort(array, bak, len) ;
free(bak) ;
}
void _mergeSort(int *array, int *bakArray, int len)
{
if (len >= 2) {
int leftLen = len/2 ;
_mergeSort(array, bakArray, leftLen) ;
_mergeSort(array+leftLen, bakArray, len-leftLen) ;
int *pa = array ;
int *pb = array+leftLen ;
int aIndex = 0 ;
int bIndex = 0 ;
while (aIndex < leftLen && bIndex < len-leftLen) {
int a = pa[aIndex] ;
int b = pb[bIndex] ;
if (a < b) {
bakArray[aIndex+bIndex] = a ;
++aIndex ;
} else if (a == b) {
bakArray[aIndex+bIndex] = a ;
bakArray[aIndex+bIndex+1] = a ;
++aIndex ;
++bIndex ;
} else {
bakArray[aIndex+bIndex] = b ;
++bIndex ;
}
}
if (aIndex < leftLen) {
memcpy(bakArray+aIndex+bIndex, pa+aIndex, sizeof(int)*(leftLen-aIndex)) ;
} else if (bIndex < len-leftLen) {
memcpy(bakArray+aIndex+bIndex, pb+bIndex, sizeof(int)*(len-leftLen-bIndex)) ;
}
memcpy(array, bakArray, sizeof(int)*len) ;
}
}
static const int MaxArraySize = 100 ;
int main()
{
srand(time(NULL)) ;
int array[MaxArraySize] ;
for (int i = 0 ; i < MaxArraySize; ++i) {
array[i] = rand() % 10000 ;
}
mergeSort(array, MaxArraySize) ;
for (int i = 0 ; i < MaxArraySize; ++i) {
printf("%d ", array[i]) ;
}
printf("\n") ;
return 0 ;
}

Nested if else if statements with multiple variable for loops

Below is the code I am using for a program which is to be used for an airplane seating selection. It seats passengers based upon either a smoking or non-smoking preference.
I am using nested if else statements with 2 variables in each as counters and accumulators as well as nested if-then-else statements which should fill the assign[] array of structures.
Am I unable to copy arrays of structures directly into other arrays of structures using counters for the indexes? Help*/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace System;
using namespace std;
struct passengers{
char plname[15] ;//passenger name in array
char pfname[15];
char stPref;// = seat preference, either S smoking or N non-smoking
int row;//row 0-40 (41 rows) index data, to be used later to match the index to the structure of array index
int col; //column 1-3
};struct passengers waiting[41];//Hard Coded Array of struct passengers waiting members for use with output testing
//= {{"WOODS","BILL",'S',10,2},{"BORAX","M T", 'S', 9, 2},{"THOMAS","LINDA",'N',7,2},{"HAYWARD","MARK",'N',7,3},{"SWIFT","TOM",'N',8,1},{"DOBBS","DR.",'N',8,2},{"GOLDEN","VINNIE",'N',8,3},{"HACKER","E",'N',5,3},{"RUSSEL","STEVE",'N',5,1},{"CHAMPION","SPARKY",'N',3,1},{"INNERMENTS","TEX",'S',8,2}};
//Hard Coded Array of struct passengers all[41]. This is a list of all people that want on the plane
struct passengers all[41] = {{"SMITH","JOHN",'N',3,2},{"STEVE","JOBS",'S',9,3},{"CAPONE","AL",'N',3,2},{"JACKSON","MICHAEL",'S',8,1},{"HUMPHREY","H",'S',8,2},{"RINEHART","JIM",'N',3,1},{"EASTMAN","KEN",'N',1,1},{"WINSTON","SALEM",'S',8,3},{"SMYTHE","SUSAN",'S',9,1},{"KENDRIKS","AL",'N',9,2},{"ALLISON","DENNIS",'S',9,3},{"GREENBLATT","RICHARD",'S',10,1},{"DAVIS","BOB",'S',10,3},{"WOODS","BILL",'S',10,2},{"BORAX","M T",'S',9,2},{"HENRY","JOHN",'N',1,2},{"STEVASON","E",'N',1,3},{"WILLIAMS","KEN",'N',2,1},{"SMITH","MARTHA",'N',2,2},{"KOCH","JOE",'N',2,3},{"PACKARD","H P",'N',3,3},{"RINEHART","JANE",'N',3,2},{"SWENSON","CECIL",'N',4,1},{"CORY","TROY",'N',4,2},{"BYES","NICKOLINE",'N',4,3},{"BYES","JENNIFER",'N',5,3},{"HARRIS","JOHN",'N',5,2},{"HARRIS","JUDY",'N',5,1},{"HARTMAN","F G",'N',6,1},{"SOUSE","D T",'N',6,2},{"JOHNSON","MAGIC",'N',6,3},{"LAMPTON","GEORGE",'N',7,1},{"THOMAS","LINDA",'N',7,2},{"HAYWARD","MARK",'N',7,3},{"SWIFT","TOM",'N',8,1},{"DOBBS","DR.",'N',8,2},{"GOLDEN","VINNIE",'N',8,3},{"HACKER","E.",'N',5,3},{"RUSSEL","STEVE.",'N',5,2},{"CHAMPION","SPARKY.",'N',3,1},{"INNERMENTS","TEX.",'S',8,2}};
struct passengers assign[30];//Array of structures for the actual seating assignment
//Initializes char array plane so all seats are empty
char plane[10][3] = { {'E','E','E'},{'E','E','E'},{'E','E','E'},{'E','E','E'},{'E','E','E'},{'E','E','E'},{'E','E','E'},{'E','E','E'},{'E','E','E'},{'E','E','E'} };
int x,y,z,a,b,c,count = 0;//Declares integer variables for use with accumulators and counters.
void entList();//Enter function prototype
void prtList();//Print function prototype
void seatPrgm();//Enters Passengers based on seat availability
/******************************************* Main Program ********************************************************************/
int main()
{
/********** Decision, Selection, Iteration Section... Assigns Seats based on Availability **********/
while (z<41)
{
//seatPrgm();
//************************************ User Case Selection Menu *******************************************/
char menu = '#';//Declares menu a character variable.This variable will be used for the menu selections and has a default value
//of # to ensure no problems with it's buffer.
printf("\t\t\tWelcome to Fast Flights.\n\n\t\tPlease Make a selection from thew menu\n\n");//User Prompt
printf("\t\tE to Enter Passenger Seating Information\n\t\tP to Print the Assigned Seating Report\n\t\tQ to quit.\n\n");
scanf("%c",&menu);//scans in the menu selection
while(menu !='Q')//While variable menu does not equal Q...
{
menu =(toupper(menu));
switch(menu)//Switch Statement generates a case selection menu...
{
case 'E' : entList();
printf("\n\t\t\n\n");
system("pause");
scanf("%c",&menu);
break;
case 'P' : prtList();
printf("\n\t\t\n\n");
system("pause");
scanf("%c",&menu);
break;
default : if (menu!= 'Q')
printf("\n\t\nPlease enter one of the selections\n");
else printf("\n");
scanf("%c",&menu);
system("pause");
break;
}
}
system("pause");//namespace system pause Pauses the program long enough to display data
return 0;//returns null value to int main()
}
}
void entList()
{ /*count=0;
printf("\tPlease enter passenger name and seating preferences\n");
printf("\nPassenger Name:");
gets(assign[count].pname);
// scanf("%c"); // this gets the enter key left over in the buffer - do not need this after a gets
printf("\nSeating Preference Smoking or Non-Smoking? Please enter S or N:");
scanf("%c",&assign[count].stPref);
// it was skipping because I had formatting in the scanf statement
printf("\nEnter the Seat Row Number:");
scanf("%c",&assign[count].row);
printf("\nEnter the Seat Column Number:");
scanf("%c",&assign[count].col);
count++;*/
}
//Print Function Header
void prtList()
{
/************** This section prints the first header for the Non-Smoking Section ***********************/
printf("\n\n");
for (x = 0; x<80; x++)
printf("*"); //Prints the asterisks in the heading
printf("\n");
for (x = 0; x<6; x++)
printf("*");
printf("\n");
printf("*\t\t\tNon Smoking Section\n");
printf("*\n");
for (x = 0; x<80; x++)
printf("*");
for (x = 0; x<6; x++)
printf("*");
printf("*\n");
/****************** Prints the Non-Smoking Section Seating Assignments ****************************************/
printf("\n");
x=0;
for(a=0;a<7;a++)
{
for(b=0;b<3;b++) //Prints passengers assign.[30] structure of arrays Non Smoking Section last name and first name members
{
printf("\t%s %s\t", all[x].plname,all[x].pfname);
x++;
}
printf("\n");
}
/*************************************************************************************/
/************** This section prints the second header for the Smoking Section ***********************/
printf("\n\n");
for (x = 0; x<80; x++)
printf("*"); //Prints the asterisks in the heading
printf("\n");
for (x = 0; x<6; x++)
printf("*");
printf("\n");
printf("*\t\t\tSmoking Section\n");
printf("*\n");
for (x = 0; x<80; x++)
printf(".");
/******************** Prints the Smoking Section Seating Assignments ********************************************/
for(x=0;x<10;x++)
{
for(y=0;y<3;y++) //print tests output for plane array
printf("%c ",plane[x][y]);
printf("\n");
}
x=0;
for(a=0;a<10;a++)
{
for(b=0;b<3;b++) //print test for all array of structures
{
printf("%s %s\t", all[x].pfname,all[x].plname);
x++;
}
printf("\n");
}
printf("\n");
x=0;
for(a=8;a<11;a++)
{
for(b=0;b<3;b++)
{
printf("\t%s %s\t", assign[x].plname,assign[x].pfname);
x++;
}
printf("\n");
}
/********************** This section prints the third header for the Waiting List *******************************/
printf("\n\n");
for (x = 0; x<80; x++)
printf("*"); //Prints the asterisks in the heading
printf("\n");
for (x = 0; x<6; x++)
printf("*");
printf("\n");
printf("*\t\t\t\tWaiting List\n");
printf("*\n");
printf("*\tNAME\t\tSMOKING CHOICE\t\tROW\t\tCOLUMN\n");
printf("*\n");
for (x = 0; x<80; x++)
printf(".");
/****************************** Prints the Waiting List Info ********************************************************/
printf("\n");
x = 0;
for(a=0;a<11;a++)
{
printf("%i\t%s %s\t\t%c\t\t%i\t\t%i",(a+1),waiting[x].plname,waiting[x].pfname,waiting[x].stPref,waiting[x].row,waiting[x].col);
x++;
printf("\n");
}
/************************************ End of Function *************************************************/
}
void seatPrgm()
{
a=0;
z=0;
for(x=0;x<10;x++)
{
for(y=0;y<3;y++) //FIX THIS!!!!!!!!!!!!!!!!
{
while((plane[x][y]) == 'E') //While empty
{
if((all[z].stPref)=='N')
{
(all[z] = assign[a+1]); //Fills the assigned seats
(plane[x][y] == 'F');
z++;
a++;
}
else
{
(all[z] = assign[a+1]);
(plane[x][y] == 'F');
z++;
a++;
};
};
while(plane[x][y] == 'F') //Puts them on the waiting list if that seat is already occupied or 'F' FULL.
{
while(z<41)
{
(all[z] = waiting[z]);
z++;
a++;
};
};
};
};
}

Collatz sequence?

Im trying to solve the Collatz problem. It's all working except of one my int highest which should compare whether counter of one number is greater than counter of next number seems not to be working. I also tried my highest variable as array but still getting no result. Thanks for your any advice.
#include <vector>
#include <iostream>
using namespace std;
int main()
{
__int64 num;
int i;
int counter=0;
//vector<int> a(1000000);
//vector<int> b(1000000);
__int64 highest=0;
int j=0;
for(j=2;j<=1000000;j++)
{
num=j;
counter=0;
for(i=0;i<1000000;i++)
{
cout<<"num is: "<<j<<endl;
if(num==1)
{
break;
}
if(num%2==0)
{
num = num/2;
counter++;
cout<<num<<endl;
}
else if(num%2!=0)
{
counter++;
num= (num*3)+1;
cout<<num<<endl;
}
}
cout<<"counter: "<<counter<<endl;
//this part is not working
if(highest<=counter)
{
highest=counter;
cout<<"highest is: "<<highest<<endl;
}
}
return 0;
}