i cant think A blog belong to Mohammad Azwan bin Ali. Most of his writings are about his real life story, ideas, thoughts, moderate political views, computer, programming, tips & tricks, particularly in Linux…. and of course it includes some random unspecified crappy stuffs too! Don't forget to check Movies and Junkyard pages out!
note: most of entries is not suitable for faint hearted person or anybody with iq below 100.

c/c++ programming: number spirals generator

there's several ways we can generate a spiral number like this.

5x6 spiral

 1  2  3  4  5  6
18 19 20 21 22  7
17 28 29 30 23  8
16 27 26 25 24  9
15 14 13 12 11 10

today i would like to show two ways of doing it

first, we can use mapping technique. it's done by going through the number spiral direction and map it's coordinate in form of two dimensional arrays. this is pretty much easier to understand but take up a lot of resources and execution time.

here's the my mapping code (written in c++)

jump in to read more .. ;)

  1. #include <cstdlib>
  2. #include <ctime>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. int i=0,x,y,spiral[100][100];
  7. char direction = 'r';
  8. void change_direction() {
  9.      switch(direction) {
  10.      case 'r':direction='d';break;
  11.      case 'd':direction='l';break;
  12.      case 'l':direction='u';break;
  13.      case 'u':direction='r';break;
  14.      }
  15. }
  16. int check_cell(int a,int b) {
  17.  if (b >= y || b <0) { return 0; }  else if (a >= x) { return 0; }
  18.  else if (spiral[a][b] != 0) { return 0; }
  19.  else { return 1; }
  20. }
  21. void move_cell(int &amp;a,int &amp;b) {
  22.      int next_a = a, next_b = b;
  23.      if (i == x*y-1) { return; }
  24.      switch(direction) {
  25.      case 'r': next_b = b + 1;break;
  26.      case 'd': next_a = a + 1;break;
  27.      case 'l': next_b = b - 1;break;
  28.      case 'u': next_a = a - 1;break;
  29.      }
  30.      if (check_cell(next_a,next_b)) {
  31.          a = next_a;b = next_b;
  32.      }
  33.      else {
  34.           change_direction();
  35.           move_cell(a,b);
  36.           }
  37.     return;
  38. }
  39.  
  40. int main() {
  41. int j,a=0,b=0;
  42. srand((unsigned)time(0));
  43. while (!x||!y) { x = rand()%10; y = rand()%10; }
  44. printf("%dx%d spiral number\n",x,y);
  45. for (i = 0;i< x;i++) {
  46.          for (j = 0;j < y;j++) {
  47.              printf("%d\t",spiral[i][j]);
  48.          }
  49.          printf("\n");
  50.      }
  51. return 0;
  52. }

preview output

in this method, all we have to do is go through the number spiral and change direction when it reach certain limit or if next cell already being occupied. it's more like snake movement.

now, the second technique is by represent those number in matrix form. we going to create a function that going to give us a number for (i,j) position with current size of spiral (a*b) loop.
for example 5x6 spiral will be

→→→→→  j →→→→→

|  29 28 27 26 25 24
↓  12             23      11 10  9  8
i  13             22 -->  2         7  --> 1 0
↓  14             21      3  4   5  6      a=1 b=2
↓  15 16 17 18 19 20      a = 3 b = 4
    a = 5 b = 6

notice that when the number from left to right then top to bottom, the number reduce from
total-[a*b-i+j+1] // note we +1 because our point start from (0,0)
meanwhile for left-side, start with (1,1) top to bottom then left to right,the number sequence are in
total-[(a-1)*(b-1)-((a-i)+(b-j))+2;]
where total is dimension of a*b. we can use recursive to loop for outer layer of spiral to inner.
here's my code written in c. since the number is inverted, we need to minus it with total (a*b) when printing it.

  1. #include <stdio.h>
  2. #include <time.h>
  3. int s(int i, int j, int a,int b){
  4.  return (i == 0 || j == (b-1)) ? \
  5.  (a*b) - (1 + i + j) : (i == (a-1) || j == 0) ?\
  6.  (a-1)*(b-1)-((a-i)+(b-j))+2 :\
  7.  (a > 2 || b > 2) ? s(i-1, j-1, a-2,b-2) : 0;\
  8. }
  9. int main() {
  10. int x,y,a,b;
  11. // srand((unsigned)time(0)); //use this for random generation
  12. // while (!a||!b) { a = rand()%10; b = rand()%10; }
  13. a=5;b=6;
  14. for (x=0;x < a;x++){ for (y=0;y<b;y++)printf("%d\t",a*b-s(x,y,a,b)); printf("\n\n"); }
  15. return 0;
  16. }
  17.  

preview code output

you can print the spiral number from inner to outer by changing a*b-s(x,y,a,b) to s(x,y,a,b) in printf ;)
i know this might not be the most optimal solution but hope i can share something with you guys
thank you :)


No Comments Yet


There are no comments yet. You could be the first!

Leave a Comment

:D [angely] [argh] [blindfold] [color] [cry] [bye] [cutie] [dance] [flirt] [ghost] [thumb] >_< hmmm more »