Trying to do a language Conversion

Hello, I know there are much easier ways to do what I am attempting to do (which is convert C code to Go) by just adding a C library to the code, however per my Coursera practice, I am not allowed to do that.

I am attempting to convert the following C program:

#include <stdio.h>

main()
{
   int input;                               /* User defined integer       */
   int loc[14][14];                         /* Array holding all          */
                                            /*  input*input values.       */
   int row;                                 /* Determines row of matrix   */
   int col;                                 /* Determines col of matrix   */
   int value;                               /* Integer between 1 and      */
                                            /*  input*input               */
   int otherdiag;                           /* Total of one matrix diagonal*/

   printf("\nMagic Squares: This program produces an NxN matrix where\n");
   printf("N is some positive odd integer.  The matrix contains the \n");
   printf("values 1 to N*N.  The sum of each row, each column, and \n");
   printf("the two main diagonals are all equal.  Not only does this \n");
   printf("program produces the matrix, it also computes the totals for\n");
   printf("each row, column, and two main diagonals.\n");

   printf("\nBecause of display constraints, this program can work with\n");
   printf("values up to 13 only.\n\n");

    printf("Enter a positive, odd integer (-1 to exit program):\n");
   while (scanf("%d",&input) == 1)
   {

/*                                                                        */
/*    If input = -1, then exit program.                                   */
/*                                                                        */
      if (input == -1)
	 break;
/*                                                                        */
/*    Validity check for input: Must be a positive odd integer < 13.      */
/*                                                                        */
      if (input <= 0)
      {
         printf("Sorry, but the integer has to be positive.\n");
	 printf("\nEnter a positive, odd integer (-1 to exit program):\n");
  	 continue;
      }
      if (input > 13)
      {
	 printf("Sorry, but the integer has to be less than 15.\n");
	 printf("\nEnter a positive, odd integer (-1 to exit program):\n");
	 continue;
      }
      if (input%2 == 0)
      {
	 printf("Sorry, but the integer has to be odd.\n");
	 printf("\nEnter a positive, odd integer (-1 to exit program):\n");
	 continue;
      }
/*                                                                        */
/*    Initialize matrix, row, col, and otherdiag                          */
/*                                                                        */
      for (row = 0; row <= input; row++)    /* Initialize matrix with     */
         for (col = 0; col <= input; col++) /*  all zeroes.               */
            loc[row][col] = 0;              /* Values will reside within  */
                                            /*  rows 1 to input*input and */
                                            /*  columns 1 to input*input. */
                                            /* Row totals will reside in  */
                                            /*  loc[row][0], where row is */
                                            /*  the row number, while the */
                                            /*  column totals will reside */
                                            /*  in loc[0][col], where col */
                                            /*  is the column number.     */  
      row = 1;                              /* First value gets to sit on */
      col = input/2 + 1;                    /*  1st row, middle of matrix.*/
      otherdiag = 0;

 /*                                                                        */
/*    Loop for every value up to input*input, and position value in matrix*/
/*                                                                        */
      for (value = 1; value <= input*input; value++)
      {                                     /* Loop for all values.       */
         if (loc[row][col] > 0)             /* If some value already      */
         {                                  /*  present, then             */
            row += 2;                       /*  move down 1 row of prev.  */
            if (row > input)                /*  If exceeds side, then     */    
               row -= input;                /*   go to other side.        */

            col--;                          /*  move left 1 column.       */
            if (col < 1)                    /*  If exceeds side, then     */
               col = input;                 /*   go to other side.        */
         }

         loc[row][col] = value;             /* Assign value to location.  */

         loc[0][col] += value;              /* Add to its column total.   */
         loc[row][0] += value;              /* Add to its row total.      */
         if (row == col)                    /* Add to diagonal total if   */
            loc[0][0] += value;             /*  it falls on the diagonal. */

         if (row+col == input+1)            /* Add to other diagonal if   */
            otherdiag += value;             /*  it falls on the line.     */

/*                                                                        */
/*       Determine where new row and col are                              */
/*                                                                        */
         row--;
         if (row < 1)                       /* If row exceeds side then   */
            row = input;                    /*  goto other side.          */
         col++;
         if (col > input)                   /* If col exceeds side then   */
            col = 1;                        /*  goto other side.          */
      }                                     /* End of getting all values. */

/*                                                                        */
/*    Print out the matrix with its totals                                */
/*                                                                        */
      printf("\nThe number you selected was %d",input);
      printf(", and the matrix is:\n\n");
      for (row = 1; row <=input; row++)     /* Loop: print a row at a time*/
      {
         printf("     ");                   /* Create column for diag.total*/
         for (col = 1; col <=input; col++)
            printf("%5d",loc[row][col]);    /* Print values found in a row*/
         printf(" = %5d\n",loc[row][0]);    /* Print total of row.        */
      }

 /*                                                                        */
/*    Print out the totals for each column, starting with diagonal total. */
/*                                                                        */
      for (col = 0; col <=input; col++)     /* Print line separating the  */
         printf("-----");                   /*  value matrix and col totals*/
      printf("\n%5d",otherdiag);            /* Print out the diagonal total*/
      for (col = 1; col <=input; col++)
         printf("%5d",loc[0][col]);         /* Print out the column totals*/
      printf("   %5d\n",loc[0][0]);         /* Print out the other diagonal*/
                                            /*  total                     */
      printf("\nEnter a positive, odd integer (-1 to exit program):\n");

   }                                        /* End of while input>-1 loop */
   printf("\nBye bye!\n");
}

Converting it to Golang, I did the following:

package main

import (
	"fmt"
	"os"
)

var otherdiag int
var loc [][]int
var row, col int

func main() {
	var input int /* User defined integer       */

	for input != -1 {
		fmt.Printf("\nMagic Squares: This program produces an NxN matrix where\n")
		fmt.Printf("N is some positive odd integer.  The matrix contains the \n")
		fmt.Printf("values 1 to N*N.  The sum of each row, each column, and \n")
		fmt.Printf("the two main diagonals are all equal.  Not only does this \n")
		fmt.Printf("program produces the matrix, it also computes the totals for\n")
		fmt.Printf("each row, column, and two main diagonals.\n")

		fmt.Printf("\nBecause of display constraints, this program can work with\n")
		fmt.Printf("values up to 13 only.\n\n")

		fmt.Printf("Enter a positive, odd integer (-1 to exit program):\n")
		fmt.Scan(&input)

		/*                                                                        */
		/*    If input = -1, then exit program.                                   */
		/*                                                                        */
		if input == -1 {
			fmt.Println("Bye Bye!")
			os.Exit(0)
		} else if input <= 0 {

			fmt.Printf("Sorry, but the integer has to be positive.\n")
			fmt.Printf("\nEnter a positive, odd integer (-1 to exit program):\n")
			continue

		} else if input > 13 {

			fmt.Printf("Sorry, but the integer has to be less than 13.\n")
			fmt.Printf("\nEnter a positive, odd integer (-1 to exit program):\n")
			continue

		} else if input%2 == 0 {

			fmt.Printf("Sorry, but the integer has to be odd.\n")
			fmt.Printf("\nEnter a positive, odd integer (-1 to exit program):\n")
			continue

		}

		displayMatrix(input, loc)

	}

}

func createMatrix(matrixSize int) (loc [][]int) {
	// Use make to create two dimensional array
	// allocate memory for 1-dimensional array of size matrixSize
	// within for loop allocate memory for 2-dimension array
	loc = make([][]int, matrixSize)
	for i := range loc {
		loc[i] = make([]int, matrixSize)
	}

	return loc

}

func initMatrix(arraySize int, loc [][]int) {
	// Create nested for loop to initialize array
	loc = createMatrix(arraySize)
	for i := 0; i < arraySize; i++ {
		for j := 0; j < arraySize; j++ {
			loc[i][j] = 0
		}
	}
}

func calculateMatrix(userVal int, loc [][]int) {
	loc = createMatrix(userVal) //declare loc
	initMatrix(userVal, loc)    //initialize loc to a matrix of all zeroes
	// Convert C code calculation without changing the logic.
	row = 1                 /* First value gets to sit on */
	col = (userVal / 2) + 1 /*  1st row, middle of matrix.*/
	//otherdiag := 0

	/*                                                                        */
	/*    Loop for every value up to input*input, and position value in matrix*/
	/*                                                                        */
	for value := 1; value <= userVal*userVal; value++ {
		/* Loop for all values.       */
		if loc[row][col] > 0 { /* If some value already      */
			/*  present, then             */
			row += 2           /*  move down 1 row of prev.  */
			if row > userVal { /*  If exceeds side, then     */
				row -= userVal /*   go to other side.        */
			}
			col--        /*  move left 1 column.       */
			if col < 1 { /*  If exceeds side, then     */
				col = userVal
			} /*   go to other side.        */
		}

		loc[row][col] = value /* Assign value to location.  */

		/*                                                                        */
		/*       Add to totals                                                    */
		/*                                                                        */
		loc[0][col] += value /* Add to its column total.   */
		loc[row][0] += value /* Add to its row total.      */
		if row == col {      /* Add to diagonal total if   */
			loc[0][0] += value
		} /*  it falls on the diagonal. */

		if row+col == userVal+1 { /* Add to other diagonal if   */
			otherdiag += value /*  it falls on the line.     */
		}
		/*                                                                        */
		/*       Determine where new row and col are                              */
		/*                                                                        */
		row--
		if row < 1 { /* If row exceeds side then   */
			row = userVal /*  goto other side.          */
		}
		col++
		if col > userVal { /* If col exceeds side then   */
			col = 1 /*  goto other side.          */
		}
	} /* End of getting all values. */
}

func displayMatrix(userVal int, loc [][]int) {
	// Create nested for loop to read each array element and display
	// matrix with column totals and row totals
	loc = createMatrix(userVal)
	initMatrix(userVal, loc)
	calculateMatrix(userVal, loc)
	fmt.Printf("\nThe number you selected was %d", userVal)
	fmt.Printf(", and the matrix is:\n\n")
	for row := 1; row <= userVal; row++ { /* Loop: print a row at a time*/

		fmt.Printf("     ") /* Create column for diag.total*/
		for col := 1; col <= userVal; col++ {
			fmt.Printf("%5d", loc[row][col])
		} /* Print values found in a row*/
		fmt.Printf(" = %5d\n", loc[row][0]) /* Print total of row.        */
	}

	/*                                                                        */
	/*    Print out the totals for each column, starting with diagonal total. */
	/*                                                                        */
	for col := 0; col <= userVal; col++ { /* Print line separating the  */
		fmt.Printf("-----") /*  value matrix and col totals*/
		fmt.Printf("\n%5d", otherdiag)
	} /* Print out the diagonal total*/

	for col := 1; col <= userVal; col++ {
		fmt.Printf("%5d", loc[0][col])    /* Print out the column totals*/
		fmt.Printf("   %5d\n", loc[0][0]) /* Print out the other diagonal*/
	} /*  total                     */

}

I am getting the following runtime error upon compilation and I’m unsure why:

panic: runtime error: index out of range

goroutine 1 [running]:main.calculateMatrix(0x3, 0xc420082190, 0x3, 0x3)        /home/Documents/CourseraCourse/Assignment1/hw1.go:97 +0x263main.displayMatrix(0x3, 0xc4200820f0, 0x3, 0x3)
        /home/Documents/CourseraCourse/Assignment1/hw1.go:142 +0xb0
main.main()        /home/Documents/CourseraCourse/Assignment1/hw1.go:55 +0x278
exit status 2 

line 97 is the following line of code:if loc[row][col] > 0

line 142 calls the calculateMatrix() function

and line 55 is a call to the displayMatrix() function.

I feel as if I am doing something wrong in the calculate function. Any suggestions would be appreciated. Thanks!

In the C version, you declare the two-dimensional array loc[][] as a 14x14 array of ints. When I ran the program with an input of 3, the part that calculates the contents of the array accessed indices 1-3 of loc, not 0-2. It is using a 3x3 part of the 14x14 array, and accessing the 2nd through 4th rows and columns, not the first through third.

If it is declared as

int loc[3][3]

The program won’t work right.

In the Go version, you are allocating loc to be the same size as the number that is input. When the user enters 3, loc is allocated to be 3x3, and you may use row and col from 0 to 2. But the Go version also has row and col ranging from 1 to 3. On line 97, the program tries to access loc[3][3], which does not exist.

The result is the runtime error you got, and index out of range indicates that either row or col is too large.

You can use a fmt.Printf() statement to show the values of row and col during each iteration of the loop in the function calculateMatrix().

fmt.Printf("row: %d, col: %d\n",row,col)

Put that at line 97, just before

if loc[row][col] > 0 { /* If some value already      */

and you will see the behavior I described.

@jayts thanks for the info. I am working on it now.

I had to fix a couple of other things too, but I got it to work right. Let me know if you need more help.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.