5 Replies - 1055 Views - Last Post: 22 March 2019 - 06:48 PM Rate Topic: -----

#1 Doomblaze   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 24-December 18

Shorter code

Posted 22 March 2019 - 04:57 AM

So I've written a code that takes input of any N number and creates an NxN array, then takes the input for every individual slot in the array as a number value. Afterwards, it calculates the sum of numbers in the shape of a plus symbol ( + ) thus focusing on every number in the array and sums it up with all four neighbouring ones. And the only problem is when the number is at the edges or at the corners you have to only include the neighbouring numbers inside the array.
I have solved it and the code works fine, but it's too long and I'm curious to know if there's any more compact way of writing it. And by "it" i'm referring to the second loop.

PS: I'm printing instead of calculating sum to display the process and see if there's anything wrong

#include <stdio.h>

int main() {
	int a[100][100], i, j, n;
	scanf("%d", &n);
	printf("\n");
	
	for(i=0;i<n;i++) {
		for(j=0;j<n;j++){
			scanf("%d",&a[i][j]);
		}
	}
	printf("\n");
	for(i=0;i<n;i++) {
		for(j=0;j<n;j++){
			if(i==0 && j ==0) printf("%d %d %d", a[i][j],a[i+1][j],a[i][j+1]);
			else if (i==0 && j==n-1)printf("%d %d %d", a[i][j],a[i][j-1],a[i+1][j]);
			else if(j==0 && i ==n-1)printf("%d %d %d", a[i][j],a[i-1][j],a[i][j+1]);
			else if(i==0) printf("%d %d %d %d", a[i][j],a[i][j-1],a[i+1][j],a[i][j+1]);
			else if(j==0) printf("%d %d %d %d", a[i][j],a[i-1][j],a[i+1][j],a[i][j+1]);
			else if(i==n-1 && j ==n-1) printf("%d %d %d", a[i][j],a[i-1][j],a[i][j-1]);
			else if(i==n-1) printf("%d %d %d %d", a[i][j],a[i-1][j],a[i][j-1],a[i][j+1]);
			else if(j==n-1) printf("%d %d %d %d", a[i][j],a[i-1][j],a[i][j-1],a[i+1][j]);
			else printf("%d %d %d %d %d", a[i][j],a[i-1][j],a[i][j-1],a[i+1][j],a[i][j+1]);
			printf("\n");
		}
	}
}


Is This A Good Question/Topic? 0
  • +

Replies To: Shorter code

#2 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6818
  • View blog
  • Posts: 23,194
  • Joined: 05-May 12

Re: Shorter code

Posted 22 March 2019 - 06:23 AM

Yes replace lines 16 to 24 with with a call to a helper function that has the following prototype:
int AddNeighbors(int i, int j, int n, int a[100][100]);



Inside the function perform your range checking and adding. That will still include a branches but it will likely be less than what you currently have.

To go truly branchless, the common trick used by games is to have an array that is bigger than what you are using. The bigger array serves as a border. (e.g. 102x102 array to store the 100x100 data.) Top left data will go into (1,1) instead of your current (0,0). That way when you are looking at the row above (1,1), it will be (1,0) which will not access the array out of bounds.
Was This Post Helpful? 1
  • +
  • -

#3 BetaWar   User is offline

  • #include "soul.h"
  • member icon

Reputation: 1602
  • View blog
  • Posts: 8,435
  • Joined: 07-September 06

Re: Shorter code

Posted 22 March 2019 - 07:30 AM

"Shorter", I don't think so without starting to really crush some lines together.

However, you can make it tidier and more legible. By adding a few helper functions, I was able to get it to around 30-40 lines (depending on brace placement and the like) with only a single if statement in the entire application. The helper functions also make it far easier to narrow down issues and gain test confidence in your code.

Some ideas for useful helper functions:
A function that ensures the given index is within your range bounds, wrapping as necessary to get to a valid index.
A function to grab a valid value from the array given 2 indices.
A function to do your addition for the plus sign, so you don't have to worry about rewriting that code in multiple places.

Now. Just for fun. If I threw out all coding standards and legibility sides of things, I was able to get the application down to 23 lines. With a little fudging, I think I may be able to get it down to 21.
Was This Post Helpful? 1
  • +
  • -

#4 Salem_c   User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2322
  • View blog
  • Posts: 4,434
  • Joined: 30-May 10

Re: Shorter code

Posted 22 March 2019 - 09:19 AM

First of all, make it easy for people to test and validate the results. Nobody wants to type in lots of numbers to a program with an uncertain output.

Also, 100x100 is way too big. If it works with say 10x10, then it will work with 100x100.

Your version.
#include <stdio.h>
#define SIZE 10
int main() {
	int a[SIZE][SIZE], i, j, n = SIZE;
	for(i=0;i<n;i++) {
		for(j=0;j<n;j++){
			a[i][j] = 1;
		}
	}
	for(i=0;i<n;i++) {
		for(j=0;j<n;j++){
			int sum = 0;
			if(i==0 && j ==0) sum=(a[i][j]+a[i+1][j]+a[i][j+1]);
			else if (i==0 && j==n-1)sum=(a[i][j]+a[i][j-1]+a[i+1][j]);
			else if(j==0 && i ==n-1)sum=(a[i][j]+a[i-1][j]+a[i][j+1]);
			else if(i==0) sum=(a[i][j]+a[i][j-1]+a[i+1][j]+a[i][j+1]);
			else if(j==0) sum=(a[i][j]+a[i-1][j]+a[i+1][j]+a[i][j+1]);
			else if(i==n-1 && j ==n-1) sum=(a[i][j]+a[i-1][j]+a[i][j-1]);
			else if(i==n-1) sum=(a[i][j]+a[i-1][j]+a[i][j-1]+a[i][j+1]);
			else if(j==n-1) sum=(a[i][j]+a[i-1][j]+a[i][j-1]+a[i+1][j]);
			else sum=(a[i][j]+a[i-1][j]+a[i][j-1]+a[i+1][j]+a[i][j+1]);
			printf("%d ",sum);
		}
		printf("\n");
	}
}



My version.
#include <stdio.h>

#define SIZE    10

static int cellValue(int r, int c, int a[SIZE][SIZE] ) {
    return r >= 0 && r < SIZE &&
           c >= 0 && c < SIZE
           ? a[r][c]
           : 0;
}

static int sumNeighbours(int row, int col, int a[SIZE][SIZE]) {
    int sum = 0;
    for ( int c = col - 1 ; c <= col+1 ; c++ ) {
        sum += cellValue(row,c,a);
    }
    sum += cellValue(row-1,col,a);
    sum += cellValue(row+1,col,a);
    return sum;
}

int main() {
  int a[SIZE][SIZE], i, j, n = SIZE;
  for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
      a[i][j] = 1;
    }
  }
  for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
      printf("%d ",sumNeighbours(i,j,a));
    }
    printf("\n");
  }
}



It's easy to see the correctness, because the output looks like this.
3 4 4 4 4 4 4 4 4 3 
4 5 5 5 5 5 5 5 5 4 
4 5 5 5 5 5 5 5 5 4 
4 5 5 5 5 5 5 5 5 4 
4 5 5 5 5 5 5 5 5 4 
4 5 5 5 5 5 5 5 5 4 
4 5 5 5 5 5 5 5 5 4 
4 5 5 5 5 5 5 5 5 4 
4 5 5 5 5 5 5 5 5 4 
3 4 4 4 4 4 4 4 4 3 


3's in the corners, 4's on the edges and 5's in the interior.

The next point I'd like to make is that source code length has nothing to do with actual machine efficiency.

Super compressed code only qualifies you for entry to the IOCCC.
Not only does everyone else find it hard to read, making changes yourself is frustrating and error prone.

Everyone else should be going for clarity of purpose before worrying about source code length.

Counting the instructions generated by compilation (foo.c is yours, bar.c is mine).
$ gcc -S foo.c && egrep -c '^\s+[a-z]' foo.s
487
$ gcc -S bar.c && egrep -c '^\s+[a-z]' bar.s
131

$ gcc -S -O2 foo.c && egrep -c '^\s+[a-z]' foo.s
117
$ gcc -S -O2 bar.c && egrep -c '^\s+[a-z]' bar.s
82


Your if/else chain actually generates more code.
Further, there are NO actual function calls at run-time in my version with the -O2 flag. The compiler optimiser recognises their simplicity and simply inlines them away.

Finally, if you wanted sumNeighbours to sum eight neighbours instead of four, what are you going to do?
Was This Post Helpful? 2
  • +
  • -

#5 Doomblaze   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 24-December 18

Re: Shorter code

Posted 22 March 2019 - 03:23 PM

Thanks for the insightful responses, I always thought that shorter = faster, apparently not.

I just want to clarify that I'm still a rookie and haven't gone that far with functions yet, but since they run faster and better, I'm going to dedicate more time to learning them.

As for the input of every individual value I have deliberately made it like that, since that's what my university TA wants.
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6818
  • View blog
  • Posts: 23,194
  • Joined: 05-May 12

Re: Shorter code

Posted 22 March 2019 - 06:48 PM

View PostDoomblaze, on 22 March 2019 - 06:23 PM, said:

Thanks for the insightful responses, I always thought that shorter = faster, apparently not.

Look up "unrolled loops" sometime. It's a case where longer code is turns out to be faster.

View PostDoomblaze, on 22 March 2019 - 06:23 PM, said:

As for the input of every individual value I have deliberately made it like that, since that's what my university TA wants.

Yes, because likely your TA will run you program like:
$> yourprogram < test_case_1.txt
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1