Thread: Output multiple inputs in reverse order - C

  1. #1
    Registered User
    Join Date
    Nov 2019
    Posts
    135

    Output multiple inputs in reverse order - C

    Hey all!

    I'm struggling for a lot of time trying to solve some exercise:

    Write a program that reads in pairs of integers representing the scores of basketball games until it encounters EOF. Then, the program prints the scores it read and the difference between the scores in reverse order. At the end it prints the largest difference it encountered.
    Tips:

    • You may assume all the input is correct (which also means you can use scanf).
    • You may assume all memory allocations succeed.
    • Your implementation is expected to be efficient in memory, but there is no bound on the input size.
    • There is no bound on the number of input numbers
    • Do NOT use VLAs!
    • You might find the scanf, malloc, realloc functions useful.

    For example:
    Input Result
    117 101
    113 102
    82 104
    82 104 22
    113 102 11
    117 101 16
    largest difference = 22



    - So, my approach is recursion of course, but I don't succeed to yield correct outputs. I have been trying to bug the code but something is going wrong with scanf, making it difficult to move on...

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    
    int recurse(int* diff) {
        int score1 = 0;
        int score2 = 0;
        int largest;
        if (scanf("%i %i", &score1, &score1) != 2) {
            return 1;
        }
        else {
            int currDiff = score1 - score2;
            if (currDiff > *diff) {
                largest = currDiff;
            }
            else {
                largest = *diff;
            }
            
            if (recurse(&largest)) {
                printf("%i %i %i", score1, score2, currDiff);
            }
        }
        *diff = largest;
        return 1;
    }
    
    
    int main()
    {
        int diff = 0;
        recurse(&diff);    
        printf("largest difference = %i\n", diff);
    }
    Does someone figuring the problem out?

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    771
    You say "recursion, of course" but using recursion never occurred to me. The question hints that you would use malloc and realloc (which you must have covered in class).

    However, using recursion is interesting since it allows you to store the previous values on the stack until you read the last values and then to print them out in reverse order as the stack unwinds.

    But the assignment does say to use memory efficiently, and recursion will probably use at least twice as much memory as a reallocated array.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    int find_biggest_diff(int biggest) {
        int a, b;
        if (scanf("%d%d", &a, &b) != 2)
            return 0;
        biggest = find_biggest_diff(biggest);
        int dif = abs(a - b);
        printf("%d %d %d\n", a, b, dif);
        return dif > biggest ? dif : biggest;
    }
     
    int main() {
        printf("%d\n", find_biggest_diff(0));
    }
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  3. #3
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Quote Originally Posted by john.c View Post
    You say "recursion, of course" but using recursion never occurred to me. The question hints that you would use malloc and realloc (which you must have covered in class).

    However, using recursion is interesting since it allows you to store the previous values on the stack until you read the last values and then to print them out in reverse order as the stack unwinds.

    But the assignment does say to use memory efficiently, and recursion will probably use at least twice as much memory as a reallocated array.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    int find_biggest_diff(int biggest) {
        int a, b;
        if (scanf("%d%d", &a, &b) != 2)
            return 0;
        biggest = find_biggest_diff(biggest);
        int dif = abs(a - b);
        printf("%d %d %d\n", a, b, dif);
        return dif > biggest ? dif : biggest;
    }
     
    int main() {
        printf("%d\n", find_biggest_diff(0));
    }
    Thank you. Really appreciate that.
    What went wrong with my recursion actually?

    As for the allocation option - I thought it would be very ugly and not elegant code.

    My way - We can define a pointer to pointer char which reallocs every time we have a legal scanf input.
    At the end, we're iterating the pointer to pointer from the end to beginning, printing each char pointer element.

    But here is my inconvenient part - during these iterations - we'll have to split each string into integers (using strtol), getting the difference of its values.
    But it also seems to be very inefficient and ugly way of solving, isn't it?

    Thank you!

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    771
    As for what went wrong with your attempt:
    * You've written score1 twice in your scanf.
    * You need to take the absolute value of the difference.
    * The return value is meaningless (as is the if around the recursive call).


    Once these problems are fixed, it looks almost identical to mine except that you are using a pointer instead of the return value for the result.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    void recurse(int* diff) {
        int score1, score2;
        if (scanf("%d %d", &score1, &score2) != 2)
            return;
        recurse(diff);
        int currDiff = abs(score1 - score2);
        *diff = currDiff > *diff ? currDiff : *diff;
        printf("%d %d %d\n", score1, score2, currDiff);
    }
     
    int main() {
        int diff = 0;
        recurse(&diff);
        printf("%d\n", diff);
    }

    As for the use of realloc, it isn't that bad.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct {
        int a, b;
    } Score;
     
    int main() {
        int size = 0, allocated = 10;
        Score *scores = malloc(allocated * sizeof *scores);
     
        for (int a, b; scanf("%d%d", &a, &b) == 2; ) {
            if (size >= allocated) {
                allocated = allocated * 3 / 2;
                scores = realloc(scores, allocated * sizeof *scores);
            }
            scores[size++] = (Score){a, b};
        }
     
        int biggest = 0;
        for (int i = size; i-- > 0; ) {
            int dif = abs(scores[i].a - scores[i].b);
            if (dif > biggest)
                biggest = dif;
            printf("%d %d %d\n", scores[i].a, scores[i].b, dif);
        }
        printf("%d\n", biggest);
     
        free(scores);
     
        return 0;
    }
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  5. #5
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Quote Originally Posted by john.c View Post
    As for what went wrong with your attempt:
    * You've written score1 twice in your scanf.
    * You need to take the absolute value of the difference.
    * The return value is meaningless (as is the if around the recursive call).


    Once these problems are fixed, it looks almost identical to mine except that you are using a pointer instead of the return value for the result.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    void recurse(int* diff) {
        int score1, score2;
        if (scanf("%d %d", &score1, &score2) != 2)
            return;
        recurse(diff);
        int currDiff = abs(score1 - score2);
        *diff = currDiff > *diff ? currDiff : *diff;
        printf("%d %d %d\n", score1, score2, currDiff);
    }
     
    int main() {
        int diff = 0;
        recurse(&diff);
        printf("%d\n", diff);
    }

    As for the use of realloc, it isn't that bad.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct {
        int a, b;
    } Score;
     
    int main() {
        int size = 0, allocated = 10;
        Score *scores = malloc(allocated * sizeof *scores);
     
        for (int a, b; scanf("%d%d", &a, &b) == 2; ) {
            if (size >= allocated) {
                allocated = allocated * 3 / 2;
                scores = realloc(scores, allocated * sizeof *scores);
            }
            scores[size++] = (Score){a, b};
        }
     
        int biggest = 0;
        for (int i = size; i-- > 0; ) {
            int dif = abs(scores[i].a - scores[i].b);
            if (dif > biggest)
                biggest = dif;
            printf("%d %d %d\n", scores[i].a, scores[i].b, dif);
        }
        printf("%d\n", biggest);
     
        free(scores);
     
        return 0;
    }
    As for the recursion - for some reason, I wanted the recursion func to return some value indicating the call is terminated or just succeeded, but I see on your verse it's nonsense...

    As for the scores - This is a really elegant solution I didn't think of.
    Just one elementary question regarding your code, in line 10, you're using sizeof on scores* but it seems to be reasonable to get size of scores without * as you're allocating scores and not pointers to scores.

    Thank you so much!

  6. #6
    Registered User
    Join Date
    Dec 2017
    Posts
    771
    I used *scores with sizeof because I wanted the size of what scores points to, not the size of the pointer itself.
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  7. #7
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Quote Originally Posted by john.c View Post
    I used *scores with sizeof because I wanted the size of what scores points to, not the size of the pointer itself.
    Equivalent, got it.
    Thank you!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 05-30-2010, 10:22 PM
  2. Multiple sound inputs to one output
    By DonR2 in forum C++ Programming
    Replies: 8
    Last Post: 06-23-2004, 04:37 PM
  3. multiple inputs of multiple types
    By frontz in forum C Programming
    Replies: 8
    Last Post: 01-19-2004, 02:57 PM
  4. Multiple inputs with cin
    By DJPG5 in forum C++ Programming
    Replies: 2
    Last Post: 02-16-2003, 04:10 PM
  5. How to output tokens in reverse order using strtok
    By Ninz in forum C++ Programming
    Replies: 4
    Last Post: 02-01-2003, 09:00 PM

Tags for this Thread