Related
I try to use Jacobian matrix to solve the logistic parameter y=k/(1+exp(-rt+b)) for the non linear regression using GSL c++ library without success possibly the respective derivatives to three variable k,r, and b are wrong , below are my C++ code snippet .
If I set the fdf.df=NULL;
I can obtains the non-optimised parameter of which I have compared with known Fortran solver , the k value seemed not optimised . Could someone suggest how to code properly the Jacobian matrix under
int expb_df please?
#include<gsl/gsl_vector.h>
#include<gsl/gsl_matrix.h>
#include <gsl/gsl_randist.h>
#include<gsl/gsl_rng.h>
#include<gsl/gsl_blas.h>
#include<gsl/gsl_multifit_nlinear.h>
vector<int> vec_indata = {3, 1, 0, 0, 3, 1, 0, 0, 0, 0, 2, 2, 0, 0, 4, 0, 2, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
2, 4, 3, 4, 14, 5, 28, 10, 6, 18, 12, 20, 9, 39, 41, 190, 125, 120, 117, 110, 130, 153, 123, 212, 106,
172, 235, 130, 159, 150, 156, 140, 142, 208, 217, 150, 179, 131, 170, 156, 109, 118, 184, 153, 134, 170,
85, 110, 69, 54, 84, 36, 57, 50, 71, 88, 51, 38, 40, 31, 94, 57, 69, 105, 122, 55, 30, 45, 39, 68, 54,
67, 70, 16, 37, 40, 36, 17, 22, 47, 37, 31, 50, 78, 48, 60, 172, 187, 15, 10, 103, 30, 57, 38, 20, 93,
277, 19, 37, 19, 7, 7, 2, 31, 33, 43, 8, 41, 11, 10, 14, 6, 21, 16, 15, 3, 6, 4, 6, 10, 18, 3, 2, 1, 3,
5, 10, 5, 5, 6,3,6,13,8,14,7,4,5,3,18,9,15,21,15,16,9,21,23,13,7,39,13,8,12,9,14,2,1,21,15,25,7,13,
11,9,11,15,20,26,25,12,7,16,5,9,8,10,7,11,6,5,10,11,17,6,14,6,14,11,6,6,62,100,24};
int expb_f(const gsl_vector *x, void *indata, gsl_vector *f) {
size_t n = ((struct idata*)indata)->n;
double *t = ((struct idata*)indata)->t;
double *y = ((struct idata*)indata)->y;
double k = gsl_vector_get(x, 0);
double r = gsl_vector_get(x, 1);
double b = gsl_vector_get(x, 2);
size_t i;
for (int i = 0; i < n; i++) {
/* logistic Model y=k/(1+exp(-r*t+b)) */
double y_hat = k / (1 + std::exp(-r * t[i] + b));
gsl_vector_set(f, i, y_hat - y[i]);
}
return GSL_SUCCESS;
}
int expb_df(const gsl_vector * x, void *data, gsl_matrix * J) {
size_t n = ((struct idata*)data)->n;
double *t = ((struct idata*)data)->t;
double *y = ((struct idata*)data)->y;
double k = gsl_vector_get(x, 0);
double r = gsl_vector_get(x, 1);
double b = gsl_vector_get(x, 2);
size_t i;
for (int i = 0; i < n; i++) {
double dv = -1 * std::pow((1 + std::exp(-r * t[i])), -2);
double e = std::exp(-r * t[i] + b);
gsl_matrix_set(J, i, 0, 1);
gsl_matrix_set(J, i, 1, -t[i]*e);
gsl_matrix_set(J, i, 2, -e);
}
return GSL_SUCCESS;
}
void callback(const size_t iter, void *params,
const gsl_multifit_nlinear_workspace *w) {
String out_txt;
gsl_vector *f = gsl_multifit_nlinear_residual(w);
gsl_vector *x = gsl_multifit_nlinear_position(w);
double rcond;
/* compute reciprocal condition number of J(x) */
// gsl_multifit_nlinear_rcond(&rcond, w);
out_txt = "Iter " + String(iter) + " k=" + String(gsl_vector_get(x, 0)) +
" r=" + String(gsl_vector_get(x, 1)) + " b=" +
String(gsl_vector_get(x, 2)) + " ," + String(gsl_blas_dnrm2(f)) +
"\r\n" + out_txt;
}
void FitLogistic() {
const gsl_multifit_nlinear_type *T = gsl_multifit_nlinear_trust;
gsl_multifit_nlinear_workspace *w;
gsl_multifit_nlinear_fdf fdf;
gsl_multifit_nlinear_parameters fdf_params =
gsl_multifit_nlinear_default_parameters();
size_t N = size(vec_indata);
const size_t n = N;
const size_t p = 3;
gsl_vector *f;
gsl_matrix *J;
gsl_matrix *covar = gsl_matrix_alloc(p, p);
double t[N], y[N], weights[N];
struct idata d = {
n, t, y
};
double x_init[3] = {20000, 0.01, 1};
gsl_vector_view x = gsl_vector_view_array(x_init, p);
gsl_vector_view wts = gsl_vector_view_array(weights, n);
double chisq, chisq0;
int status, info;
size_t i;
const double xtol = 1e-8;
const double gtol = 1e-8;
const double ftol = 0.0;
/* define the function to be minimized */
fdf.f = expb_f;
// jacobian matrix
fdf.df=NULL;
//fdf.df = expb_df;
fdf.fvv = NULL;
fdf.n = n;
fdf.p = p;
fdf.params = &d;
int cum_actual_cnt = 0;
// ShowMessage(String(N));
for (i = 0; i < N; i++) {
// t[i] = i*N/(n-1);
t[i] = i;
y[i] = vec_indata.at(i) + cum_actual_cnt;
cum_actual_cnt += vec_indata.at(i);
weights[i] = 1 / ((0.1 * y[i]) * (0.1 * y[i]));
}
// ShowMessage(String(y[N-1]));
/* allocate workspace with default parameters */
w = gsl_multifit_nlinear_alloc(T, &fdf_params, n, p);
/* initialize solver with starting point and weights */
gsl_multifit_nlinear_init(&x.vector, &fdf, w);
// gsl_multifit_nlinear_winit(&x.vector, &wts.vector, &fdf, w);
/* solve the system with a maximum of 1000 iterations */
status = gsl_multifit_nlinear_driver(1000, xtol, gtol, ftol, callback, NULL,
&info, w);
ShowMessage("Fit Status " + String(gsl_strerror(status)) + " " +
gsl_multifit_nlinear_name(w) + "/" + gsl_multifit_nlinear_trs_name(w));
/* compute covariance of best fit parameters */
J = gsl_multifit_nlinear_jac(w);
gsl_multifit_nlinear_covar(J, 0.0, covar);
gsl_multifit_nlinear_free(w);
}
After adjusting for the error in the partial derivative with respect to k,r,and b , I manage to obtain the output result exactly similar to above code which was coded without assigning the Jacobian matrix or putting fdf.df=NULL; I am not able to ascertain if the solution is optimum or not , may be someone is able to comment , thanks
fdf.df = expb_df;
for (int i = 0; i < n; i++) {
double dv = std::pow((1 + std::exp(-r * t[i] + b)), 2);
double e = std::exp(-r * t[i] + b);
double u =1+ std::exp(-r * t[i] + b);
sigma = i - 1;
gsl_matrix_set(J, i, 0, 1/u);
gsl_matrix_set(J, i, 1, (k*t[i]*e)/(u*u));
gsl_matrix_set(J, i, 2, (-k*e)/(u*u));
}
Let's say I have this array:
int oldv[10] = {16, 12, 24, 96, 45, 22, 18, 63, 47, 56};
and another one like
int newv[8];
and I want to fill new from alternating ends of old until a certain condition is met such that I'd have:
newv = [16, 56, 12, 47, 24, 63 ...]
Let's say I want to put in new only 3 numbers taken from old (that is: 16, 56, 12).
I've tried with the following for loop, but of course is not enough...
for(int i = 0; i < 3; i++)
newv[i] = oldv[i*(sizeof(oldv)-1)];
Any help?
int _old[10] = {16, 12, 24, 96, 45, 22, 18, 63, 47, 56};
int _new[8];
const int old_size = sizeof(_old)/sizeof(int);
const int new_size = sizeof(_new)/sizeof(int);
for (int i = 0; i < new_size; ++i)
{
if (i % 2)
_new[i] = _old[old_size - i / 2 - 1];
else
_new[i] = _old[i / 2];
std::cout << _new[i] << " ";
}
std::cout << std::endl;
Returns 16 56 12 47 24 63 96 18
See it live
Enjoy.
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
int main(int, char**)
{
int oldv[] = { 16, 12, 24, 96, 45, 22, 18, 63, 47, 56 };
int newv[8];
size_t numbers_i_want = 3;
size_t oldv_b = 0;
size_t oldv_e = sizeof oldv / sizeof *oldv;
size_t newv_e = sizeof newv / sizeof *newv;
for(size_t i = 0;
i != min(numbers_i_want, newv_e) && oldv_b != oldv_e;
++i)
{
newv[i] = (i % 2) ? oldv[--oldv_e] : oldv[oldv_b++];
}
copy(newv, newv + min(numbers_i_want, newv_e),
ostream_iterator<decltype(*newv)>(cout, " "));
return 0;
}
I am trying to make a shell algorithm to arrange a [5][5][5] array, so far I can print the whole array but when I run shell() it prints the same array. It doesn't print the numbers arranged. Any help please?
#include <iostream>
#include <stdlib.h>
using namespace std;
void ordShell(int numbers[5][5][5], int n);
void exchange(int& x, int& y);
int main()
{
int numbers[5][5][5] = {
{ {1,2,3,4,5}, {41,42,43,44,45}, {11,12,13,14,15}, {16, 17, 18, 19, 20}, {21, 22, 23, 24, 25} },
{ {26,27,28,29,30}, {31,32,33,34,35 }, {36,37,38,39,40}, {6,7,8,9,10}, {46, 47, 48, 49, 50}, },
{ {51, 52, 53, 54, 55}, {56,57,58,59,60}, {61,62,63,64,65}, {66, 67, 68, 69, 70}, {71, 72, 73, 74, 75}, },
{ {76, 77, 78, 79, 80}, {81,82,83,84,85}, {86,87,88,89,90}, {91, 92, 93, 94, 95}, {96, 97, 98, 99, 100}, },
{ {101, 102, 103, 104, 105}, {106,107,108,109,110}, {111, 112, 113, 114, 115}, {116, 117, 118, 119, 120}, {121, 122, 123, 124, 125} }
};
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
for(int l=0;l<5;l++)
{
cout<<numbers[i][j][l]<<",";
}
}}
cout<<"whatever"<<"";
cout<<"\n"<<"";
cout<<"NOW COMES SHELL"<<"";
ordShell(numbers,5);
cout<<"NUMBERS ARRANGED AFTER SHELL"<<"";
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
for(int l=0;l<5;l++)
{
cout<<numbers[i][j][l]<<",";
}
}}
return 0;
}
void ordShell(int numbers[5][5][5], int n)
{
int jump, i, j, k,j1,j2,k1,k2;
jump = n / 2;
while (jump > 0)
{
for (i = jump; i < n; i++)
{
j = i - jump;
j1= i - jump;
j2= i - jump;
while (j >= 0 )
{
k = j + jump;
k1 = j + jump;
k2 = j + jump;
if (numbers[j][j1][j2] <= numbers[k][k1][k2])
{j = -1; // arranged pair
j1 = -1;
j2 = -1;}
else
{
cout<<"exchange: "<<"";
cout<<numbers[j][j1][j2]<<" ";
cout<<numbers[k][k1][k2]<<"\n";
exchange(numbers[j][j1][j2], numbers[k][k1][k2]);
j -= jump;
j1 -= jump;
j2 -= jump;
}
}
}
jump = jump / 2;
cout<<"Jump: "<<jump<<"\n";
}
}
void exchange(int& x, int& y)
{
int aux = x;
x = y;
y = aux;
}
The problem is quite simple in your function: you aren't modifying the array but only a copy of it:
void ordShell(int numbers[5][5][5], int n)//makes a copy of numbers
If you want to avoid the issue, you need to give a pointer to your function instead.
However, the C++ way is to use the STL instead so you should make your array that way: std::vector<std::vector<std::vector<int> > > (you can use the same initialization after)
That way in your function you would only need to pass a reference to this:
void ordShell(std::vector<std::vector<std::vector<int> > >& numbers, int n)
You can also use typedef to make the variable name easier to read:
typedef std::vector<std::vector<std::vector<int> > > vector3D
And one last thing, you don't need your exchange function, std::swap does the same thing.
I'm trying to solve the 11th problem on ProjectEuler.net. The goal for this problem is to find the largest product in a 20x20 grid of 4 adjacent numbers in any direction (up, down, right, left, diagonal).
I'm using the BigInteger library because I don't know how large will the numbers be and I don't want an overflow - but I think this might be the problem. Every time I restart the program I get a different answer. :/ I also tried to use an unsigned long long int just to see what will happen - the answer remained the same.
This is the code (Nothing complicated; I just test every element in the grid to see if it has 3 adjacent numbers in any direction, compute the product and set it as the new largest if it is larger than the previous one. On the end I print the largest product.):
//NO.11
#include <iostream>
#include <BigIntegerLibrary.hh>
#include <windows.h>
int main()
{
int grid[20][20] =
{
{ 8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8},
{49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0},
{81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65},
{52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 2, 36, 91},
{22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80},
{24, 47, 32, 60, 99, 03, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50},
{32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70},
{67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21},
{24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72},
{21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95},
{78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92},
{16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57},
{86, 56, 0, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58},
{19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40},
{ 4, 52, 8, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66},
{88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69},
{ 4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36},
{20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16},
{20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54},
{ 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48}
};
BigInteger biggestProduct = 0;
//unsigned long long int biggestProduct = 0;
for (int row = 0; row < 20; row++)
{
for (int col = 0; col < 20; col++)
{
BigInteger product;
//unsigned long long int product;
//std::cout << grid[row][col] << ":" << std::endl; system("pause>nul");
//UP
if ((row-1 >= 0) && (row-2 >= 0) && (row-3 >= 0))
{
product = grid[row][col] * grid[row-1][col] * grid[row-2][col] * grid[row-3][col];
//std::cout << " U: " << grid[row][col] << "*" << grid[row-1][col] << "*" << grid[row-2][col] << "*" << grid[row-3][col] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
//DOWN
if ((row+1 >= 0) && (row+2 >= 0) && (row+3 >= 0))
{
product = grid[row][col] * grid[row+1][col] * grid[row+2][col] * grid[row+3][col];
//std::cout << " D: " << grid[row][col] << "*" << grid[row+1][col] << "*" << grid[row+2][col] << "*" << grid[row+3][col] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
//RIGHT
if ((col+1 >= 0) && (col+2 >= 0) && (col+3 >= 0))
{
product = grid[row][col] * grid[row][col+1] * grid[row][col+2] * grid[row][col+3];
//std::cout << " R: " << grid[row][col] << "*" << grid[row][col+1] << "*" << grid[row][col+2] << "*" << grid[row][col+3] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
//LEFT
if ((col-1 >= 0) && (col-2 >= 0) && (col-3 >= 0))
{
product = grid[row][col] * grid[row][col-1] * grid[row][col-2] * grid[row][col-3];
//std::cout << " L: " << grid[row][col] << "*" << grid[row][col-1] << "*" << grid[row][col-2] << "*" << grid[row][col-3] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
//UP-RIGHT
if ((row-1 >= 0) && (row-2 >= 0) && (row-3 >= 0) && (col+1 >= 0) && (col+2 >= 0) && (col+3 >= 0))
{
product = grid[row][col] * grid[row-1][col+1] * grid[row-2][col+2] * grid[row-3][col+3];
//std::cout << " U-R: " << grid[row][col] << "*" << grid[row-1][col+1] << "*" << grid[row-2][col+2] << "*" << grid[row-3][col+3] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
//DOWN-RIGHT
if ((row+1 >= 0) && (row+2 >= 0) && (row+3 >= 0) && (col+1 >= 0) && (col+2 >= 0) && (col+3 >= 0))
{
product = grid[row][col] * grid[row+1][col+1] * grid[row+2][col+2] * grid[row+3][col+3];
//std::cout << " D-R: " << grid[row][col] << "*" << grid[row+1][col+1] << "*" << grid[row+2][col+2] << "*" << grid[row+3][col+3] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
//DOWN-LEFT
if ((row+1 >= 0) && (row+2 >= 0) && (row+3 >= 0) && (col-1 >= 0) && (col-2 >= 0) && (col-3 >= 0))
{
product = grid[row][col] * grid[row+1][col-1] * grid[row+2][col-2] * grid[row+3][col-3];
//std::cout << " D-L: " << grid[row][col] << "*" << grid[row+1][col-1] << "*" << grid[row+2][col-2] << "*" << grid[row+3][col-3] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
//UP-LEFT
if ((row-1 >= 0) && (row-2 >= 0) && (row-3 >= 0) && (col-1 >= 0) && (col-2 >= 0) && (col-3 >= 0))
{
product = grid[row][col] * grid[row-1][col-1] * grid[row-2][col-2] * grid[row-3][col-3];
//std::cout << " U-L: " << grid[row][col] << "*" << grid[row-1][col-1] << "*" << grid[row-2][col-2] << "*" << grid[row-3][col-3] << "= \t" << product << std::endl; system("pause>nul");
if (product > biggestProduct)
biggestProduct = product;
}
}
}
std::cout << biggestProduct;
return 0;
}
Does anyone know what's wrong?
your problem are your range checks:
example:
// DOWN
if ((row+1 >= 0) && (row+2 >= 0) && (row+3 >= 0))
should be:
// DOWN
//if ((row+1 < 20 ) && (row+2 < 20 ) && (row+3 < 20 ))
//which still contains redundant comparisons (as pointed out by Blastfurnace),
//and thus can be can be simplified to :
if( row + 3 < 20 )
If you have random results on each run for a program, and you dont use concurrency, random number generators or something like that, most likely that randomness i caused by undefined behaviour like reading unallocated memory or reading using unintialised variables.
Looks like you're reading off the bottom and right edges:
if ((row+1 >= 0) && (row+2 >= 0) && (row+3 >= 0))
if ((col+1 >= 0) && (col+2 >= 0) && (col+3 >= 0))
and the same test with the diagonals.
You should be checking that the index doesn't reach 20.
visit this link for code
http://codingloverlavi.blogspot.in/2013/06/project-euler-solution-11.html
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
long find_max(int **);
int main()
{
FILE *f;
int **arr,i=0,j;
arr=(int **)malloc(sizeof(int*)*20);
for(i=0;i<20;i++)
arr[i]=(int *)malloc(sizeof(int)*20);
f=fopen("D:/b.txt","r");
if(f)
for(i=0;i<20;i++)
for(j=0;j<20;j++)
fscanf(f,"%d",&arr[i][j]);
else
printf("file operation not successful\n");
printf("Answer = %ld\n",find_max(arr));
system("pause");
}
long find_max(int **arr)
{
int i,j,k;
long product,max=0;
for(i=0;i<20;i++)
for(j=0;j<20;j++)
{
/*checking for horizontal sequence*/
product=1;
for(k=0;k<4;k++)
{
if(j+k<20)
{
product*=arr[i][j+k];
}
}
if(product>max)
max=product;
/*checking for vertical sequence*/
product=1;
for(k=0;k<4;k++)
{
if(i+k<20)
{
product*=arr[i+k][j];
}
}
if(product>max)
max=product;
product=1;
for(k=0;k<4;k++)
{
if( (i+k<20) && (j+k<20) )
{
product*=arr[i+k][j+k];
}
}
if(product>max)
max=product;
product=1;
for(k=0;k<4;k++)
{
if( (i+k<20) && (j-k>0) )
{
product*=arr[i+k][j-k];
}
}
if(product>max)
max=product;
}
return max;
}
I've been learning to program for quite a bit and it seems that one of the greatest competitions between programmers is how few lines one can do a procedure in. Noticing this trend, I'd like to learn to make my programs a bit tighter, cleaner, and preferring functionality without excess. Here's the code I used to solve ProjectEuler problem 11. It's quite large which kinda worries me when I see code a fourth of its size doing the same thing, hehe.
#include <iostream>
using namespace std;
int array[20][20] = {{8,2,22,97,38,15,0,40,0,75,4,5,7,78,52,12,50,77,91,8},
{49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48,4,56,62,0},
{81,49,31,73,55,79,14,29,93,71,40,67,53,88,30,3,49,13,36,65},
{52,70,95,23,4,60,11,42,69,24,68,56,1,32,56,71,37,2,36,91},
{22,31,16,71,51,67,63,89,41,92,36,54,22,40,40,28,66,33,13,80},
{24,47,32,60,99,3,45,2,44,75,33,53,78,36,84,20,35,17,12,50},
{32,98,81,28,64,23,67,10,26,38,40,67,59,54,70,66,18,38,64,70},
{67,26,20,68,2,62,12,20,95,63,94,39,63,8,40,91,66,49,94,21},
{24,55,58,5,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72},
{21,36,23,9,75,0,76,44,20,45,35,14,0,61,33,97,34,31,33,95},
{78,17,53,28,22,75,31,67,15,94,3,80,4,62,16,14,9,53,56,92},
{16,39,5,42,96,35,31,47,55,58,88,24,0,17,54,24,36,29,85,57},
{86,56,0,48,35,71,89,7,5,44,44,37,44,60,21,58,51,54,17,58},
{19,80,81,68,5,94,47,69,28,73,92,13,86,52,17,77,4,89,55,40},
{4,52,8,83,97,35,99,16,7,97,57,32,16,26,26,79,33,27,98,66},
{88,36,68,87,57,62,20,72,3,46,33,67,46,55,12,32,63,93,53,69},
{4,42,16,73,38,25,39,11,24,94,72,18,8,46,29,32,40,62,76,36},
{20,69,36,41,72,30,23,88,34,62,99,69,82,67,59,85,74,4,36,16},
{20,73,35,29,78,31,90,1,74,31,49,71,48,86,81,16,23,57,5,54},
{1,70,54,71,83,51,54,69,16,92,33,48,61,43,52,1,89,19,67,48},
};
int s = 0;
int right()
{
int a = 1;
int i = 0;
int n = 0;
int r = 0;
int c = 0;
for(n = 0;n <= 359;n++)
{
if(c <= 16)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[r][(c + i)] << " ";
a *= array[r][(c + i)];
};
//cout << a << " ";
i = 0; c++;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 0; r++;};
};
return s;
};
int left()
{
int a = 1;
int i = 0;
int n = 0;
int r = 0;
int c = 19;
for(n = 0;n <= 359;n++)
{
if(c >= 3)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[r][(c - i)] << " ";
a *= array[r][(c - i)];
};
//cout << a << " ";
i = 0; c--;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 19; r++;};
};
return s;
};
int down()
{
int n = 0;
int i = 0;
int r = 0;
int c = 0;
int a = 1;
for(n = 0;n <= 356;n++)
{
if(c <= 19)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[(r + i)][c] << " ";
a *= array[(r + i)][c];
};
//cout << a << " ";
i = 0; c++;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 0;
if(r <= 16){
r++;
}else{break;};
};
};
return s;
};
int up()
{
int n = 0;
int i = 0;
int r = 19;
int c = 0;
int a = 1;
for(n = 0;n <= 356;n++)
{
if(c <= 19)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[(r - i)][c] << " ";
a *= array[(r - i)][c];
};
//cout << a << " ";
i = 0; c++;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 0;
if(r >= 3){
r--;
}else{break;};
};
};
return s;
};
int diag_left_up()
{
int n = 0;
int i = 0;
int r = 19;
int c = 19;
int a = 1;
for(n = 0;n <= 304;n++)
{
if(c >= 3 && r >= 3)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[(r - i)][(c - i)] << " ";
a *= array[(r - i)][(c - i)];
};
//cout << a << " ";
i = 0; c--;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 19;
if(r >= 3){
r--;
}else{break;};
};
};
return s;
};
int diag_left_down()
{
int n = 0;
int i = 0;
int r = 0;
int c = 19;
int a = 1;
for(n = 0;n <= 304;n++)
{
if(c >= 3 && r <= 16)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[(r + i)][(c - i)] << " ";
a *= array[(r + i)][(c - i)];
};
//cout << a << " ";
i = 0; c--;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 19;
if(r <= 16){
r++;
}else{break;};
};
};
return s;
};
int diag_right_up()
{
int n = 0;
int i = 0;
int r = 19;
int c = 0;
int a = 1;
for(n = 0;n <= 304;n++)
{
if(c <= 16 && r >= 3)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[(r - i)][(c + i)] << " ";
a *= array[(r - i)][(c + i)];
};
//cout << a << " ";
i = 0; c++;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 0;
if(r >= 3){
r--;
}else{break;};
};
};
return s;
};
int diag_right_down()
{
int n = 0;
int i = 0;
int r = 0;
int c = 0;
int a = 1;
for(n = 0;n <= 304;n++)
{
if(c <= 16 && r <= 16)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[(r + i)][(c + i)] << " ";
a *= array[(r + i)][(c + i)];
};
//cout << a << " ";
i = 0; c++;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 0;
if(r <= 16){
r++;
}else{break;};
};
};
return s;
};
int main()
{
cout << "Result from right():" << '\t' << right();
cout << endl;
cout << "Result from left():" << '\t' << left();
cout << endl;
cout << "Result from down():" << '\t' << down();
cout << endl;
cout << "Result from up():" << '\t' << up();
cout << endl;
cout << "Result from diag_right_up(): " << '\t' << diag_right_up();
cout << endl;
cout << "Result from diag_right_down(): " << '\t' << diag_right_down();
cout << endl;
cout << "Result from diag_left_up(): " << '\t' << diag_left_up();
cout << endl;
cout << "Result from diag_left_down(): " << '\t' << diag_left_down();
cout << endl << endl << "Greatest result: " << s;
return 0;
}
The first thing I notice is that you've got a lot of functions that do basically the same thing (with some numbers different). I would investigate adding a couple of parameters to that function, so that you can describe the direction you're going. So for example, instead of calling right() you might call traverse(1, 0) and traverse(0, -1) instead of up().
Your traverse() function declaration might look like:
int traverse(int dx, int dy)
with the appropriate changes inside to adapt its behaviour for different values of dx and dy.
Well, for starters, you only need four of those directions: right/left, up/down, right-up/down-left and right-down/up-left. Multiplication is commutative, so it doesn't matter which direction you go from a given pair (if you find "a b c d" in one direction, you'll find "d c b a" in the opposite direction, and you get the same result when multiplying those numbers together).
Secondly, use more descriptive variable names. A variable name like s is meaningless; something like maximum is better, because that tells you what that variable is for. That doesn't mean you should never ever use a single-character variable name - e.g., using i as a for-loop counter is perfectly fine, and if you're dealing with coordinates, x and y can also be just fine, but when at all possible, you should use a descriptive name to make the code more self-documenting.
Thirdly, you can look into what Greg suggests and refactor your methods to take a direction instead. This would allow you to ditch all of the similar methods (and just call that one method 4 times with different parameters to cover all of the necessary directions).
And finally, you may want to be more consistent about your formatting - I know that can be hard to start doing, but it helps you in the long run. To understand what I mean here, take a good look at this snippet, taken from your down() method:
if(c <= 19)
{
for(i = 0;i <= 3;i++)
{
//cout << " " << array[(r + i)][c] << " ";
a *= array[(r + i)][c];
};
//cout << a << " ";
i = 0; c++;
if(a > s)
{
s = a;
a = 1;
};
//cout << s << " " << endl;
a = 1;
}else{c = 0;
if(r <= 16){
r++;
}else{break;};
};
Notice how you place a line break before the opening curly bracket of your ifs, but write }else{ on a single line. Additionally, inside the first else, you have another if-block where you don't place a line break before the curly bracket, and the closing bracket has the same indent level as the block content (r++;). This is quite inconsistent, and makes it harder to read.
static void largestProduct11() {
int[][] arr = {
{8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8},
{49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56,
62, 0},
{81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13,
36, 65},
{52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36,
91},
{22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33,
13, 80},
{24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17,
12, 50},
{32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38,
64, 70},
{67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94,
21},
{24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89,
63, 72},
{21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33,
95},
{78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56,
92},
{16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85,
57},
{86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17,
58},
{19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55,
40},
{4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98,
66},
{88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93,
53, 69},
{4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76,
36},
{20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4,
36, 16},
{20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5,
54},
{1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67,
48}
};
/*
* |A11 A12 A13 * * A1N|
* |A21 A22 A23 * * A2N|
* |A31 A32 A33 A3N|
* * *
* * *
* |An1 A2N A3N * * ANN|
*
* */
String line;
int[] temp = new int[4];
int compre = 1;
int result = 1;
for (int i = 0; i < arr.length - 3; i++) { // optimize:- the condition is true
// if the remaining index are at least four therefore the length should be reduced by
// three that means only the first 16 members can can satisfy the condition
for (int j = 0; j < arr[0].length - 3; j++) {
result = arr[i][j] * arr[i + 1][j + 1] * arr[i + 2][j + 2] * arr[i + 3][j + 3];
if (compre < result) {
compre = result;
}
}
}
//
System.out.println(compre + " Right sie test ");
for (int i = 0; i < arr.length - 3; i++) {
line = "{";
for (int j = arr[0].length - 1; j > 3; j--) {
result = arr[i][j] * arr[i + 1][j - 1] * arr[i + 2][j - 2] * arr[i + 3][j
- 3];
if (compre < result) {
compre = result;
}
}
}
System.out.println(compre + " final result"); // solution= 70600674
}