COMP1511 18s1 (webcms)
COMP1511 18s1 (flask)
  1. The tutorial will start as usual with a code review.

    But instead the code you will review written by a previous COMP1511 student.

    Discuss the weakness of the style in the code below and how it might be improved:

        // Test if a point is inside a triangle.
    // Julian Saknussemm
    //
    // Given Three points of a triangle, and another arbitrary point this program determines if that point lies inside
    // the triangle.
    //
    // This is determined by satisfying the following rule:
    // A point P(x,y) is inside triangle A(x0,y0), B(x1,y1), C(x2,y2)
    // iff
    // P is on the same side of the line AB as C
    // P is on the same side of the line BC as A
    // and
    // P is on the same side of the line AC as B
    //
    // A special case exits for a vertical line (inf gradient) when testing the side of the line
    
    #include <stdio.h>
    
    int test2( double px, double py, double m, double b )
    {   if( py < m * px + b ) {
            return -1; // point is under line
               }else if ( py == m * px + b ){
               return 0;
               } else {
               return 1; // over
            }
    }
    
    int // two points lie on the same side of a line
    test1( double px, double py, double m,double b, double lx,double ly) {
            return (test2( px,py, m,b )==test2(lx,ly,m,b));
    }
    int tritest(double x0,double y0,double x1,double y1,double x2,double y2,double px, double py){
    
            int line1, line2, line3;
    // line eqns
    
    double m01 = (y1-y0)/(x1-x0);
    // b: y - y1 = m( x - x1 ), x = 0
    double b01 = m01 * -x1 + y1;
    double m02, m12, b02, b12;
    m02 = (y2-y0)/(x2-x0);
    m12 = (y2-y1)/(x2-x1);
    b02 = m02 * -x2 + y2;
    b12 = m12 * -x2 + y2;
    
    // vertical line checks
    if( x1 == x0 ) {
       line1 = ( (px <= x0) == (x2 <= x0) );
    } else {
       line1 = test1( px, py, m01, b01,x2,y2);
    }
    
    if( x1 == x2 ) {
            line2 = ( (px <= x2) == (x0 <= x2) );
    } else {
            line2 = test1(px,py, m12, b12,x0,y0);
    }
    
    if( x2 == x0 ) {
    line3 = ( (px <= x0 ) == (x1 <= x0) );} else {
            line3 = test1(px, py, m02,b02,x1,y1);
    }
    
       return line1 && line2 && line3;
    
    }
    int main(int argc, char* argv[]) {
    double x0,y0,x1,y1,x2,y2,px;
    double py;
    
    int scanfsReturnValueAggregatedOverAllScanfs = 0;
    
    // get input
            printf("Triangle Vertex A (x,y): "); scanfsReturnValueAggregatedOverAllScanfs += scanf("%lf,%lf", &x0,&y0);
            printf("Triangle Vertex  B (x,y): "); scanfsReturnValueAggregatedOverAllScanfs += scanf("%lf,%lf", &x1,&y1);
            printf("Triangle Vertex  C (x,y): "); scanfsReturnValueAggregatedOverAllScanfs += scanf("%lf,%lf", &x2,&y2);
       printf("Test Point (x,y): "); scanfsReturnValueAggregatedOverAllScanfs += scanf("%lf,%lf", &px,&py);
    
    // print error
       if( scanfsReturnValueAggregatedOverAllScanfs != 8 ) {
                    printf("You're stupid and didn't put in the right inputs!\n");
                    return 1;
    }
    
    // print answer
       printf("Point (%.2lf,%.2lf) is ", px,py);
       if(tritest(x0,y0,x1,y1,x2,y2,px,py)) printf("inside");
       else printf("outside");
       printf(" the Triangel\n");
    
    // return 0
    return 0;
    }
    
    
    1. Encode and decode a message with a Caesar cipher.
    2. The shift is the key for a Caesar Cipher - how many bits are in it?

    3. How would you crack a Caesar Cipher?

    4. Encode and decode a message with a Substitution cipher.
    5. The letter mapping is the key for a Substitution cipher - how many bits are in it?

    6. How would you crack a Substitution Cipher (assume the plain text is English)?

  • Write a program sum_digits.c which reads characters from its input and counts digits.

    When the end of input is reached it should print a count of how many digits occurred in its input and their sum.

    The only functions you can use are getchar and printf.

    For example:

    ./sum_digits
    1 2 3 o'clock
    4 o'clock rock
    Input contained 4 digits which summed to 10
    ./sum_digits
    12 twelve 24 twenty four
    thirty six 36
    Input contained 6 digits which summed to 18
    

    Revision questions

    The remaining tutorial questions are primarily intended for revision - either this week or later in session.

    Your tutor may still choose to cover some of the questions time permitting.

  • Write a program letter_triangle.c that read an positive integer n and outputs a triangle of letters of height n as below. For example:
    ./letter_triangle
    Enter height: 3
      A
     BCB
    DEFED
    ./letter_triangle
    Enter height: 7
          A
         BCB
        DEFED
       GHIJIHG
      KLMNONMLK
     PQRSTUTSRQP
    VWXYZABAZYXWV
    ./letter_triangle
    Enter height: 10
             A
            BCB
           DEFED
          GHIJIHG
         KLMNONMLK
        PQRSTUTSRQP
       VWXYZABAZYXWV
      CDEFGHIJIHGFEDC
     KLMNOPQRSRQPONMLK
    TUVWXYZABCBAZYXWVUT
    

  • Write a program input_statistics.c that for the characters provided on standard input:
  • For example:

    ./input_statistics
        "Beauty is truth, truth beauty," -- that is all
        Ye know on earth, and all ye need to know.
    Input contains 27 blanks, tabs and new lines
    Number of words: 19
    Length of shortest word: 2
    Length of longest word: 8
    ./input_statistics
    And here is another example with only one line of input!!!!!!!!!
    Input contains 11 blanks, tabs and new lines
    Number of words: 11
    Length of shortest word: 2
    Length of longest word: 14
    
  • How many ints can the array matrix below hold?
    #include <stdio.h>
    
    #define N_ROWS 12
    #define N_COLUMNS 15
    
    int main(void) {
        int matrix[N_ROWS][N_COLUMNS];
    

    Write nested loops that set every element of matrix. Each element should be set to the product of its two indices.

    Write nested loops that print the elements of matrix plus sums of each row and sums of each column.

    The output of your code should look like this:

    a.out
        0    0    0    0    0    0    0    0    0    0    0    0    0    0    0 |    0
        0    1    2    3    4    5    6    7    8    9   10   11   12   13   14 |  105
        0    2    4    6    8   10   12   14   16   18   20   22   24   26   28 |  210
        0    3    6    9   12   15   18   21   24   27   30   33   36   39   42 |  315
        0    4    8   12   16   20   24   28   32   36   40   44   48   52   56 |  420
        0    5   10   15   20   25   30   35   40   45   50   55   60   65   70 |  525
        0    6   12   18   24   30   36   42   48   54   60   66   72   78   84 |  630
        0    7   14   21   28   35   42   49   56   63   70   77   84   91   98 |  735
        0    8   16   24   32   40   48   56   64   72   80   88   96  104  112 |  840
        0    9   18   27   36   45   54   63   72   81   90   99  108  117  126 |  945
        0   10   20   30   40   50   60   70   80   90  100  110  120  130  140 | 1050
        0   11   22   33   44   55   66   77   88   99  110  121  132  143  154 | 1155
    ---------------------------------------------------------------------------
        0   66  132  198  264  330  396  462  528  594  660  726  792  858  924
    

  • A student has written this program to read ints until the end-of-input. It counts how many numbers it reads categorized by their last digit:
    #include <stdio.h>
    
    #define N 10
    
    int main(void) {
        int digit_count[N];
        int x, last_digit;
    
        while (scanf("%d", &x) == 1) {
            last_digit = x % N;
            digit_count[last_digit] = digit_count[last_digit] + 1;
        }
        last_digit = 0;
        while (last_digit < N) {
            printf("%d numbers with last digit %d read\n", digit_count[last_digit], last_digit);
            last_digit = last_digit + 1;
        }
    
        return 0;
    }
    
    
    It works on the students laptop:
    gcc -Wall -O last_digit.c
    a.out
    42 121 100 11
    <cntrl-d>
    1 numbers with last digit 0 read
    2 numbers with last digit 1 read
    1 numbers with last digit 2 read
    0 numbers with last digit 3 read
    0 numbers with last digit 4 read
    0 numbers with last digit 5 read
    0 numbers with last digit 6 read
    0 numbers with last digit 7 read
    0 numbers with last digit 8 read
    1 numbers with last digit 9 read
    
    

    But when run at uni, it fails:

    dcc last_digit.c
    a.out
    42 121 100 11
    <cntrl-d>
    778121076 numbers with last digit 0 read
    7632239 numbers with last digit 1 read
    -2032569224 numbers with last digit 2 read
    32727 numbers with last digit 3 read
    0 numbers with last digit 4 read
    0 numbers with last digit 5 read
    -2032409578 numbers with last digit 6 read
    32727 numbers with last digit 7 read
    -21600000 numbers with last digit 8 read
    32767 numbers with last digit 9 read
    
    

    Why doesn't the code work at uni?

    Why doesn't dcc detect an error?

    Fix the code (make sure you understand how it works - it's a common and useful programming pattern).

    1. What is the effect of each of the following statements? What are the initial values in the arrays?
      int nums1[10];
      

      int nums2[] = {0,1,2,3,4,5,6,7,8,9};
      

      int nums3[10] = {0,2,4,6,8,-2};
      

      int nums4[10] = {0};
      

      int nums5[2][10] = {{0,1,2,3,4,5,6,7,8,9},
                          {10,20,30,40,50,60,70,80,90,100}};
      

    2. What would the output of the following fragment of code be - given the array definitions above?
      
      printf("%d\n",nums2[3]); 

      printf("%d\n",nums3[5]);

      printf("%d\n",nums5[0][1]);

      printf("%d\n",nums5[1][0]);

      nums1[0] = nums2[1] + 10 ; printf("%d\n",nums1[0]);

      int i = 0; printf("%d\n",nums1[i]);

    3. What is wrong with the following piece of code - given the above array definitions?
      printf("%d\n",nums2[10]);   

      printf("%d\n",nums5[2][0]);

      printf("%d\n",nums5[1][10]);