diff options
author | Haidong Ji | 2022-04-15 15:51:30 -0500 |
---|---|---|
committer | Haidong Ji | 2022-04-15 15:51:30 -0500 |
commit | 442a49ad5a48d417345959b903ae6a6d32d55759 (patch) | |
tree | c7127bb497e5e439018b1915e0136eec2c9cb124 |
Excellent fundamentals and displine training, many tools and techniques
exercises: gdb, emacs, valgrind, git
292 files changed, 9887 insertions, 0 deletions
diff --git a/00_hello/README b/00_hello/README new file mode 100644 index 0000000..d94ecc4 --- /dev/null +++ b/00_hello/README @@ -0,0 +1,47 @@ +This assignment is a walkthrough for you to use +emacs, git, and the grading system. Your goal +is to create a file called "hello.txt" with one line +in it, that says + +hello + + + +(1) Use emacs to open/create a file called hello.txt + o Type C-x C-f (Control x, then Control f) [which opens + a new file] + o type hello.txt [then hit enter] + o Split the screen (C-x 2) and then change one half to + show this buffer (C-x b , should say default: README, if so hit + Enter. If not, type README, then hit Enter). Then use + "C-x o" to move back into the hello.txt buffer. +(2) Write one line, that says hello [then hit enter---we generally +end files with a newline] +(3) Save the file: C-x C-s +(4) Add/commit/push it to git + Suspend emacs with C-z then run the following commands + git add hello.txt + git commit -m "Did assignment 0" + git push + fg + The last of these will bring emacs back + +(5) Grade the assignment, get your feedback (and the next assignment) + Suspend emacs (C-z) + grade + git pull + fg + +(6) Now, open up your grade.txt file in emacs (C-x C-f grade.txt) + so you can read your feedback. Don't forget that you can + change back to this buffer with C-x b, and/or split the screen + with C-x 2 + When you are done, you can quit Emacs with C-x C-c. + +(7) Did something go wrong? If so, fix it, and add/push/commit/grade + again. If everything went right, you should have your gotten + your next assignment when you did git pull. After you quit emacs, + cd to that directory: + cd ../01_apple + and open the README there in emacs. Follow its instructions! +
\ No newline at end of file diff --git a/01_apple/README b/01_apple/README new file mode 100644 index 0000000..0b7c72f --- /dev/null +++ b/01_apple/README @@ -0,0 +1,10 @@ +Ok, now you've been walked through editing, saving, +and submitting an assignment. For this assignment, we're just going +to have you practice that on your own before +we move on to things involving writing code. + +- Create a file called "fruit.txt" +- Write one line, containing the text +apple +into that file +- Save the file and submit the assignment for grading diff --git a/01_apple/fruit.txt b/01_apple/fruit.txt new file mode 100644 index 0000000..4c479de --- /dev/null +++ b/01_apple/fruit.txt @@ -0,0 +1 @@ +apple diff --git a/01_apple/grade.txt b/01_apple/grade.txt new file mode 100644 index 0000000..0b58cac --- /dev/null +++ b/01_apple/grade.txt @@ -0,0 +1,4 @@ +Grading at Sat 27 Nov 2021 02:09:16 AM UTC +Your file matched the expected output + +Overall Grade: PASSED diff --git a/02_code1/README b/02_code1/README new file mode 100644 index 0000000..49bd449 --- /dev/null +++ b/02_code1/README @@ -0,0 +1,33 @@ +Open the code1.c file you have in this directory. +You will see two functions: max and main. + +In max, the algorithm is written as comments, but there is no code. +You should translate this algorithm to code. + +In main, there are three print statements which call max and print +its result. These would let you check if max is working right. + +There is also a comment asking you to write one more print statement +with a call to max. In that comment, it asks you to take the max +of two numbers (written as hex), and print them out. +Add a line of code to do this. + +When you have done this, run + +./test.sh + +This script will try to compile your code (which you will learn about in +the next chapter), as well as run it. If your code does not have legal +syntax, it will do its best to describe what is wrong. If there +is a problem, look at the code and try to see where you did not follow +the syntax rules from chapter 2. The line number and message it gives +may help you find the problem. If you cannot find the problem after a minute +or two, ask for help. + +If your code has legal syntax, test.sh will also run it, and show +you the output it produced, as well as the output we expected. + +If they are the same, you should commit, push, and grade. + +If they are not, you should see if you can fix the problem (and ask for help +if you cannot). diff --git a/02_code1/code1.c b/02_code1/code1.c new file mode 100644 index 0000000..192da3f --- /dev/null +++ b/02_code1/code1.c @@ -0,0 +1,20 @@ +int max (int num1, int num2) { + //check if num1 is greater than num2 + //if so, your answer is num1 + //otherwise, your answer is num2 + if (num1 > num2) { + return num1; + } + return num2; +} + +int main(void) { + printf("max(42, -69) is %d\n", max(42, -69)); + printf("max(33, 0) is %d\n", max(33, 0)); + printf("max(0x123456, 123456) is %d\n", max(0x123456, 123456)); + //compute the max of 0x451215AF and 0x913591AF and print it out as a decimal number + printf("max(0x451215AF, 0x913591AF) is %d\n", max(0x451215AF, 0x913591AF)); + + return 0; +} + diff --git a/02_code1/grade.txt b/02_code1/grade.txt new file mode 100644 index 0000000..172fbee --- /dev/null +++ b/02_code1/grade.txt @@ -0,0 +1,75 @@ +Grading at Sat 27 Nov 2021 02:14:17 AM UTC +Checking code1.c for legal syntax +Checking for int max (int num1, int num2) +Found on line 3, column 1 +Checking for int main(void) +Found on line 13, column 1 +Trying to run the code.. +Your file matched the expected output +Removing your main() and replacing it with our own to run more tests... +Testing max(-999, -2147483648) ... Correct +Testing max(-999, 123) ... Correct +Testing max(-999, 567) ... Correct +Testing max(-999, 891) ... Correct +Testing max(-999, 0) ... Correct +Testing max(-999, 1) ... Correct +Testing max(-999, -999) ... Correct +Testing max(-999, 123123123) ... Correct +Testing max(-87, -2147483648) ... Correct +Testing max(-87, 123) ... Correct +Testing max(-87, 567) ... Correct +Testing max(-87, 891) ... Correct +Testing max(-87, 0) ... Correct +Testing max(-87, 1) ... Correct +Testing max(-87, -999) ... Correct +Testing max(-87, 123123123) ... Correct +Testing max(0, -2147483648) ... Correct +Testing max(0, 123) ... Correct +Testing max(0, 567) ... Correct +Testing max(0, 891) ... Correct +Testing max(0, 0) ... Correct +Testing max(0, 1) ... Correct +Testing max(0, -999) ... Correct +Testing max(0, 123123123) ... Correct +Testing max(1, -2147483648) ... Correct +Testing max(1, 123) ... Correct +Testing max(1, 567) ... Correct +Testing max(1, 891) ... Correct +Testing max(1, 0) ... Correct +Testing max(1, 1) ... Correct +Testing max(1, -999) ... Correct +Testing max(1, 123123123) ... Correct +Testing max(240, -2147483648) ... Correct +Testing max(240, 123) ... Correct +Testing max(240, 567) ... Correct +Testing max(240, 891) ... Correct +Testing max(240, 0) ... Correct +Testing max(240, 1) ... Correct +Testing max(240, -999) ... Correct +Testing max(240, 123123123) ... Correct +Testing max(345, -2147483648) ... Correct +Testing max(345, 123) ... Correct +Testing max(345, 567) ... Correct +Testing max(345, 891) ... Correct +Testing max(345, 0) ... Correct +Testing max(345, 1) ... Correct +Testing max(345, -999) ... Correct +Testing max(345, 123123123) ... Correct +Testing max(999999, -2147483648) ... Correct +Testing max(999999, 123) ... Correct +Testing max(999999, 567) ... Correct +Testing max(999999, 891) ... Correct +Testing max(999999, 0) ... Correct +Testing max(999999, 1) ... Correct +Testing max(999999, -999) ... Correct +Testing max(999999, 123123123) ... Correct +Testing max(2147483647, -2147483648) ... Correct +Testing max(2147483647, 123) ... Correct +Testing max(2147483647, 567) ... Correct +Testing max(2147483647, 891) ... Correct +Testing max(2147483647, 0) ... Correct +Testing max(2147483647, 1) ... Correct +Testing max(2147483647, -999) ... Correct +Testing max(2147483647, 123123123) ... Correct + +Overall Grade: A diff --git a/02_code1/test.sh b/02_code1/test.sh new file mode 100755 index 0000000..eb21e2b --- /dev/null +++ b/02_code1/test.sh @@ -0,0 +1,34 @@ +#!/bin/bash +cat > temp.c <<EOF +#include <stdio.h> +#include <stdlib.h> +EOF +cat code1.c >> temp.c +gcc -Wall -Werror -pedantic -std=gnu99 temp.c -o code1 2>errors.txt +if [ "$?" = "0" ] + then + echo "Your code appears to have legal syntax!" + echo "Here is what I get when I run it..." + echo "-----------------" + ./code1 + echo "-----------------" + echo "Here is what I would expect the answers to be:" + echo "----------------" + cat <<EOF +max(42,-69) is 42 +max(33,0) is 33 +max(0x123456,123456) is 1193046 +max(0x451215AF, 0x913591AF) is 1158813103 +EOF + echo "---------------" + else + echo "Oh no, the syntax of your code is not correct!" + mesg=`grep error errors.txt | head -1` + ln=`echo "$mesg" | cut -f2 -d":"` + let ln=${ln}-2 + echo "I discovered the problem on line $ln " + echo "(though the problem may be earlier and I just got confused)" + echo "Here is my best attempt to describe what is wrong:" + echo "$mesg" | cut -f5 -d":" + fi +rm -f temp.c errors.txt code1 diff --git a/03_code2/README b/03_code2/README new file mode 100644 index 0000000..704aefc --- /dev/null +++ b/03_code2/README @@ -0,0 +1,34 @@ +Open the code2.c file you have in this directory. +You will see two functions: printTriangle and main. + +As with the previous problem, the printTriangle function +has an algorithm written as comments, but there is no code. +You should translate this algorithm to code. + +In main, there are three print statements which print out a triangle +with height 4, and the total number of stars in that triangle (returned +by the printTriangle function). + +There is also a comment asking you to write a few more statements +to do the same thing for a triangle of height 7. +Add the code to do this. + +When you have done this, run + +./test.sh + +As before, this script will try to compile your code (which you will learn about +ina n upcoming lesson), as well as run it. If your code does not have legal +syntax, it will do its best to describe what is wrong. If there +is a problem, look at the code and try to see where you did not follow +the syntax rules from Course 1 The line number and message it gives +may help you find the problem. If you cannot find the problem after a minute +or two, ask for help. + +If your code has legal syntax, test.sh will also run it, and show +you the output it produced, as well as the output we expected. + +If they are the same, you should commit, push, and grade. + +If they are not, you should see if you can fix the problem (and ask for help +if you cannot). diff --git a/03_code2/code2.c b/03_code2/code2.c new file mode 100644 index 0000000..25af8a0 --- /dev/null +++ b/03_code2/code2.c @@ -0,0 +1,51 @@ + +int printTriangle(int size) { + //start with starCount being 0 + int starCount = 0; + + //count from 0 (inclusive) to size (exclusive), for each number i that you count + for (int i = 0; i < size; i++) { + + //count from 0 (inclusive) to i (inclusive), for each number j that you count + for (int j = 0; j <= i; j++) { + + //print a "*" + printf("*"); + + //increment starCount + starCount++; + } + + //when you finish counting on j, + + //print a newline ("\n") + printf("\n"); + } + + //when you finish counting on i, + + //your answer is starCount + return starCount; + +} + + +int main(void) { + int numStars; + printf("Here is a triangle with height 4\n"); + numStars = printTriangle(4); + printf("That triangle had %d total stars\n", numStars); + //now print "Here is a triangle with height 7\n" + printf("Here is a triangle with height 7\n"); + + //then call printTriangle, passing in 7, and assign the result to numStars + numStars = printTriangle(7); + + //finally, print "That triangle had %d total stars\n", such that the %d + //prints the value of numStars + printf("That triangle had %d total stars\n", numStars); + + + return 0; +} + diff --git a/03_code2/grade.txt b/03_code2/grade.txt new file mode 100644 index 0000000..0138468 --- /dev/null +++ b/03_code2/grade.txt @@ -0,0 +1,23 @@ +Grading at Sat 27 Nov 2021 02:21:26 AM UTC +Checking code2.c for legal syntax +Checking for int printTriangle (int size) +Found on line 4, column 1 +Checking for int main(void) +Found on line 35, column 1 +Trying to run the code.. +Your file matched the expected output +Removing your main() and replacing it with our own to run more tests... +Testing printTriangle(0) ... Correct +Testing printTriangle(1) ... Correct +Testing printTriangle(2) ... Correct +Testing printTriangle(3) ... Correct +Testing printTriangle(4) ... Correct +Testing printTriangle(7) ... Correct +Testing printTriangle(9) ... Correct +Testing printTriangle(12) ... Correct +Testing printTriangle(142) ... Correct +Testing printTriangle(191) ... Correct +Testing printTriangle(2037) ... Correct +Testing printTriangle(2479) ... Correct + +Overall Grade: A diff --git a/03_code2/test.sh b/03_code2/test.sh new file mode 100755 index 0000000..649b8a6 --- /dev/null +++ b/03_code2/test.sh @@ -0,0 +1,46 @@ +#!/bin/bash +cat > temp.c <<EOF +#include <stdio.h> +#include <stdlib.h> +EOF +cat code2.c >> temp.c +gcc -Wall -Werror -pedantic -std=gnu99 temp.c -o code2 2>errors.txt +if [ "$?" = "0" ] + then + echo "Your code appears to have legal syntax!" + echo "Here is what I get when I run it..." + echo "-----------------" + ./code2 + echo "-----------------" + echo "Here is what I would expect the answers to be:" + echo "----------------" + cat <<EOF +Here is a triangle with height 4 +* +** +*** +**** +That triangle had 10 total stars +Here is a triangle with height 7 +* +** +*** +**** +***** +****** +******* +That triangle had 28 total stars +EOF + echo "---------------" + else + echo "Oh no, the syntax of your code is not correct!" + mesg=`grep error errors.txt | head -1` + ln=`echo "$mesg" | cut -f2 -d":"` + let ln=${ln}-2 + echo "I discovered the problem on line $ln " + echo "(though the problem may be earlier and I just got confused)" + echo "Here is my best attempt to describe what is wrong:" + echo "$mesg" | cut -f5 -d":" + fi +rm -f errors.txt temp.c code2 + diff --git a/04_compile/README b/04_compile/README new file mode 100644 index 0000000..dd090e6 --- /dev/null +++ b/04_compile/README @@ -0,0 +1,16 @@ +For this assignment, you will be practicing writing, compiling, and +running code. You should write a C file, called hello.c, with a main +function that uses the printf function to print the message + +Hello World + +[be sure to include a newline!] + +Your program should return EXIT_SUCCESS to indicate that it was successful +(the return value of main indicates success [0] or failure [anything else]). + +Don't forget to include stdio.h (for printf) and stdlib.h (for +EXIT_SUCCESS). + +When you are done, compile your code and run it. +The submit it for grading. diff --git a/04_compile/grade.txt b/04_compile/grade.txt new file mode 100644 index 0000000..ebec7bb --- /dev/null +++ b/04_compile/grade.txt @@ -0,0 +1,6 @@ +Grading at Sat 27 Nov 2021 02:23:56 AM UTC +Compiling your code +Checking if your program prints "Hello World" +Your file matched the expected output + +Overall Grade: PASSED diff --git a/04_compile/hello.c b/04_compile/hello.c new file mode 100644 index 0000000..30c032e --- /dev/null +++ b/04_compile/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> +#include <stdlib.h> + +int main() { + printf("Hello World\n"); + return EXIT_SUCCESS; +} diff --git a/05_squares/README b/05_squares/README new file mode 100644 index 0000000..b239759 --- /dev/null +++ b/05_squares/README @@ -0,0 +1,48 @@ + 1. Open the file "squares.c" and look at the squares function. + You will find that I have already done steps 1--4 + for an algorithm which draws two (possibly overlapping) + squares (one of #s and one of *s). + + 2. Read the generalized steps that I have written as comments + in this file. Note that whenever I indicate a range + (count from x to y, or between x and y), the range is + inclusive of the lower bound, and exclusive of the upper bound. + All counting is "count up by one." Determine if there are + any parts of these steps that you will want to abstract + out into a separate function. + + 3. Implement this algorithm by translating my steps into code. + You may abstract any pieces you want out into separate functions. + We've provided two helpers with specification we think may be helpful. + + 4. We have provided squares_test.o, which has a main function + that takes four command line arguments (size1, x_offset, y_offset, size2), + and calls your squares function with those arguments. + You can compile your code and link it with this object file + to make a program: + gcc -o squares -Wall -Werror -std=gnu99 --pedantic squares.c squares_test.o + Then you can run it like this: + ./square 4 1 2 3 + which would call your squares function with + size1=4 + x_offset=1 + y_offset=2 + size2=3 + + which should produce output that looks like this: +#### +# # +#*** +#*#* + *** +We have also provided 3 files which show the correct output for three inputs +(./squares 3 5 8 2,./squares 5 2 4 6,./squares 9 2 3 4) in the files +whose names starts with ans_ (and then has the parameter values in its name, +separated by _s). + +Use "diff" like you just learned to compare your program's output +to the correct output. + + 5. Submit your modified squares.c file (git commit/git push/grade). + + diff --git a/05_squares/ans_3_5_8_2.txt b/05_squares/ans_3_5_8_2.txt new file mode 100644 index 0000000..82f65f6 --- /dev/null +++ b/05_squares/ans_3_5_8_2.txt @@ -0,0 +1,10 @@ +### +# # +### + + + + + + ** + ** diff --git a/05_squares/ans_5_2_4_6.txt b/05_squares/ans_5_2_4_6.txt new file mode 100644 index 0000000..8585a26 --- /dev/null +++ b/05_squares/ans_5_2_4_6.txt @@ -0,0 +1,10 @@ +##### +# # +# # +# # +##****** + * * + * * + * * + * * + ****** diff --git a/05_squares/ans_9_2_3_4.txt b/05_squares/ans_9_2_3_4.txt new file mode 100644 index 0000000..26cc452 --- /dev/null +++ b/05_squares/ans_9_2_3_4.txt @@ -0,0 +1,9 @@ +######### +# # +# # +# **** # +# * * # +# * * # +# **** # +# # +######### diff --git a/05_squares/grade.txt b/05_squares/grade.txt new file mode 100644 index 0000000..18c9364 --- /dev/null +++ b/05_squares/grade.txt @@ -0,0 +1,437 @@ +Grading at Sun 28 Nov 2021 08:44:52 PM UTC +Trying to compile your code and link with squares_test.o +Testing ./squares 1 0 0 1 +PASSED + - Correct +Testing ./squares 1 0 0 5 +PASSED + - Correct +Testing ./squares 1 0 0 9 +PASSED + - Correct +Testing ./squares 1 0 1 1 +PASSED + - Correct +Testing ./squares 1 0 1 5 +PASSED + - Correct +Testing ./squares 1 0 1 9 +PASSED + - Correct +Testing ./squares 1 0 3 1 +PASSED + - Correct +Testing ./squares 1 0 3 5 +PASSED + - Correct +Testing ./squares 1 0 3 9 +PASSED + - Correct +Testing ./squares 1 0 8 1 +PASSED + - Correct +Testing ./squares 1 0 8 5 +PASSED + - Correct +Testing ./squares 1 0 8 9 +PASSED + - Correct +Testing ./squares 1 4 0 1 +PASSED + - Correct +Testing ./squares 1 4 0 5 +PASSED + - Correct +Testing ./squares 1 4 0 9 +PASSED + - Correct +Testing ./squares 1 4 1 1 +PASSED + - Correct +Testing ./squares 1 4 1 5 +PASSED + - Correct +Testing ./squares 1 4 1 9 +PASSED + - Correct +Testing ./squares 1 4 3 1 +PASSED + - Correct +Testing ./squares 1 4 3 5 +PASSED + - Correct +Testing ./squares 1 4 3 9 +PASSED + - Correct +Testing ./squares 1 4 8 1 +PASSED + - Correct +Testing ./squares 1 4 8 5 +PASSED + - Correct +Testing ./squares 1 4 8 9 +PASSED + - Correct +Testing ./squares 1 7 0 1 +PASSED + - Correct +Testing ./squares 1 7 0 5 +PASSED + - Correct +Testing ./squares 1 7 0 9 +PASSED + - Correct +Testing ./squares 1 7 1 1 +PASSED + - Correct +Testing ./squares 1 7 1 5 +PASSED + - Correct +Testing ./squares 1 7 1 9 +PASSED + - Correct +Testing ./squares 1 7 3 1 +PASSED + - Correct +Testing ./squares 1 7 3 5 +PASSED + - Correct +Testing ./squares 1 7 3 9 +PASSED + - Correct +Testing ./squares 1 7 8 1 +PASSED + - Correct +Testing ./squares 1 7 8 5 +PASSED + - Correct +Testing ./squares 1 7 8 9 +PASSED + - Correct +Testing ./squares 4 0 0 1 +PASSED + - Correct +Testing ./squares 4 0 0 5 +PASSED + - Correct +Testing ./squares 4 0 0 9 +PASSED + - Correct +Testing ./squares 4 0 1 1 +PASSED + - Correct +Testing ./squares 4 0 1 5 +PASSED + - Correct +Testing ./squares 4 0 1 9 +PASSED + - Correct +Testing ./squares 4 0 3 1 +PASSED + - Correct +Testing ./squares 4 0 3 5 +PASSED + - Correct +Testing ./squares 4 0 3 9 +PASSED + - Correct +Testing ./squares 4 0 8 1 +PASSED + - Correct +Testing ./squares 4 0 8 5 +PASSED + - Correct +Testing ./squares 4 0 8 9 +PASSED + - Correct +Testing ./squares 4 4 0 1 +PASSED + - Correct +Testing ./squares 4 4 0 5 +PASSED + - Correct +Testing ./squares 4 4 0 9 +PASSED + - Correct +Testing ./squares 4 4 1 1 +PASSED + - Correct +Testing ./squares 4 4 1 5 +PASSED + - Correct +Testing ./squares 4 4 1 9 +PASSED + - Correct +Testing ./squares 4 4 3 1 +PASSED + - Correct +Testing ./squares 4 4 3 5 +PASSED + - Correct +Testing ./squares 4 4 3 9 +PASSED + - Correct +Testing ./squares 4 4 8 1 +PASSED + - Correct +Testing ./squares 4 4 8 5 +PASSED + - Correct +Testing ./squares 4 4 8 9 +PASSED + - Correct +Testing ./squares 4 7 0 1 +PASSED + - Correct +Testing ./squares 4 7 0 5 +PASSED + - Correct +Testing ./squares 4 7 0 9 +PASSED + - Correct +Testing ./squares 4 7 1 1 +PASSED + - Correct +Testing ./squares 4 7 1 5 +PASSED + - Correct +Testing ./squares 4 7 1 9 +PASSED + - Correct +Testing ./squares 4 7 3 1 +PASSED + - Correct +Testing ./squares 4 7 3 5 +PASSED + - Correct +Testing ./squares 4 7 3 9 +PASSED + - Correct +Testing ./squares 4 7 8 1 +PASSED + - Correct +Testing ./squares 4 7 8 5 +PASSED + - Correct +Testing ./squares 4 7 8 9 +PASSED + - Correct +Testing ./squares 8 0 0 1 +PASSED + - Correct +Testing ./squares 8 0 0 5 +PASSED + - Correct +Testing ./squares 8 0 0 9 +PASSED + - Correct +Testing ./squares 8 0 1 1 +PASSED + - Correct +Testing ./squares 8 0 1 5 +PASSED + - Correct +Testing ./squares 8 0 1 9 +PASSED + - Correct +Testing ./squares 8 0 3 1 +PASSED + - Correct +Testing ./squares 8 0 3 5 +PASSED + - Correct +Testing ./squares 8 0 3 9 +PASSED + - Correct +Testing ./squares 8 0 8 1 +PASSED + - Correct +Testing ./squares 8 0 8 5 +PASSED + - Correct +Testing ./squares 8 0 8 9 +PASSED + - Correct +Testing ./squares 8 4 0 1 +PASSED + - Correct +Testing ./squares 8 4 0 5 +PASSED + - Correct +Testing ./squares 8 4 0 9 +PASSED + - Correct +Testing ./squares 8 4 1 1 +PASSED + - Correct +Testing ./squares 8 4 1 5 +PASSED + - Correct +Testing ./squares 8 4 1 9 +PASSED + - Correct +Testing ./squares 8 4 3 1 +PASSED + - Correct +Testing ./squares 8 4 3 5 +PASSED + - Correct +Testing ./squares 8 4 3 9 +PASSED + - Correct +Testing ./squares 8 4 8 1 +PASSED + - Correct +Testing ./squares 8 4 8 5 +PASSED + - Correct +Testing ./squares 8 4 8 9 +PASSED + - Correct +Testing ./squares 8 7 0 1 +PASSED + - Correct +Testing ./squares 8 7 0 5 +PASSED + - Correct +Testing ./squares 8 7 0 9 +PASSED + - Correct +Testing ./squares 8 7 1 1 +PASSED + - Correct +Testing ./squares 8 7 1 5 +PASSED + - Correct +Testing ./squares 8 7 1 9 +PASSED + - Correct +Testing ./squares 8 7 3 1 +PASSED + - Correct +Testing ./squares 8 7 3 5 +PASSED + - Correct +Testing ./squares 8 7 3 9 +PASSED + - Correct +Testing ./squares 8 7 8 1 +PASSED + - Correct +Testing ./squares 8 7 8 5 +PASSED + - Correct +Testing ./squares 8 7 8 9 +PASSED + - Correct +Testing ./squares 11 0 0 1 +PASSED + - Correct +Testing ./squares 11 0 0 5 +PASSED + - Correct +Testing ./squares 11 0 0 9 +PASSED + - Correct +Testing ./squares 11 0 1 1 +PASSED + - Correct +Testing ./squares 11 0 1 5 +PASSED + - Correct +Testing ./squares 11 0 1 9 +PASSED + - Correct +Testing ./squares 11 0 3 1 +PASSED + - Correct +Testing ./squares 11 0 3 5 +PASSED + - Correct +Testing ./squares 11 0 3 9 +PASSED + - Correct +Testing ./squares 11 0 8 1 +PASSED + - Correct +Testing ./squares 11 0 8 5 +PASSED + - Correct +Testing ./squares 11 0 8 9 +PASSED + - Correct +Testing ./squares 11 4 0 1 +PASSED + - Correct +Testing ./squares 11 4 0 5 +PASSED + - Correct +Testing ./squares 11 4 0 9 +PASSED + - Correct +Testing ./squares 11 4 1 1 +PASSED + - Correct +Testing ./squares 11 4 1 5 +PASSED + - Correct +Testing ./squares 11 4 1 9 +PASSED + - Correct +Testing ./squares 11 4 3 1 +PASSED + - Correct +Testing ./squares 11 4 3 5 +PASSED + - Correct +Testing ./squares 11 4 3 9 +PASSED + - Correct +Testing ./squares 11 4 8 1 +PASSED + - Correct +Testing ./squares 11 4 8 5 +PASSED + - Correct +Testing ./squares 11 4 8 9 +PASSED + - Correct +Testing ./squares 11 7 0 1 +PASSED + - Correct +Testing ./squares 11 7 0 5 +PASSED + - Correct +Testing ./squares 11 7 0 9 +PASSED + - Correct +Testing ./squares 11 7 1 1 +PASSED + - Correct +Testing ./squares 11 7 1 5 +PASSED + - Correct +Testing ./squares 11 7 1 9 +PASSED + - Correct +Testing ./squares 11 7 3 1 +PASSED + - Correct +Testing ./squares 11 7 3 5 +PASSED + - Correct +Testing ./squares 11 7 3 9 +PASSED + - Correct +Testing ./squares 11 7 8 1 +PASSED + - Correct +Testing ./squares 11 7 8 5 +PASSED + - Correct +Testing ./squares 11 7 8 9 +PASSED + - Correct +You got all cases right + +Overall Grade: PASSED diff --git a/05_squares/squares.c b/05_squares/squares.c new file mode 100644 index 0000000..9c3eff3 --- /dev/null +++ b/05_squares/squares.c @@ -0,0 +1,82 @@ +#include <stdio.h> +#include <stdlib.h> + + +int max(int num1, int num2){ + if (num1 > num2) { + return num1; + } + return num2; +} +/* + * Determines if coord is in range between + * offset (INCLUSIVE) and offset + size (EXCLUSIVE) + */ +int isInRange(int coord, int offset, int size) { + // if coord is in range, return 1 + if (coord >= offset && coord < offset + size) { + return 1; + } + // else, return 0 + return 0; +} + +/* + * Determines if coord is at border of offset or + * offset + size + */ +int isAtBorder(int coord, int offset, int size) { + // if coord is equal to offest or offset + size + if (coord == offset || coord == offset + size) { + return 1; + } + // return 1, else return 0 + return 0; +} + +void squares(int size1, int x_offset, int y_offset, int size2) { + //compute the max of size1 and (x_offset + size2). Call this w + int w = max(size1, x_offset + size2); + + //compute the max of size1 and (y_offset + size2). Call this h + int h = max(size1, y_offset + size2); + + //count from 0 to h. Call the number you count with y + for (int y = 0; y < h; y++) { + + //count from 0 to w. Call the number you count with x + for (int x = 0; x < w; x++) { + + //check if EITHER + // ((x is between x_offset and x_offset +size2) AND + // y is equal to either y_offset OR y_offset + size2 - 1 ) + // OR + // ((y is between y_offset and y_offset + size2) AND + // x is equal to either x_offset OR x_offset + size2 -1) + // if so, print a * + if (((isInRange(x, x_offset, size2) == 1) && (isAtBorder(y, y_offset, size2 -1) == 1)) || ((isInRange(y, y_offset, size2) == 1) && (isAtBorder(x, x_offset, size2-1) == 1))) { + printf("*"); + } else { + + //if not, + // check if EITHER + // x is less than size1 AND (y is either 0 or size1-1) + // OR + // y is less than size1 AND (x is either 0 or size1-1) + //if so, print a # + if ((x < size1 && (y == 0 ||y==size1 -1 )) ||(y < size1 &&(x == 0||x == size1 -1) ) ) { + printf("#"); + } + + //else print a space + else {printf(" "); + } + } + } + //when you finish counting x from 0 to w, + //print a newline + printf("\n"); + } + +} + diff --git a/06_rect/Makefile b/06_rect/Makefile new file mode 100644 index 0000000..b083f98 --- /dev/null +++ b/06_rect/Makefile @@ -0,0 +1,2 @@ +rectangle: rectangle.c + gcc -o rectangle -pedantic -std=gnu99 -Wall -Werror rectangle.c diff --git a/06_rect/README b/06_rect/README new file mode 100644 index 0000000..7309f2c --- /dev/null +++ b/06_rect/README @@ -0,0 +1,65 @@ +For this problem, we will be writing a function which takes +two rectangles, determines the region in which they overlap +(which is also a rectangle), and returns that region. + +Before proceeding, think about what the corner case(s) [no pun intended!] +in this problem might be. + + 1. Open the provided file called "rectangle.c" + + 2. In the "rectangle.c" file, define a struct for rectangles + which has 4 fields: x, y, width, and height. Each of these + fields should be an int. Use typedef so that the typename + "rectangle" refers to your struct. + + 3. One corner we might have to deal with is if the rectangle's + representation is non-standard: if the width or height are + negative. One way to deal with inputs that come in non-standard + formats is to "canonicalize" them---convert them to the standard + (or "canonical") representation. First, write the function + + rectangle canonicalize(rectangle r); + + which takes a rectangle, and "fixes" its representation + by ensuring that the width and height are non-negative (and + appropriately adjusting the x and/or y co-ordinate). That is, + if your canonicalize function were passed a rectangle with + x=3, y=2, width=-2, height=4 + then it should return a rectangle with + x=1, y=2, width=2, height=4 + as these both describe the same rectangle, but the later is + in a canonical representation. + + It may be a good idea to stop and test this function + before proceeding. Compile and run your code. + The main function we have provided should be useful, + as it canonicalizes the rectangles it prints. + + 4. Now, write the function + rectangle intersection(rectangle r1, rectangle r2) + which takes two rectangles (r1, and r2), and returns + the rectangle representing the intersection of the two. + + Note that there is a corner case where the correct answer + is "no intersection". We have not learned how to represent + "no such thing" yet, but we will consider a rectangle with + both width and height equal to 0 to mean "no such rectangle". + + We will consider a rectangle to have one (but not the other) + of width or height equal to 0 to be an appropriate answer + when rectangles share an edge but do not overlap. For example, + x=0,y=0,width=1, height=1 + and + x=-1,y=1,width=3,height=2 + Should result in the "rectangle" + x=0,y=1,width=1,height=0 + 5. We have provided a main function which tests your code, + as well as correct output (rectangle_ans.txt) to diff against. + + 6. Submit your code + +Hint: + Do Step 1 (work an example yourself) four or five times. + Draw a variety of different ways that rectangles can overlap. + Use these to help you think abou the general algorithm for how + to determine their overlapping region. diff --git a/06_rect/grade.txt b/06_rect/grade.txt new file mode 100644 index 0000000..c82efe8 --- /dev/null +++ b/06_rect/grade.txt @@ -0,0 +1,13 @@ +Grading at Sun 28 Nov 2021 08:50:44 PM UTC +Attempting to compile rectangle.c +Tring to run rectangle +Your file matched the expected output +removing your main() and replacing it with out own to run more tests... +################################################# +testcase1: +testcase1 passed +################################################# +testcase2: +testcase2 passed + +Overall Grade: A diff --git a/06_rect/rectangle.c b/06_rect/rectangle.c new file mode 100644 index 0000000..9d3708e --- /dev/null +++ b/06_rect/rectangle.c @@ -0,0 +1,201 @@ +#include <stdio.h> +#include <stdlib.h> +//I've provided "min" and "max" functions in +//case they are useful to you +int min (int a, int b) { + if (a < b) { + return a; + } + return b; +} +int max (int a, int b) { + if (a > b) { + return a; + } + return b; +} + +//Declare your rectangle structure here! +typedef struct rectangle_t { + int x; + int y; + int width; + int height; +} rectangle; + +rectangle canonicalize(rectangle r) { + //WRITE THIS FUNCTION + if (r.width < 0) { + r.x = r.x + r.width; + r.width = r.width * (-1); + } + if (r.height < 0) { + r.y = r.y + r.height; + r.height = r.height * (-1); + } + return r; +} +rectangle left_rect(rectangle r1, rectangle r2) { + if (r1.x < r2.x){ + return r1; + } else { + return r2; + } +} + +rectangle lower_rect(rectangle r1, rectangle r2) { + if (r1.y < r2.y){ + return r1; + } else { + return r2; + } +} + +rectangle intersection(rectangle r1, rectangle r2) { + //WRITE THIS FUNCTION + r1 = canonicalize(r1); + r2 = canonicalize(r2); + rectangle ans; + ans.x = max(r1.x, r2.x); + ans.y = max(r1.y, r2.y); + + // Find the width + // find the rectangle with the smallest x + rectangle left = left_rect(r1, r2); + if (ans.x <= left.x + left.width){ + ans.width = min(r1.x + r1.width, r2.x + r2.width) - ans.x; + } else { + ans.width = 0; + ans.height = 0; + return ans; + } + + rectangle lower = lower_rect(r1, r2); + if (ans.y <= lower.y + lower.height){ + ans.height = min(r1.y + r1.height, r2.y + r2.height) - ans.y; + } else { + ans.height = 0; + ans.width = 0; + return ans; + } + return ans; +} + +//You should not need to modify any code below this line +void printRectangle(rectangle r) { + r = canonicalize(r); + if (r.width == 0 && r.height == 0) { + printf("<empty>\n"); + } + else { + printf("(%d,%d) to (%d,%d)\n", r.x, r.y, + r.x + r.width, r.y + r.height); + } +} + +int main (void) { + rectangle r1; + rectangle r2; + rectangle r3; + rectangle r4; + + r1.x = 2; + r1.y = 3; + r1.width = 5; + r1.height = 6; + printf("r1 is "); + printRectangle(r1); + + r2.x = 4; + r2.y = 5; + r2.width = -5; + r2.height = -7; + printf("r2 is "); + printRectangle(r2); + + r3.x = -2; + r3.y = 7; + r3.width = 7; + r3.height = -10; + printf("r3 is "); + printRectangle(r3); + + r4.x = 0; + r4.y = 7; + r4.width = -4; + r4.height = 2; + printf("r4 is "); + printRectangle(r4); + + //test everything with r1 + rectangle i = intersection(r1,r1); + printf("intersection(r1,r1): "); + printRectangle(i); + + i = intersection(r1,r2); + printf("intersection(r1,r2): "); + printRectangle(i); + + i = intersection(r1,r3); + printf("intersection(r1,r3): "); + printRectangle(i); + + i = intersection(r1,r4); + printf("intersection(r1,r4): "); + printRectangle(i); + + //test everything with r2 + i = intersection(r2,r1); + printf("intersection(r2,r1): "); + printRectangle(i); + + i = intersection(r2,r2); + printf("intersection(r2,r2): "); + printRectangle(i); + + i = intersection(r2,r3); + printf("intersection(r2,r3): "); + printRectangle(i); + + i = intersection(r2,r4); + printf("intersection(r2,r4): "); + printRectangle(i); + + //test everything with r3 + i = intersection(r3,r1); + printf("intersection(r3,r1): "); + printRectangle(i); + + i = intersection(r3,r2); + printf("intersection(r3,r2): "); + printRectangle(i); + + i = intersection(r3,r3); + printf("intersection(r3,r3): "); + printRectangle(i); + + i = intersection(r3,r4); + printf("intersection(r3,r4): "); + printRectangle(i); + + //test everything with r4 + i = intersection(r4,r1); + printf("intersection(r4,r1): "); + printRectangle(i); + + i = intersection(r4,r2); + printf("intersection(r4,r2): "); + printRectangle(i); + + i = intersection(r4,r3); + printf("intersection(r4,r3): "); + printRectangle(i); + + i = intersection(r4,r4); + printf("intersection(r4,r4): "); + printRectangle(i); + + + return EXIT_SUCCESS; + +} diff --git a/06_rect/rectangle_ans.txt b/06_rect/rectangle_ans.txt new file mode 100644 index 0000000..0b1b88f --- /dev/null +++ b/06_rect/rectangle_ans.txt @@ -0,0 +1,20 @@ +r1 is (2,3) to (7,9) +r2 is (-1,-2) to (4,5) +r3 is (-2,-3) to (5,7) +r4 is (-4,7) to (0,9) +intersection(r1,r1): (2,3) to (7,9) +intersection(r1,r2): (2,3) to (4,5) +intersection(r1,r3): (2,3) to (5,7) +intersection(r1,r4): <empty> +intersection(r2,r1): (2,3) to (4,5) +intersection(r2,r2): (-1,-2) to (4,5) +intersection(r2,r3): (-1,-2) to (4,5) +intersection(r2,r4): <empty> +intersection(r3,r1): (2,3) to (5,7) +intersection(r3,r2): (-1,-2) to (4,5) +intersection(r3,r3): (-2,-3) to (5,7) +intersection(r3,r4): (-2,7) to (0,7) +intersection(r4,r1): <empty> +intersection(r4,r2): <empty> +intersection(r4,r3): (-2,7) to (0,7) +intersection(r4,r4): (-4,7) to (0,9) diff --git a/07_retirement/Makefile b/07_retirement/Makefile new file mode 100644 index 0000000..066d283 --- /dev/null +++ b/07_retirement/Makefile @@ -0,0 +1,2 @@ +retirement: retirement.c + gcc -o retirement -pedantic -std=gnu99 -Wall -Werror retirement.c diff --git a/07_retirement/README b/07_retirement/README new file mode 100644 index 0000000..0e9d000 --- /dev/null +++ b/07_retirement/README @@ -0,0 +1,82 @@ + For this problem, you will be writing a "retirement savings" calculator. + We'll remove the effects of inflation by keeping everything in + "today's dollars" and using a "Rate of return" that is in terms of + "more than inflation." + + 1. Create a file called "retirement.c". Include the usual header + files (stdlib.h and stdio.h) at the top. + + 2. We're going to model both savings (while working) and expenditure + (while retired). It turns out that both of these require the + same basic information, so we will make a struct to represent that. + Declare a struct _retire_info which has three fields: + (1) an int called "months" for the number of months it is applicable to, + (2) a double called "contribution" for how many dollars + are contributed (or spent if negative) from the account per month + (3) a double called "rate_of_return" for the rate of returns + (which we will assume to be "after inflation"). + + After you have declared this struct, use typedef to make "retire_info" + another name for this struct. + + 3. Write the function + void retirement (int startAge, //in months + double initial, //initial savings in dollars + retire_info working, //info about working + retire_info retired) //info about being retired + + This function should perform two tasks (which are similar---look + for a chance to abstract something out into a function!). + + First, it should compute your retirement account balance each + month while you are working. To do this, you need to calculate + the account balance increase from returns (balance * rate of return), + and add that to the current balance. You then need to add the + monthly contribution to the balance. + For example, if you have $1,000 in the account, earn a 0.5% rate of + return per month, and contribute $100 per month, you would + cmopute 1000 * 0.005 = $5 in interest earned. You would then + add this plus the monthly contribution to the balance to end up + with $1105 in the account at the end of the month. + + At the start of each month (before the balance changes), you should + print out the current balance with the following format: + "Age %3d month %2d you have $%.2lf\n" + The first two format conversions are the savers age in years and months. + The third format conversion is the account balance + This calculation goes on for the number of months specified + in the "working" retire_info structure. + + + Second, you should perform a very similar calculation for each + month of retirment. The difference here is that you will use the + information in the "retired" retire_info structure instead + of the information in the "working" structure. As with + working, you should print out the same information as before. + + [Hint: since you are performing a very similar computation, + think about how you can abstract that part out into a function, + and re-use it, rather than re-writing it] + + 4. Write a main function which computes the retirement assuming + Working: + -------- + Months: 489 + Per Month Savings: $1000 + Rate of Return: 4.5% per year ( 0.045/12 per month) + [above inflation] + Retired: + -------- + Months: 384 + Per Month Spending: -4000 + Rate of Return: 1% per year ( 0.01/12 per month) + [above inflation] + Starting conditions: + ------------------- + Age: 327 months (27 years, 3 months) + Savings: $21,345 + 5. Compile your code (we provided a Makefile) and test + it (we provided the output: retirement_ans.txt). + + 6. Submit retirement.c + diff --git a/07_retirement/grade.txt b/07_retirement/grade.txt new file mode 100644 index 0000000..85fb66b --- /dev/null +++ b/07_retirement/grade.txt @@ -0,0 +1,279 @@ +Grading at Mon 29 Nov 2021 01:53:29 AM UTC +Attempting to compile retirement.c +Checking for struct _retire_info +Found on line 4, column 1 +Checking for field int months +Found on line 5, column 3 +Checking for field double contribution +Found on line 6, column 3 +Checking for field double rate_of_return +Found on line 7, column 3 +Checking for typedef of struct _retire_info to retire_info +Found on line 9, column 1 +Checking for void retirement (int startAge, double initial, retire_info working, retire_info retired) +Found on line 11, column 1 +Checking for int main(void) +Found on line 32, column 1 +Trying to run retirement calculator.. +Your file matched the expected output +Removing your main() and replacing it with our own to run more tests... + | Working | Retired + Age | Initial | Saving | Rate | Months | Spending | Rate | Months | Result + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0008900 | 220 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0008900 | 406 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0043300 | 221 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0043300 | 382 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0006600 | 233 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0006600 | 399 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0040800 | 219 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0040800 | 407 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -3567.00 | 0.0008600 | 221 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -3567.00 | 0.0008600 | 375 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -3567.00 | 0.0045300 | 215 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -3567.00 | 0.0045300 | 396 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -6534.00 | 0.0009100 | 228 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -6534.00 | 0.0009100 | 401 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -6534.00 | 0.0044500 | 218 | Correct + 240 | 0.00 | 1234.00 | 0.0026700 | 591 | -6534.00 | 0.0044500 | 406 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0006700 | 224 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0006700 | 400 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0041500 | 230 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0041500 | 372 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0008300 | 217 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0008300 | 406 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0048900 | 233 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0048900 | 386 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -3567.00 | 0.0006600 | 212 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -3567.00 | 0.0006600 | 377 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -3567.00 | 0.0047400 | 232 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -3567.00 | 0.0047400 | 401 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -6534.00 | 0.0008900 | 233 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -6534.00 | 0.0008900 | 391 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -6534.00 | 0.0043800 | 208 | Correct + 240 | 0.00 | 1234.00 | 0.0056700 | 592 | -6534.00 | 0.0043800 | 370 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -3567.00 | 0.0005500 | 227 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -3567.00 | 0.0005500 | 403 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -3567.00 | 0.0043300 | 214 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -3567.00 | 0.0043300 | 406 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -6534.00 | 0.0006200 | 213 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -6534.00 | 0.0006200 | 394 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -6534.00 | 0.0041100 | 217 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 597 | -6534.00 | 0.0041100 | 393 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -3567.00 | 0.0004600 | 208 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -3567.00 | 0.0004600 | 392 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -3567.00 | 0.0045400 | 214 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -3567.00 | 0.0045400 | 401 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -6534.00 | 0.0007000 | 229 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -6534.00 | 0.0007000 | 402 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -6534.00 | 0.0049900 | 218 | Correct + 240 | 0.00 | 2673.00 | 0.0026700 | 612 | -6534.00 | 0.0049900 | 373 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -3567.00 | 0.0005200 | 206 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -3567.00 | 0.0005200 | 370 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -3567.00 | 0.0047300 | 208 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -3567.00 | 0.0047300 | 406 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -6534.00 | 0.0007300 | 214 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -6534.00 | 0.0007300 | 378 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -6534.00 | 0.0047300 | 211 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 597 | -6534.00 | 0.0047300 | 399 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -3567.00 | 0.0001800 | 230 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -3567.00 | 0.0001800 | 384 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -3567.00 | 0.0045200 | 220 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -3567.00 | 0.0045200 | 384 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -6534.00 | 0.0009800 | 230 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -6534.00 | 0.0009800 | 392 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -6534.00 | 0.0047300 | 219 | Correct + 240 | 0.00 | 2673.00 | 0.0056700 | 611 | -6534.00 | 0.0047300 | 393 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0003200 | 211 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0003200 | 386 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0042700 | 206 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0042700 | 374 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0000100 | 217 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0000100 | 408 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0041600 | 225 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0041600 | 391 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -3567.00 | 0.0002900 | 227 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -3567.00 | 0.0002900 | 376 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -3567.00 | 0.0044100 | 209 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -3567.00 | 0.0044100 | 375 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -6534.00 | 0.0006800 | 233 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -6534.00 | 0.0006800 | 389 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -6534.00 | 0.0041000 | 223 | Correct + 240 | 11222.51 | 1234.00 | 0.0026700 | 595 | -6534.00 | 0.0041000 | 404 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0001300 | 224 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0001300 | 374 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0042500 | 209 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0042500 | 383 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0005000 | 232 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0005000 | 405 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0043500 | 228 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0043500 | 396 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -3567.00 | 0.0003900 | 213 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -3567.00 | 0.0003900 | 398 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -3567.00 | 0.0047200 | 226 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -3567.00 | 0.0047200 | 398 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -6534.00 | 0.0002000 | 208 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -6534.00 | 0.0002000 | 396 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -6534.00 | 0.0042200 | 226 | Correct + 240 | 11222.51 | 1234.00 | 0.0056700 | 606 | -6534.00 | 0.0042200 | 379 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -3567.00 | 0.0000000 | 222 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -3567.00 | 0.0000000 | 398 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -3567.00 | 0.0047100 | 204 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -3567.00 | 0.0047100 | 405 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -6534.00 | 0.0005100 | 230 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -6534.00 | 0.0005100 | 400 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -6534.00 | 0.0048600 | 221 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 597 | -6534.00 | 0.0048600 | 405 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -3567.00 | 0.0003600 | 206 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -3567.00 | 0.0003600 | 395 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -3567.00 | 0.0047900 | 229 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -3567.00 | 0.0047900 | 382 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -6534.00 | 0.0001400 | 222 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -6534.00 | 0.0001400 | 390 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -6534.00 | 0.0042000 | 230 | Correct + 240 | 11222.51 | 2562.00 | 0.0026700 | 593 | -6534.00 | 0.0042000 | 401 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -3567.00 | 0.0004600 | 233 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -3567.00 | 0.0004600 | 391 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -3567.00 | 0.0046800 | 225 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -3567.00 | 0.0046800 | 373 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -6534.00 | 0.0006000 | 206 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -6534.00 | 0.0006000 | 397 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -6534.00 | 0.0047200 | 222 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 597 | -6534.00 | 0.0047200 | 403 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -3567.00 | 0.0006200 | 204 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -3567.00 | 0.0006200 | 409 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -3567.00 | 0.0044000 | 220 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -3567.00 | 0.0044000 | 408 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -6534.00 | 0.0003800 | 212 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -6534.00 | 0.0003800 | 391 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -6534.00 | 0.0044500 | 204 | Correct + 240 | 11222.51 | 2562.00 | 0.0056700 | 611 | -6534.00 | 0.0044500 | 371 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0002000 | 205 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0002000 | 390 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0040600 | 204 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0040600 | 378 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0003300 | 209 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0003300 | 409 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0042700 | 218 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0042700 | 407 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -3567.00 | 0.0006900 | 232 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -3567.00 | 0.0006900 | 381 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -3567.00 | 0.0040500 | 214 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -3567.00 | 0.0040500 | 382 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -6534.00 | 0.0005200 | 222 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -6534.00 | 0.0005200 | 393 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -6534.00 | 0.0045600 | 215 | Correct + 345 | 0.00 | 1234.00 | 0.0026700 | 586 | -6534.00 | 0.0045600 | 404 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0001400 | 230 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0001400 | 401 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0042400 | 232 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0042400 | 406 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0008500 | 222 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0008500 | 396 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0046400 | 221 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0046400 | 409 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -3567.00 | 0.0007900 | 224 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -3567.00 | 0.0007900 | 385 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -3567.00 | 0.0041500 | 207 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -3567.00 | 0.0041500 | 390 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -6534.00 | 0.0006100 | 207 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -6534.00 | 0.0006100 | 387 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -6534.00 | 0.0048100 | 214 | Correct + 345 | 0.00 | 1234.00 | 0.0056700 | 610 | -6534.00 | 0.0048100 | 403 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -3567.00 | 0.0009000 | 221 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -3567.00 | 0.0009000 | 409 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -3567.00 | 0.0042100 | 227 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -3567.00 | 0.0042100 | 402 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -6534.00 | 0.0003900 | 225 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -6534.00 | 0.0003900 | 395 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -6534.00 | 0.0046700 | 204 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 597 | -6534.00 | 0.0046700 | 387 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -3567.00 | 0.0006000 | 227 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -3567.00 | 0.0006000 | 393 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -3567.00 | 0.0045800 | 213 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -3567.00 | 0.0045800 | 393 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -6534.00 | 0.0009400 | 220 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -6534.00 | 0.0009400 | 377 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -6534.00 | 0.0040300 | 209 | Correct + 345 | 0.00 | 3384.00 | 0.0026700 | 590 | -6534.00 | 0.0040300 | 386 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -3567.00 | 0.0007100 | 233 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -3567.00 | 0.0007100 | 396 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -3567.00 | 0.0043300 | 226 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -3567.00 | 0.0043300 | 393 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -6534.00 | 0.0006000 | 216 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -6534.00 | 0.0006000 | 400 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -6534.00 | 0.0040400 | 233 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 597 | -6534.00 | 0.0040400 | 379 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -3567.00 | 0.0009300 | 207 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -3567.00 | 0.0009300 | 391 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -3567.00 | 0.0044400 | 233 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -3567.00 | 0.0044400 | 397 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -6534.00 | 0.0000900 | 223 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -6534.00 | 0.0000900 | 387 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -6534.00 | 0.0046700 | 221 | Correct + 345 | 0.00 | 3384.00 | 0.0056700 | 600 | -6534.00 | 0.0046700 | 392 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0003600 | 204 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0003600 | 388 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0046300 | 207 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -3567.00 | 0.0046300 | 388 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0001900 | 207 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0001900 | 376 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0041800 | 207 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 597 | -6534.00 | 0.0041800 | 373 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -3567.00 | 0.0008700 | 213 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -3567.00 | 0.0008700 | 399 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -3567.00 | 0.0041900 | 232 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -3567.00 | 0.0041900 | 381 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -6534.00 | 0.0006900 | 212 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -6534.00 | 0.0006900 | 398 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -6534.00 | 0.0047100 | 232 | Correct + 345 | 14292.05 | 1234.00 | 0.0026700 | 610 | -6534.00 | 0.0047100 | 370 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0007400 | 229 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0007400 | 377 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0040800 | 206 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -3567.00 | 0.0040800 | 406 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0009800 | 215 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0009800 | 405 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0040200 | 227 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 597 | -6534.00 | 0.0040200 | 388 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -3567.00 | 0.0007000 | 206 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -3567.00 | 0.0007000 | 387 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -3567.00 | 0.0042300 | 223 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -3567.00 | 0.0042300 | 375 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -6534.00 | 0.0007300 | 229 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -6534.00 | 0.0007300 | 373 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -6534.00 | 0.0049900 | 204 | Correct + 345 | 14292.05 | 1234.00 | 0.0056700 | 595 | -6534.00 | 0.0049900 | 388 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -3567.00 | 0.0006400 | 204 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -3567.00 | 0.0006400 | 394 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -3567.00 | 0.0045400 | 218 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -3567.00 | 0.0045400 | 375 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -6534.00 | 0.0007000 | 206 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -6534.00 | 0.0007000 | 408 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -6534.00 | 0.0043300 | 227 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 597 | -6534.00 | 0.0043300 | 376 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -3567.00 | 0.0001400 | 225 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -3567.00 | 0.0001400 | 375 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -3567.00 | 0.0044600 | 210 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -3567.00 | 0.0044600 | 391 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -6534.00 | 0.0004900 | 233 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -6534.00 | 0.0004900 | 385 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -6534.00 | 0.0048000 | 212 | Correct + 345 | 14292.05 | 2904.00 | 0.0026700 | 587 | -6534.00 | 0.0048000 | 396 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -3567.00 | 0.0007500 | 212 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -3567.00 | 0.0007500 | 401 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -3567.00 | 0.0040400 | 220 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -3567.00 | 0.0040400 | 378 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -6534.00 | 0.0001300 | 211 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -6534.00 | 0.0001300 | 407 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -6534.00 | 0.0040800 | 211 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 597 | -6534.00 | 0.0040800 | 396 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -3567.00 | 0.0001300 | 227 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -3567.00 | 0.0001300 | 376 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -3567.00 | 0.0043200 | 218 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -3567.00 | 0.0043200 | 382 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -6534.00 | 0.0003700 | 230 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -6534.00 | 0.0003700 | 375 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -6534.00 | 0.0047100 | 223 | Correct + 345 | 14292.05 | 2904.00 | 0.0056700 | 594 | -6534.00 | 0.0047100 | 397 | Correct + +Overall Grade: A diff --git a/07_retirement/retirement.c b/07_retirement/retirement.c new file mode 100644 index 0000000..fd2d5c5 --- /dev/null +++ b/07_retirement/retirement.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <stdlib.h> + +struct _retire_info { + int months; + double contribution; + double rate_of_return; +}; +typedef struct _retire_info retire_info; + +void retirement (int startAge, //in months + double initial, //initial savings in dollars + retire_info working, //info about working + retire_info retired) //info about being retired +{ + double balance = initial; + int age = startAge; + for (int i = 1; i <= working.months; i++) { + printf("Age %3d month %2d you have $%.2lf\n", age / 12, age % 12, balance); + balance = balance * (1 + working.rate_of_return) + working.contribution; + age++; + } + + for (int i = 1; i <= retired.months; i++) { + printf("Age %3d month %2d you have $%.2lf\n", age / 12, age % 12, balance); + balance = balance * (1 + retired.rate_of_return) + retired.contribution; + age++; + } + +} + +int main (void) { + retire_info working; + working.months = 489; + working.contribution = 1000; + working.rate_of_return = 0.045/12; + + retire_info retired; + retired.months = 384; + retired.contribution = -4000; + retired.rate_of_return = 0.01/12; + + retirement(327, 21345, working, retired); + return EXIT_SUCCESS; +} diff --git a/07_retirement/retirement_ans.txt b/07_retirement/retirement_ans.txt new file mode 100644 index 0000000..6804877 --- /dev/null +++ b/07_retirement/retirement_ans.txt @@ -0,0 +1,873 @@ +Age 27 month 3 you have $21345.00 +Age 27 month 4 you have $22425.04 +Age 27 month 5 you have $23509.14 +Age 27 month 6 you have $24597.30 +Age 27 month 7 you have $25689.54 +Age 27 month 8 you have $26785.87 +Age 27 month 9 you have $27886.32 +Age 27 month 10 you have $28990.89 +Age 27 month 11 you have $30099.61 +Age 28 month 0 you have $31212.48 +Age 28 month 1 you have $32329.53 +Age 28 month 2 you have $33450.77 +Age 28 month 3 you have $34576.21 +Age 28 month 4 you have $35705.87 +Age 28 month 5 you have $36839.76 +Age 28 month 6 you have $37977.91 +Age 28 month 7 you have $39120.33 +Age 28 month 8 you have $40267.03 +Age 28 month 9 you have $41418.03 +Age 28 month 10 you have $42573.35 +Age 28 month 11 you have $43733.00 +Age 29 month 0 you have $44897.00 +Age 29 month 1 you have $46065.36 +Age 29 month 2 you have $47238.11 +Age 29 month 3 you have $48415.25 +Age 29 month 4 you have $49596.81 +Age 29 month 5 you have $50782.80 +Age 29 month 6 you have $51973.23 +Age 29 month 7 you have $53168.13 +Age 29 month 8 you have $54367.51 +Age 29 month 9 you have $55571.39 +Age 29 month 10 you have $56779.78 +Age 29 month 11 you have $57992.71 +Age 30 month 0 you have $59210.18 +Age 30 month 1 you have $60432.22 +Age 30 month 2 you have $61658.84 +Age 30 month 3 you have $62890.06 +Age 30 month 4 you have $64125.90 +Age 30 month 5 you have $65366.37 +Age 30 month 6 you have $66611.49 +Age 30 month 7 you have $67861.29 +Age 30 month 8 you have $69115.77 +Age 30 month 9 you have $70374.95 +Age 30 month 10 you have $71638.86 +Age 30 month 11 you have $72907.50 +Age 31 month 0 you have $74180.90 +Age 31 month 1 you have $75459.08 +Age 31 month 2 you have $76742.05 +Age 31 month 3 you have $78029.84 +Age 31 month 4 you have $79322.45 +Age 31 month 5 you have $80619.91 +Age 31 month 6 you have $81922.23 +Age 31 month 7 you have $83229.44 +Age 31 month 8 you have $84541.55 +Age 31 month 9 you have $85858.58 +Age 31 month 10 you have $87180.55 +Age 31 month 11 you have $88507.48 +Age 32 month 0 you have $89839.38 +Age 32 month 1 you have $91176.28 +Age 32 month 2 you have $92518.19 +Age 32 month 3 you have $93865.13 +Age 32 month 4 you have $95217.13 +Age 32 month 5 you have $96574.19 +Age 32 month 6 you have $97936.35 +Age 32 month 7 you have $99303.61 +Age 32 month 8 you have $100676.00 +Age 32 month 9 you have $102053.53 +Age 32 month 10 you have $103436.23 +Age 32 month 11 you have $104824.12 +Age 33 month 0 you have $106217.21 +Age 33 month 1 you have $107615.52 +Age 33 month 2 you have $109019.08 +Age 33 month 3 you have $110427.90 +Age 33 month 4 you have $111842.01 +Age 33 month 5 you have $113261.41 +Age 33 month 6 you have $114686.14 +Age 33 month 7 you have $116116.22 +Age 33 month 8 you have $117551.65 +Age 33 month 9 you have $118992.47 +Age 33 month 10 you have $120438.69 +Age 33 month 11 you have $121890.34 +Age 34 month 0 you have $123347.43 +Age 34 month 1 you have $124809.98 +Age 34 month 2 you have $126278.02 +Age 34 month 3 you have $127751.56 +Age 34 month 4 you have $129230.63 +Age 34 month 5 you have $130715.24 +Age 34 month 6 you have $132205.43 +Age 34 month 7 you have $133701.20 +Age 34 month 8 you have $135202.58 +Age 34 month 9 you have $136709.59 +Age 34 month 10 you have $138222.25 +Age 34 month 11 you have $139740.58 +Age 35 month 0 you have $141264.61 +Age 35 month 1 you have $142794.35 +Age 35 month 2 you have $144329.83 +Age 35 month 3 you have $145871.06 +Age 35 month 4 you have $147418.08 +Age 35 month 5 you have $148970.90 +Age 35 month 6 you have $150529.54 +Age 35 month 7 you have $152094.03 +Age 35 month 8 you have $153664.38 +Age 35 month 9 you have $155240.62 +Age 35 month 10 you have $156822.77 +Age 35 month 11 you have $158410.86 +Age 36 month 0 you have $160004.90 +Age 36 month 1 you have $161604.92 +Age 36 month 2 you have $163210.93 +Age 36 month 3 you have $164822.98 +Age 36 month 4 you have $166441.06 +Age 36 month 5 you have $168065.22 +Age 36 month 6 you have $169695.46 +Age 36 month 7 you have $171331.82 +Age 36 month 8 you have $172974.31 +Age 36 month 9 you have $174622.97 +Age 36 month 10 you have $176277.80 +Age 36 month 11 you have $177938.84 +Age 37 month 0 you have $179606.12 +Age 37 month 1 you have $181279.64 +Age 37 month 2 you have $182959.44 +Age 37 month 3 you have $184645.53 +Age 37 month 4 you have $186337.96 +Age 37 month 5 you have $188036.72 +Age 37 month 6 you have $189741.86 +Age 37 month 7 you have $191453.39 +Age 37 month 8 you have $193171.34 +Age 37 month 9 you have $194895.74 +Age 37 month 10 you have $196626.59 +Age 37 month 11 you have $198363.94 +Age 38 month 0 you have $200107.81 +Age 38 month 1 you have $201858.21 +Age 38 month 2 you have $203615.18 +Age 38 month 3 you have $205378.74 +Age 38 month 4 you have $207148.91 +Age 38 month 5 you have $208925.72 +Age 38 month 6 you have $210709.19 +Age 38 month 7 you have $212499.35 +Age 38 month 8 you have $214296.22 +Age 38 month 9 you have $216099.83 +Age 38 month 10 you have $217910.21 +Age 38 month 11 you have $219727.37 +Age 39 month 0 you have $221551.35 +Age 39 month 1 you have $223382.16 +Age 39 month 2 you have $225219.85 +Age 39 month 3 you have $227064.42 +Age 39 month 4 you have $228915.91 +Age 39 month 5 you have $230774.35 +Age 39 month 6 you have $232639.75 +Age 39 month 7 you have $234512.15 +Age 39 month 8 you have $236391.57 +Age 39 month 9 you have $238278.04 +Age 39 month 10 you have $240171.58 +Age 39 month 11 you have $242072.23 +Age 40 month 0 you have $243980.00 +Age 40 month 1 you have $245894.92 +Age 40 month 2 you have $247817.03 +Age 40 month 3 you have $249746.34 +Age 40 month 4 you have $251682.89 +Age 40 month 5 you have $253626.70 +Age 40 month 6 you have $255577.80 +Age 40 month 7 you have $257536.22 +Age 40 month 8 you have $259501.98 +Age 40 month 9 you have $261475.11 +Age 40 month 10 you have $263455.64 +Age 40 month 11 you have $265443.60 +Age 41 month 0 you have $267439.01 +Age 41 month 1 you have $269441.91 +Age 41 month 2 you have $271452.32 +Age 41 month 3 you have $273470.26 +Age 41 month 4 you have $275495.78 +Age 41 month 5 you have $277528.89 +Age 41 month 6 you have $279569.62 +Age 41 month 7 you have $281618.01 +Age 41 month 8 you have $283674.07 +Age 41 month 9 you have $285737.85 +Age 41 month 10 you have $287809.37 +Age 41 month 11 you have $289888.65 +Age 42 month 0 you have $291975.74 +Age 42 month 1 you have $294070.65 +Age 42 month 2 you have $296173.41 +Age 42 month 3 you have $298284.06 +Age 42 month 4 you have $300402.63 +Age 42 month 5 you have $302529.14 +Age 42 month 6 you have $304663.62 +Age 42 month 7 you have $306806.11 +Age 42 month 8 you have $308956.63 +Age 42 month 9 you have $311115.22 +Age 42 month 10 you have $313281.90 +Age 42 month 11 you have $315456.71 +Age 43 month 0 you have $317639.67 +Age 43 month 1 you have $319830.82 +Age 43 month 2 you have $322030.18 +Age 43 month 3 you have $324237.80 +Age 43 month 4 you have $326453.69 +Age 43 month 5 you have $328677.89 +Age 43 month 6 you have $330910.43 +Age 43 month 7 you have $333151.35 +Age 43 month 8 you have $335400.66 +Age 43 month 9 you have $337658.42 +Age 43 month 10 you have $339924.64 +Age 43 month 11 you have $342199.35 +Age 44 month 0 you have $344482.60 +Age 44 month 1 you have $346774.41 +Age 44 month 2 you have $349074.82 +Age 44 month 3 you have $351383.85 +Age 44 month 4 you have $353701.54 +Age 44 month 5 you have $356027.92 +Age 44 month 6 you have $358363.02 +Age 44 month 7 you have $360706.88 +Age 44 month 8 you have $363059.53 +Age 44 month 9 you have $365421.01 +Age 44 month 10 you have $367791.33 +Age 44 month 11 you have $370170.55 +Age 45 month 0 you have $372558.69 +Age 45 month 1 you have $374955.79 +Age 45 month 2 you have $377361.87 +Age 45 month 3 you have $379776.98 +Age 45 month 4 you have $382201.14 +Age 45 month 5 you have $384634.40 +Age 45 month 6 you have $387076.78 +Age 45 month 7 you have $389528.31 +Age 45 month 8 you have $391989.04 +Age 45 month 9 you have $394459.00 +Age 45 month 10 you have $396938.22 +Age 45 month 11 you have $399426.74 +Age 46 month 0 you have $401924.59 +Age 46 month 1 you have $404431.81 +Age 46 month 2 you have $406948.43 +Age 46 month 3 you have $409474.49 +Age 46 month 4 you have $412010.02 +Age 46 month 5 you have $414555.05 +Age 46 month 6 you have $417109.63 +Age 46 month 7 you have $419673.80 +Age 46 month 8 you have $422247.57 +Age 46 month 9 you have $424831.00 +Age 46 month 10 you have $427424.12 +Age 46 month 11 you have $430026.96 +Age 47 month 0 you have $432639.56 +Age 47 month 1 you have $435261.96 +Age 47 month 2 you have $437894.19 +Age 47 month 3 you have $440536.29 +Age 47 month 4 you have $443188.30 +Age 47 month 5 you have $445850.26 +Age 47 month 6 you have $448522.20 +Age 47 month 7 you have $451204.16 +Age 47 month 8 you have $453896.17 +Age 47 month 9 you have $456598.28 +Age 47 month 10 you have $459310.53 +Age 47 month 11 you have $462032.94 +Age 48 month 0 you have $464765.56 +Age 48 month 1 you have $467508.43 +Age 48 month 2 you have $470261.59 +Age 48 month 3 you have $473025.07 +Age 48 month 4 you have $475798.92 +Age 48 month 5 you have $478583.16 +Age 48 month 6 you have $481377.85 +Age 48 month 7 you have $484183.02 +Age 48 month 8 you have $486998.70 +Age 48 month 9 you have $489824.95 +Age 48 month 10 you have $492661.79 +Age 48 month 11 you have $495509.27 +Age 49 month 0 you have $498367.43 +Age 49 month 1 you have $501236.31 +Age 49 month 2 you have $504115.95 +Age 49 month 3 you have $507006.38 +Age 49 month 4 you have $509907.66 +Age 49 month 5 you have $512819.81 +Age 49 month 6 you have $515742.88 +Age 49 month 7 you have $518676.92 +Age 49 month 8 you have $521621.96 +Age 49 month 9 you have $524578.04 +Age 49 month 10 you have $527545.21 +Age 49 month 11 you have $530523.50 +Age 50 month 0 you have $533512.97 +Age 50 month 1 you have $536513.64 +Age 50 month 2 you have $539525.57 +Age 50 month 3 you have $542548.79 +Age 50 month 4 you have $545583.34 +Age 50 month 5 you have $548629.28 +Age 50 month 6 you have $551686.64 +Age 50 month 7 you have $554755.47 +Age 50 month 8 you have $557835.80 +Age 50 month 9 you have $560927.68 +Age 50 month 10 you have $564031.16 +Age 50 month 11 you have $567146.28 +Age 51 month 0 you have $570273.08 +Age 51 month 1 you have $573411.60 +Age 51 month 2 you have $576561.90 +Age 51 month 3 you have $579724.00 +Age 51 month 4 you have $582897.97 +Age 51 month 5 you have $586083.83 +Age 51 month 6 you have $589281.65 +Age 51 month 7 you have $592491.46 +Age 51 month 8 you have $595713.30 +Age 51 month 9 you have $598947.22 +Age 51 month 10 you have $602193.28 +Age 51 month 11 you have $605451.50 +Age 52 month 0 you have $608721.94 +Age 52 month 1 you have $612004.65 +Age 52 month 2 you have $615299.67 +Age 52 month 3 you have $618607.04 +Age 52 month 4 you have $621926.82 +Age 52 month 5 you have $625259.04 +Age 52 month 6 you have $628603.77 +Age 52 month 7 you have $631961.03 +Age 52 month 8 you have $635330.88 +Age 52 month 9 you have $638713.37 +Age 52 month 10 you have $642108.55 +Age 52 month 11 you have $645516.46 +Age 53 month 0 you have $648937.14 +Age 53 month 1 you have $652370.66 +Age 53 month 2 you have $655817.05 +Age 53 month 3 you have $659276.36 +Age 53 month 4 you have $662748.65 +Age 53 month 5 you have $666233.95 +Age 53 month 6 you have $669732.33 +Age 53 month 7 you have $673243.83 +Age 53 month 8 you have $676768.49 +Age 53 month 9 you have $680306.37 +Age 53 month 10 you have $683857.52 +Age 53 month 11 you have $687421.99 +Age 54 month 0 you have $690999.82 +Age 54 month 1 you have $694591.07 +Age 54 month 2 you have $698195.79 +Age 54 month 3 you have $701814.02 +Age 54 month 4 you have $705445.82 +Age 54 month 5 you have $709091.25 +Age 54 month 6 you have $712750.34 +Age 54 month 7 you have $716423.15 +Age 54 month 8 you have $720109.74 +Age 54 month 9 you have $723810.15 +Age 54 month 10 you have $727524.44 +Age 54 month 11 you have $731252.66 +Age 55 month 0 you have $734994.85 +Age 55 month 1 you have $738751.08 +Age 55 month 2 you have $742521.40 +Age 55 month 3 you have $746305.86 +Age 55 month 4 you have $750104.50 +Age 55 month 5 you have $753917.39 +Age 55 month 6 you have $757744.58 +Age 55 month 7 you have $761586.13 +Age 55 month 8 you have $765442.07 +Age 55 month 9 you have $769312.48 +Age 55 month 10 you have $773197.40 +Age 55 month 11 you have $777096.89 +Age 56 month 0 you have $781011.01 +Age 56 month 1 you have $784939.80 +Age 56 month 2 you have $788883.32 +Age 56 month 3 you have $792841.64 +Age 56 month 4 you have $796814.79 +Age 56 month 5 you have $800802.85 +Age 56 month 6 you have $804805.86 +Age 56 month 7 you have $808823.88 +Age 56 month 8 you have $812856.97 +Age 56 month 9 you have $816905.18 +Age 56 month 10 you have $820968.58 +Age 56 month 11 you have $825047.21 +Age 57 month 0 you have $829141.14 +Age 57 month 1 you have $833250.42 +Age 57 month 2 you have $837375.10 +Age 57 month 3 you have $841515.26 +Age 57 month 4 you have $845670.94 +Age 57 month 5 you have $849842.21 +Age 57 month 6 you have $854029.12 +Age 57 month 7 you have $858231.73 +Age 57 month 8 you have $862450.10 +Age 57 month 9 you have $866684.28 +Age 57 month 10 you have $870934.35 +Age 57 month 11 you have $875200.35 +Age 58 month 0 you have $879482.36 +Age 58 month 1 you have $883780.41 +Age 58 month 2 you have $888094.59 +Age 58 month 3 you have $892424.95 +Age 58 month 4 you have $896771.54 +Age 58 month 5 you have $901134.43 +Age 58 month 6 you have $905513.69 +Age 58 month 7 you have $909909.36 +Age 58 month 8 you have $914321.52 +Age 58 month 9 you have $918750.23 +Age 58 month 10 you have $923195.54 +Age 58 month 11 you have $927657.53 +Age 59 month 0 you have $932136.24 +Age 59 month 1 you have $936631.75 +Age 59 month 2 you have $941144.12 +Age 59 month 3 you have $945673.41 +Age 59 month 4 you have $950219.69 +Age 59 month 5 you have $954783.01 +Age 59 month 6 you have $959363.45 +Age 59 month 7 you have $963961.06 +Age 59 month 8 you have $968575.91 +Age 59 month 9 you have $973208.07 +Age 59 month 10 you have $977857.60 +Age 59 month 11 you have $982524.57 +Age 60 month 0 you have $987209.04 +Age 60 month 1 you have $991911.07 +Age 60 month 2 you have $996630.74 +Age 60 month 3 you have $1001368.10 +Age 60 month 4 you have $1006123.23 +Age 60 month 5 you have $1010896.19 +Age 60 month 6 you have $1015687.06 +Age 60 month 7 you have $1020495.88 +Age 60 month 8 you have $1025322.74 +Age 60 month 9 you have $1030167.70 +Age 60 month 10 you have $1035030.83 +Age 60 month 11 you have $1039912.20 +Age 61 month 0 you have $1044811.87 +Age 61 month 1 you have $1049729.91 +Age 61 month 2 you have $1054666.40 +Age 61 month 3 you have $1059621.40 +Age 61 month 4 you have $1064594.98 +Age 61 month 5 you have $1069587.21 +Age 61 month 6 you have $1074598.16 +Age 61 month 7 you have $1079627.90 +Age 61 month 8 you have $1084676.51 +Age 61 month 9 you have $1089744.05 +Age 61 month 10 you have $1094830.59 +Age 61 month 11 you have $1099936.20 +Age 62 month 0 you have $1105060.96 +Age 62 month 1 you have $1110204.94 +Age 62 month 2 you have $1115368.21 +Age 62 month 3 you have $1120550.84 +Age 62 month 4 you have $1125752.91 +Age 62 month 5 you have $1130974.48 +Age 62 month 6 you have $1136215.63 +Age 62 month 7 you have $1141476.44 +Age 62 month 8 you have $1146756.98 +Age 62 month 9 you have $1152057.32 +Age 62 month 10 you have $1157377.53 +Age 62 month 11 you have $1162717.70 +Age 63 month 0 you have $1168077.89 +Age 63 month 1 you have $1173458.18 +Age 63 month 2 you have $1178858.65 +Age 63 month 3 you have $1184279.37 +Age 63 month 4 you have $1189720.42 +Age 63 month 5 you have $1195181.87 +Age 63 month 6 you have $1200663.80 +Age 63 month 7 you have $1206166.29 +Age 63 month 8 you have $1211689.41 +Age 63 month 9 you have $1217233.25 +Age 63 month 10 you have $1222797.87 +Age 63 month 11 you have $1228383.36 +Age 64 month 0 you have $1233989.80 +Age 64 month 1 you have $1239617.26 +Age 64 month 2 you have $1245265.83 +Age 64 month 3 you have $1250935.58 +Age 64 month 4 you have $1256626.58 +Age 64 month 5 you have $1262338.93 +Age 64 month 6 you have $1268072.71 +Age 64 month 7 you have $1273827.98 +Age 64 month 8 you have $1279604.83 +Age 64 month 9 you have $1285403.35 +Age 64 month 10 you have $1291223.61 +Age 64 month 11 you have $1297065.70 +Age 65 month 0 you have $1302929.70 +Age 65 month 1 you have $1308815.68 +Age 65 month 2 you have $1314723.74 +Age 65 month 3 you have $1320653.96 +Age 65 month 4 you have $1326606.41 +Age 65 month 5 you have $1332581.18 +Age 65 month 6 you have $1338578.36 +Age 65 month 7 you have $1344598.03 +Age 65 month 8 you have $1350640.27 +Age 65 month 9 you have $1356705.18 +Age 65 month 10 you have $1362792.82 +Age 65 month 11 you have $1368903.29 +Age 66 month 0 you have $1375036.68 +Age 66 month 1 you have $1381193.07 +Age 66 month 2 you have $1387372.54 +Age 66 month 3 you have $1393575.19 +Age 66 month 4 you have $1399801.10 +Age 66 month 5 you have $1406050.35 +Age 66 month 6 you have $1412323.04 +Age 66 month 7 you have $1418619.25 +Age 66 month 8 you have $1424939.07 +Age 66 month 9 you have $1431282.59 +Age 66 month 10 you have $1437649.90 +Age 66 month 11 you have $1444041.09 +Age 67 month 0 you have $1450456.25 +Age 67 month 1 you have $1456895.46 +Age 67 month 2 you have $1463358.81 +Age 67 month 3 you have $1469846.41 +Age 67 month 4 you have $1476358.33 +Age 67 month 5 you have $1482894.68 +Age 67 month 6 you have $1489455.53 +Age 67 month 7 you have $1496040.99 +Age 67 month 8 you have $1502651.14 +Age 67 month 9 you have $1509286.09 +Age 67 month 10 you have $1515945.91 +Age 67 month 11 you have $1522630.71 +Age 68 month 0 you have $1529340.57 +Age 68 month 1 you have $1526615.02 +Age 68 month 2 you have $1523887.20 +Age 68 month 3 you have $1521157.11 +Age 68 month 4 you have $1518424.74 +Age 68 month 5 you have $1515690.09 +Age 68 month 6 you have $1512953.17 +Age 68 month 7 you have $1510213.96 +Age 68 month 8 you have $1507472.47 +Age 68 month 9 you have $1504728.70 +Age 68 month 10 you have $1501982.64 +Age 68 month 11 you have $1499234.29 +Age 69 month 0 you have $1496483.65 +Age 69 month 1 you have $1493730.72 +Age 69 month 2 you have $1490975.50 +Age 69 month 3 you have $1488217.98 +Age 69 month 4 you have $1485458.16 +Age 69 month 5 you have $1482696.04 +Age 69 month 6 you have $1479931.62 +Age 69 month 7 you have $1477164.90 +Age 69 month 8 you have $1474395.87 +Age 69 month 9 you have $1471624.53 +Age 69 month 10 you have $1468850.89 +Age 69 month 11 you have $1466074.93 +Age 70 month 0 you have $1463296.66 +Age 70 month 1 you have $1460516.07 +Age 70 month 2 you have $1457733.17 +Age 70 month 3 you have $1454947.95 +Age 70 month 4 you have $1452160.40 +Age 70 month 5 you have $1449370.54 +Age 70 month 6 you have $1446578.35 +Age 70 month 7 you have $1443783.83 +Age 70 month 8 you have $1440986.98 +Age 70 month 9 you have $1438187.80 +Age 70 month 10 you have $1435386.29 +Age 70 month 11 you have $1432582.45 +Age 71 month 0 you have $1429776.27 +Age 71 month 1 you have $1426967.75 +Age 71 month 2 you have $1424156.89 +Age 71 month 3 you have $1421343.68 +Age 71 month 4 you have $1418528.14 +Age 71 month 5 you have $1415710.24 +Age 71 month 6 you have $1412890.00 +Age 71 month 7 you have $1410067.41 +Age 71 month 8 you have $1407242.47 +Age 71 month 9 you have $1404415.17 +Age 71 month 10 you have $1401585.52 +Age 71 month 11 you have $1398753.50 +Age 72 month 0 you have $1395919.13 +Age 72 month 1 you have $1393082.40 +Age 72 month 2 you have $1390243.30 +Age 72 month 3 you have $1387401.84 +Age 72 month 4 you have $1384558.00 +Age 72 month 5 you have $1381711.80 +Age 72 month 6 you have $1378863.23 +Age 72 month 7 you have $1376012.28 +Age 72 month 8 you have $1373158.96 +Age 72 month 9 you have $1370303.26 +Age 72 month 10 you have $1367445.18 +Age 72 month 11 you have $1364584.71 +Age 73 month 0 you have $1361721.87 +Age 73 month 1 you have $1358856.64 +Age 73 month 2 you have $1355989.02 +Age 73 month 3 you have $1353119.01 +Age 73 month 4 you have $1350246.61 +Age 73 month 5 you have $1347371.81 +Age 73 month 6 you have $1344494.62 +Age 73 month 7 you have $1341615.03 +Age 73 month 8 you have $1338733.05 +Age 73 month 9 you have $1335848.66 +Age 73 month 10 you have $1332961.87 +Age 73 month 11 you have $1330072.67 +Age 74 month 0 you have $1327181.06 +Age 74 month 1 you have $1324287.04 +Age 74 month 2 you have $1321390.62 +Age 74 month 3 you have $1318491.78 +Age 74 month 4 you have $1315590.52 +Age 74 month 5 you have $1312686.84 +Age 74 month 6 you have $1309780.75 +Age 74 month 7 you have $1306872.23 +Age 74 month 8 you have $1303961.29 +Age 74 month 9 you have $1301047.93 +Age 74 month 10 you have $1298132.14 +Age 74 month 11 you have $1295213.91 +Age 75 month 0 you have $1292293.26 +Age 75 month 1 you have $1289370.17 +Age 75 month 2 you have $1286444.64 +Age 75 month 3 you have $1283516.68 +Age 75 month 4 you have $1280586.28 +Age 75 month 5 you have $1277653.43 +Age 75 month 6 you have $1274718.14 +Age 75 month 7 you have $1271780.41 +Age 75 month 8 you have $1268840.23 +Age 75 month 9 you have $1265897.59 +Age 75 month 10 you have $1262952.51 +Age 75 month 11 you have $1260004.97 +Age 76 month 0 you have $1257054.97 +Age 76 month 1 you have $1254102.52 +Age 76 month 2 you have $1251147.60 +Age 76 month 3 you have $1248190.23 +Age 76 month 4 you have $1245230.39 +Age 76 month 5 you have $1242268.08 +Age 76 month 6 you have $1239303.30 +Age 76 month 7 you have $1236336.05 +Age 76 month 8 you have $1233366.33 +Age 76 month 9 you have $1230394.14 +Age 76 month 10 you have $1227419.47 +Age 76 month 11 you have $1224442.32 +Age 77 month 0 you have $1221462.69 +Age 77 month 1 you have $1218480.57 +Age 77 month 2 you have $1215495.97 +Age 77 month 3 you have $1212508.88 +Age 77 month 4 you have $1209519.31 +Age 77 month 5 you have $1206527.24 +Age 77 month 6 you have $1203532.68 +Age 77 month 7 you have $1200535.63 +Age 77 month 8 you have $1197536.07 +Age 77 month 9 you have $1194534.02 +Age 77 month 10 you have $1191529.46 +Age 77 month 11 you have $1188522.40 +Age 78 month 0 you have $1185512.84 +Age 78 month 1 you have $1182500.77 +Age 78 month 2 you have $1179486.18 +Age 78 month 3 you have $1176469.09 +Age 78 month 4 you have $1173449.48 +Age 78 month 5 you have $1170427.35 +Age 78 month 6 you have $1167402.71 +Age 78 month 7 you have $1164375.55 +Age 78 month 8 you have $1161345.86 +Age 78 month 9 you have $1158313.65 +Age 78 month 10 you have $1155278.91 +Age 78 month 11 you have $1152241.64 +Age 79 month 0 you have $1149201.84 +Age 79 month 1 you have $1146159.51 +Age 79 month 2 you have $1143114.64 +Age 79 month 3 you have $1140067.24 +Age 79 month 4 you have $1137017.30 +Age 79 month 5 you have $1133964.81 +Age 79 month 6 you have $1130909.78 +Age 79 month 7 you have $1127852.21 +Age 79 month 8 you have $1124792.08 +Age 79 month 9 you have $1121729.41 +Age 79 month 10 you have $1118664.18 +Age 79 month 11 you have $1115596.40 +Age 80 month 0 you have $1112526.07 +Age 80 month 1 you have $1109453.17 +Age 80 month 2 you have $1106377.72 +Age 80 month 3 you have $1103299.70 +Age 80 month 4 you have $1100219.11 +Age 80 month 5 you have $1097135.96 +Age 80 month 6 you have $1094050.24 +Age 80 month 7 you have $1090961.95 +Age 80 month 8 you have $1087871.09 +Age 80 month 9 you have $1084777.65 +Age 80 month 10 you have $1081681.63 +Age 80 month 11 you have $1078583.03 +Age 81 month 0 you have $1075481.85 +Age 81 month 1 you have $1072378.08 +Age 81 month 2 you have $1069271.73 +Age 81 month 3 you have $1066162.79 +Age 81 month 4 you have $1063051.26 +Age 81 month 5 you have $1059937.14 +Age 81 month 6 you have $1056820.42 +Age 81 month 7 you have $1053701.10 +Age 81 month 8 you have $1050579.19 +Age 81 month 9 you have $1047454.67 +Age 81 month 10 you have $1044327.55 +Age 81 month 11 you have $1041197.82 +Age 82 month 0 you have $1038065.48 +Age 82 month 1 you have $1034930.54 +Age 82 month 2 you have $1031792.98 +Age 82 month 3 you have $1028652.81 +Age 82 month 4 you have $1025510.02 +Age 82 month 5 you have $1022364.61 +Age 82 month 6 you have $1019216.58 +Age 82 month 7 you have $1016065.93 +Age 82 month 8 you have $1012912.65 +Age 82 month 9 you have $1009756.74 +Age 82 month 10 you have $1006598.21 +Age 82 month 11 you have $1003437.04 +Age 83 month 0 you have $1000273.24 +Age 83 month 1 you have $997106.80 +Age 83 month 2 you have $993937.72 +Age 83 month 3 you have $990766.00 +Age 83 month 4 you have $987591.64 +Age 83 month 5 you have $984414.63 +Age 83 month 6 you have $981234.98 +Age 83 month 7 you have $978052.68 +Age 83 month 8 you have $974867.72 +Age 83 month 9 you have $971680.11 +Age 83 month 10 you have $968489.84 +Age 83 month 11 you have $965296.92 +Age 84 month 0 you have $962101.33 +Age 84 month 1 you have $958903.08 +Age 84 month 2 you have $955702.17 +Age 84 month 3 you have $952498.59 +Age 84 month 4 you have $949292.34 +Age 84 month 5 you have $946083.41 +Age 84 month 6 you have $942871.82 +Age 84 month 7 you have $939657.54 +Age 84 month 8 you have $936440.59 +Age 84 month 9 you have $933220.96 +Age 84 month 10 you have $929998.64 +Age 84 month 11 you have $926773.64 +Age 85 month 0 you have $923545.95 +Age 85 month 1 you have $920315.57 +Age 85 month 2 you have $917082.50 +Age 85 month 3 you have $913846.74 +Age 85 month 4 you have $910608.28 +Age 85 month 5 you have $907367.12 +Age 85 month 6 you have $904123.26 +Age 85 month 7 you have $900876.69 +Age 85 month 8 you have $897627.42 +Age 85 month 9 you have $894375.45 +Age 85 month 10 you have $891120.76 +Age 85 month 11 you have $887863.36 +Age 86 month 0 you have $884603.25 +Age 86 month 1 you have $881340.42 +Age 86 month 2 you have $878074.87 +Age 86 month 3 you have $874806.59 +Age 86 month 4 you have $871535.60 +Age 86 month 5 you have $868261.88 +Age 86 month 6 you have $864985.43 +Age 86 month 7 you have $861706.25 +Age 86 month 8 you have $858424.34 +Age 86 month 9 you have $855139.69 +Age 86 month 10 you have $851852.31 +Age 86 month 11 you have $848562.19 +Age 87 month 0 you have $845269.32 +Age 87 month 1 you have $841973.71 +Age 87 month 2 you have $838675.36 +Age 87 month 3 you have $835374.26 +Age 87 month 4 you have $832070.40 +Age 87 month 5 you have $828763.79 +Age 87 month 6 you have $825454.43 +Age 87 month 7 you have $822142.31 +Age 87 month 8 you have $818827.43 +Age 87 month 9 you have $815509.78 +Age 87 month 10 you have $812189.37 +Age 87 month 11 you have $808866.20 +Age 88 month 0 you have $805540.25 +Age 88 month 1 you have $802211.54 +Age 88 month 2 you have $798880.05 +Age 88 month 3 you have $795545.78 +Age 88 month 4 you have $792208.73 +Age 88 month 5 you have $788868.91 +Age 88 month 6 you have $785526.30 +Age 88 month 7 you have $782180.90 +Age 88 month 8 you have $778832.72 +Age 88 month 9 you have $775481.75 +Age 88 month 10 you have $772127.98 +Age 88 month 11 you have $768771.42 +Age 89 month 0 you have $765412.07 +Age 89 month 1 you have $762049.91 +Age 89 month 2 you have $758684.95 +Age 89 month 3 you have $755317.19 +Age 89 month 4 you have $751946.62 +Age 89 month 5 you have $748573.24 +Age 89 month 6 you have $745197.05 +Age 89 month 7 you have $741818.05 +Age 89 month 8 you have $738436.23 +Age 89 month 9 you have $735051.60 +Age 89 month 10 you have $731664.14 +Age 89 month 11 you have $728273.86 +Age 90 month 0 you have $724880.75 +Age 90 month 1 you have $721484.82 +Age 90 month 2 you have $718086.06 +Age 90 month 3 you have $714684.46 +Age 90 month 4 you have $711280.03 +Age 90 month 5 you have $707872.77 +Age 90 month 6 you have $704462.66 +Age 90 month 7 you have $701049.71 +Age 90 month 8 you have $697633.92 +Age 90 month 9 you have $694215.28 +Age 90 month 10 you have $690793.80 +Age 90 month 11 you have $687369.46 +Age 91 month 0 you have $683942.27 +Age 91 month 1 you have $680512.22 +Age 91 month 2 you have $677079.31 +Age 91 month 3 you have $673643.54 +Age 91 month 4 you have $670204.91 +Age 91 month 5 you have $666763.42 +Age 91 month 6 you have $663319.05 +Age 91 month 7 you have $659871.82 +Age 91 month 8 you have $656421.71 +Age 91 month 9 you have $652968.73 +Age 91 month 10 you have $649512.87 +Age 91 month 11 you have $646054.13 +Age 92 month 0 you have $642592.51 +Age 92 month 1 you have $639128.00 +Age 92 month 2 you have $635660.61 +Age 92 month 3 you have $632190.33 +Age 92 month 4 you have $628717.15 +Age 92 month 5 you have $625241.08 +Age 92 month 6 you have $621762.12 +Age 92 month 7 you have $618280.25 +Age 92 month 8 you have $614795.49 +Age 92 month 9 you have $611307.82 +Age 92 month 10 you have $607817.24 +Age 92 month 11 you have $604323.75 +Age 93 month 0 you have $600827.36 +Age 93 month 1 you have $597328.05 +Age 93 month 2 you have $593825.82 +Age 93 month 3 you have $590320.68 +Age 93 month 4 you have $586812.61 +Age 93 month 5 you have $583301.62 +Age 93 month 6 you have $579787.70 +Age 93 month 7 you have $576270.86 +Age 93 month 8 you have $572751.09 +Age 93 month 9 you have $569228.38 +Age 93 month 10 you have $565702.74 +Age 93 month 11 you have $562174.16 +Age 94 month 0 you have $558642.63 +Age 94 month 1 you have $555108.17 +Age 94 month 2 you have $551570.76 +Age 94 month 3 you have $548030.40 +Age 94 month 4 you have $544487.09 +Age 94 month 5 you have $540940.83 +Age 94 month 6 you have $537391.62 +Age 94 month 7 you have $533839.44 +Age 94 month 8 you have $530284.31 +Age 94 month 9 you have $526726.21 +Age 94 month 10 you have $523165.15 +Age 94 month 11 you have $519601.12 +Age 95 month 0 you have $516034.12 +Age 95 month 1 you have $512464.15 +Age 95 month 2 you have $508891.21 +Age 95 month 3 you have $505315.28 +Age 95 month 4 you have $501736.38 +Age 95 month 5 you have $498154.49 +Age 95 month 6 you have $494569.62 +Age 95 month 7 you have $490981.76 +Age 95 month 8 you have $487390.91 +Age 95 month 9 you have $483797.07 +Age 95 month 10 you have $480200.24 +Age 95 month 11 you have $476600.40 +Age 96 month 0 you have $472997.57 +Age 96 month 1 you have $469391.73 +Age 96 month 2 you have $465782.89 +Age 96 month 3 you have $462171.05 +Age 96 month 4 you have $458556.19 +Age 96 month 5 you have $454938.32 +Age 96 month 6 you have $451317.43 +Age 96 month 7 you have $447693.53 +Age 96 month 8 you have $444066.61 +Age 96 month 9 you have $440436.67 +Age 96 month 10 you have $436803.70 +Age 96 month 11 you have $433167.70 +Age 97 month 0 you have $429528.67 +Age 97 month 1 you have $425886.61 +Age 97 month 2 you have $422241.52 +Age 97 month 3 you have $418593.39 +Age 97 month 4 you have $414942.21 +Age 97 month 5 you have $411288.00 +Age 97 month 6 you have $407630.74 +Age 97 month 7 you have $403970.43 +Age 97 month 8 you have $400307.07 +Age 97 month 9 you have $396640.66 +Age 97 month 10 you have $392971.20 +Age 97 month 11 you have $389298.67 +Age 98 month 0 you have $385623.09 +Age 98 month 1 you have $381944.44 +Age 98 month 2 you have $378262.73 +Age 98 month 3 you have $374577.95 +Age 98 month 4 you have $370890.10 +Age 98 month 5 you have $367199.17 +Age 98 month 6 you have $363505.17 +Age 98 month 7 you have $359808.09 +Age 98 month 8 you have $356107.93 +Age 98 month 9 you have $352404.69 +Age 98 month 10 you have $348698.36 +Age 98 month 11 you have $344988.94 +Age 99 month 0 you have $341276.43 +Age 99 month 1 you have $337560.83 +Age 99 month 2 you have $333842.13 +Age 99 month 3 you have $330120.33 +Age 99 month 4 you have $326395.43 +Age 99 month 5 you have $322667.43 +Age 99 month 6 you have $318936.32 +Age 99 month 7 you have $315202.10 +Age 99 month 8 you have $311464.77 +Age 99 month 9 you have $307724.32 +Age 99 month 10 you have $303980.76 +Age 99 month 11 you have $300234.07 diff --git a/08_testing/README b/08_testing/README new file mode 100644 index 0000000..90b0008 --- /dev/null +++ b/08_testing/README @@ -0,0 +1,32 @@ +In this assignment, you will be black-box testing a few +broken implementations of "isPrime". You will see +that there are four broken implementations of isPrime: + +isPrime-broken1 +isPrime-broken2 +isPrime-broken3 +isPrime-broken4 + +as well as a correct implementation: + +isPrime-correct + +All of these take one command line argument, which is the *integer* +to test for primality. For example, you might run + +$ ./isPrime-correct 3 +3 is prime +$ ./isPrime-correct 4 +4 is not prime + +Your job is to find a test case for each broken implementation which +shows that it is not correct---that is, where its behavior differs +from that of isPrime-correct. Note that we do not expect you to brute +force this task. Think about what types of common errors could occur. + +For each broken program, write the input which breaks the program +into a file called "input.X" where X is 1, 2, 3, or 4 (so input.1 has +the command line argument that shows that isPrime-broken1 is broken). + +Note that isPrime-correct's behavior is considered correct, and +any test case which deviates from it is considered wrong. diff --git a/08_testing/grade.txt b/08_testing/grade.txt new file mode 100644 index 0000000..c331a43 --- /dev/null +++ b/08_testing/grade.txt @@ -0,0 +1,19 @@ +Grading at Mon 29 Nov 2021 01:58:24 AM UTC +################################################# +test input.1: +Your file matched the expected output +input.1 passed +################################################# +test input.2: +Your file matched the expected output +input.2 passed +################################################# +test input.3: +Your file matched the expected output +input.3 passed +################################################# +test input.4: +Your file matched the expected output +input.4 passed + +Overall Grade: A diff --git a/08_testing/input.1 b/08_testing/input.1 new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/08_testing/input.1 @@ -0,0 +1 @@ +1 diff --git a/08_testing/input.2 b/08_testing/input.2 new file mode 100644 index 0000000..a51fa7d --- /dev/null +++ b/08_testing/input.2 @@ -0,0 +1 @@ +2147483647 diff --git a/08_testing/input.3 b/08_testing/input.3 new file mode 100644 index 0000000..a8994dc --- /dev/null +++ b/08_testing/input.3 @@ -0,0 +1 @@ +1a diff --git a/08_testing/input.4 b/08_testing/input.4 new file mode 100644 index 0000000..3a2e3f4 --- /dev/null +++ b/08_testing/input.4 @@ -0,0 +1 @@ +-1 diff --git a/09_testing2/README b/09_testing2/README new file mode 100644 index 0000000..8081bf0 --- /dev/null +++ b/09_testing2/README @@ -0,0 +1,64 @@ +For this assignment, you will continue working on your blackbox testing +skills. However, this time, you will test a slightly more complex program +with more broken implementations. + +You can find the correct implementation of the program at + +/usr/local/l2p/match5/correct-match5 + +This program determines who wins a very simple "card game". This "game" +is played with 5 "cards" per player and 2 players. A "card" in this +game is an ASCII character (so 'x' 'a' '!' '7' '$' etc are all valid cards). +Each player has exactly 5 cards, and the player with the most matching +cards wins. That is, 5 of a kind beats 4 of a kind, which bests 3 of a kind, +which beats a pair, which beats having no matching cards. If both +players have the same number of matching cards (e.g., both have 3 of a kind), +the hand is a tie. There are no tie breakers (so one player has +3 of a kind and the other has 3 of a kind + a pair, the pair does not matter). +The values of the cards don't matter (so three 'a's and three 'b's both tie). + +If you run the correct implementation, you can see the correct behavior: + +As some examples: + +$ /usr/local/l2p/match5/correct-match5 aaaaa bbbbb +Both hands tie: each has five of a kind + +$ /usr/local/l2p/match5/correct-match5 aaaaa bbbbc +Hand 1's five of a kind beats Hand 2's four of a kind + +$ /usr/local/l2p/match5/correct-match5 aaabb bbbbc +Hand 1's three of a kind loses to Hand 2's four of a kind + +If you look in /usr/local/l2p/match5, you will see that there are 296 broken +implementations. Note that you do NOT need to come up with 296 test cases---you +may have one test case which shows that several of these implementations +are broken. + +Furthermore, to help make this testing managable for you, we have provided +run_all.sh, which will read test cases from a file you create called tests.txt, +and run them against all broken implementations. In particular, each line +of tests.txt should be the command line arguments to one invocation of the +program under test. So if you wanted to test the program with the three +examples shown above, you would write the following in tests.txt + +aaaaa bbbbb +aaaaa bbbbc +aaabb bbbbc + +and then each broken program would be run three times, and have its behavior +compared to the correct implementation. If ANY test case in tests.txt identifies +a problem with a particular broken implementation, your test suite has +succeeded for that particular implementation. You need to develop +your test suite so that it identifies the problems with all broken implementations. + + +Lastly, I'll note that each of these broken implementations arises from +making small changes in the correct implementation which could represent +reasonable mistakes in programming (this is called "mutation testing" by +the way). None of these require finding +an obscure "magic bullet" input---they can all be found with a reasonble, +comprehensive test suite. + +You will submit tests.txt for this assignment. + diff --git a/09_testing2/grade.txt b/09_testing2/grade.txt new file mode 100644 index 0000000..41bfbf6 --- /dev/null +++ b/09_testing2/grade.txt @@ -0,0 +1,300 @@ +Grading at Mon 29 Nov 2021 02:07:09 AM UTC +Your test cases identified the problem with match5-000 +Your test cases identified the problem with match5-001 +Your test cases identified the problem with match5-002 +Your test cases identified the problem with match5-003 +Your test cases identified the problem with match5-004 +Your test cases identified the problem with match5-005 +Your test cases identified the problem with match5-006 +Your test cases identified the problem with match5-007 +Your test cases identified the problem with match5-008 +Your test cases identified the problem with match5-009 +Your test cases identified the problem with match5-010 +Your test cases identified the problem with match5-011 +Your test cases identified the problem with match5-012 +Your test cases identified the problem with match5-013 +Your test cases identified the problem with match5-014 +Your test cases identified the problem with match5-015 +Your test cases identified the problem with match5-016 +Your test cases identified the problem with match5-017 +Your test cases identified the problem with match5-018 +Your test cases identified the problem with match5-019 +Your test cases identified the problem with match5-020 +Your test cases identified the problem with match5-021 +Your test cases identified the problem with match5-022 +Your test cases identified the problem with match5-023 +Your test cases identified the problem with match5-024 +Your test cases identified the problem with match5-025 +Your test cases identified the problem with match5-026 +Your test cases identified the problem with match5-027 +Your test cases identified the problem with match5-028 +Your test cases identified the problem with match5-029 +Your test cases identified the problem with match5-030 +Your test cases identified the problem with match5-031 +Your test cases identified the problem with match5-032 +Your test cases identified the problem with match5-033 +Your test cases identified the problem with match5-034 +Your test cases identified the problem with match5-035 +Your test cases identified the problem with match5-036 +Your test cases identified the problem with match5-037 +Your test cases identified the problem with match5-038 +Your test cases identified the problem with match5-039 +Your test cases identified the problem with match5-040 +Your test cases identified the problem with match5-041 +Your test cases identified the problem with match5-042 +Your test cases identified the problem with match5-043 +Your test cases identified the problem with match5-044 +Your test cases identified the problem with match5-045 +Your test cases identified the problem with match5-046 +Your test cases identified the problem with match5-047 +Your test cases identified the problem with match5-048 +Your test cases identified the problem with match5-049 +Your test cases identified the problem with match5-050 +Your test cases identified the problem with match5-051 +Your test cases identified the problem with match5-052 +Your test cases identified the problem with match5-053 +Your test cases identified the problem with match5-054 +Your test cases identified the problem with match5-055 +Your test cases identified the problem with match5-056 +Your test cases identified the problem with match5-057 +Your test cases identified the problem with match5-058 +Your test cases identified the problem with match5-059 +Your test cases identified the problem with match5-060 +Your test cases identified the problem with match5-061 +Your test cases identified the problem with match5-062 +Your test cases identified the problem with match5-063 +Your test cases identified the problem with match5-064 +Your test cases identified the problem with match5-065 +Your test cases identified the problem with match5-066 +Your test cases identified the problem with match5-067 +Your test cases identified the problem with match5-068 +Your test cases identified the problem with match5-069 +Your test cases identified the problem with match5-070 +Your test cases identified the problem with match5-071 +Your test cases identified the problem with match5-072 +Your test cases identified the problem with match5-073 +Your test cases identified the problem with match5-074 +Your test cases identified the problem with match5-075 +Your test cases identified the problem with match5-076 +Your test cases identified the problem with match5-077 +Your test cases identified the problem with match5-078 +Your test cases identified the problem with match5-079 +Your test cases identified the problem with match5-080 +Your test cases identified the problem with match5-081 +Your test cases identified the problem with match5-082 +Your test cases identified the problem with match5-083 +Your test cases identified the problem with match5-084 +Your test cases identified the problem with match5-085 +Your test cases identified the problem with match5-086 +Your test cases identified the problem with match5-087 +Your test cases identified the problem with match5-088 +Your test cases identified the problem with match5-089 +Your test cases identified the problem with match5-090 +Your test cases identified the problem with match5-091 +Your test cases identified the problem with match5-092 +Your test cases identified the problem with match5-093 +Your test cases identified the problem with match5-094 +Your test cases identified the problem with match5-095 +Your test cases identified the problem with match5-096 +Your test cases identified the problem with match5-097 +Your test cases identified the problem with match5-098 +Your test cases identified the problem with match5-099 +Your test cases identified the problem with match5-100 +Your test cases identified the problem with match5-101 +Your test cases identified the problem with match5-102 +Your test cases identified the problem with match5-103 +Your test cases identified the problem with match5-104 +Your test cases identified the problem with match5-105 +Your test cases identified the problem with match5-106 +Your test cases identified the problem with match5-107 +Your test cases identified the problem with match5-108 +Your test cases identified the problem with match5-109 +Your test cases identified the problem with match5-110 +Your test cases identified the problem with match5-111 +Your test cases identified the problem with match5-112 +Your test cases identified the problem with match5-113 +Your test cases identified the problem with match5-114 +Your test cases identified the problem with match5-115 +Your test cases identified the problem with match5-116 +Your test cases identified the problem with match5-117 +Your test cases identified the problem with match5-118 +Your test cases identified the problem with match5-119 +Your test cases identified the problem with match5-120 +Your test cases identified the problem with match5-121 +Your test cases identified the problem with match5-122 +Your test cases identified the problem with match5-123 +Your test cases identified the problem with match5-124 +Your test cases identified the problem with match5-125 +Your test cases identified the problem with match5-126 +Your test cases identified the problem with match5-127 +Your test cases identified the problem with match5-128 +Your test cases identified the problem with match5-129 +Your test cases identified the problem with match5-130 +Your test cases identified the problem with match5-131 +Your test cases identified the problem with match5-132 +Your test cases identified the problem with match5-133 +Your test cases identified the problem with match5-134 +Your test cases identified the problem with match5-135 +Your test cases identified the problem with match5-136 +Your test cases identified the problem with match5-137 +Your test cases identified the problem with match5-138 +Your test cases identified the problem with match5-139 +Your test cases identified the problem with match5-140 +Your test cases identified the problem with match5-141 +Your test cases identified the problem with match5-142 +Your test cases identified the problem with match5-143 +Your test cases identified the problem with match5-144 +Your test cases identified the problem with match5-145 +Your test cases identified the problem with match5-146 +Your test cases identified the problem with match5-147 +Your test cases identified the problem with match5-148 +Your test cases identified the problem with match5-149 +Your test cases identified the problem with match5-150 +Your test cases identified the problem with match5-151 +Your test cases identified the problem with match5-152 +Your test cases identified the problem with match5-153 +Your test cases identified the problem with match5-154 +Your test cases identified the problem with match5-155 +Your test cases identified the problem with match5-156 +Your test cases identified the problem with match5-157 +Your test cases identified the problem with match5-158 +Your test cases identified the problem with match5-159 +Your test cases identified the problem with match5-160 +Your test cases identified the problem with match5-161 +Your test cases identified the problem with match5-162 +Your test cases identified the problem with match5-163 +Your test cases identified the problem with match5-164 +Your test cases identified the problem with match5-165 +Your test cases identified the problem with match5-166 +Your test cases identified the problem with match5-167 +Your test cases identified the problem with match5-168 +Your test cases identified the problem with match5-169 +Your test cases identified the problem with match5-170 +Your test cases identified the problem with match5-171 +Your test cases identified the problem with match5-172 +Your test cases identified the problem with match5-173 +Your test cases identified the problem with match5-174 +Your test cases identified the problem with match5-175 +Your test cases identified the problem with match5-176 +Your test cases identified the problem with match5-177 +Your test cases identified the problem with match5-178 +Your test cases identified the problem with match5-179 +Your test cases identified the problem with match5-180 +Your test cases identified the problem with match5-181 +Your test cases identified the problem with match5-182 +Your test cases identified the problem with match5-183 +Your test cases identified the problem with match5-184 +Your test cases identified the problem with match5-185 +Your test cases identified the problem with match5-186 +Your test cases identified the problem with match5-187 +Your test cases identified the problem with match5-188 +Your test cases identified the problem with match5-189 +Your test cases identified the problem with match5-190 +Your test cases identified the problem with match5-191 +Your test cases identified the problem with match5-192 +Your test cases identified the problem with match5-193 +Your test cases identified the problem with match5-194 +Your test cases identified the problem with match5-195 +Your test cases identified the problem with match5-196 +Your test cases identified the problem with match5-197 +Your test cases identified the problem with match5-198 +Your test cases identified the problem with match5-199 +Your test cases identified the problem with match5-200 +Your test cases identified the problem with match5-201 +Your test cases identified the problem with match5-202 +Your test cases identified the problem with match5-203 +Your test cases identified the problem with match5-204 +Your test cases identified the problem with match5-205 +Your test cases identified the problem with match5-206 +Your test cases identified the problem with match5-207 +Your test cases identified the problem with match5-208 +Your test cases identified the problem with match5-209 +Your test cases identified the problem with match5-210 +Your test cases identified the problem with match5-211 +Your test cases identified the problem with match5-212 +Your test cases identified the problem with match5-213 +Your test cases identified the problem with match5-214 +Your test cases identified the problem with match5-215 +Your test cases identified the problem with match5-216 +Your test cases identified the problem with match5-217 +Your test cases identified the problem with match5-218 +Your test cases identified the problem with match5-219 +Your test cases identified the problem with match5-220 +Your test cases identified the problem with match5-221 +Your test cases identified the problem with match5-222 +Your test cases identified the problem with match5-223 +Your test cases identified the problem with match5-224 +Your test cases identified the problem with match5-225 +Your test cases identified the problem with match5-226 +Your test cases identified the problem with match5-227 +Your test cases identified the problem with match5-228 +Your test cases identified the problem with match5-229 +Your test cases identified the problem with match5-230 +Your test cases identified the problem with match5-231 +Your test cases identified the problem with match5-232 +Your test cases identified the problem with match5-233 +Your test cases identified the problem with match5-234 +Your test cases identified the problem with match5-235 +Your test cases identified the problem with match5-236 +Your test cases identified the problem with match5-237 +Your test cases identified the problem with match5-238 +Your test cases identified the problem with match5-239 +Your test cases identified the problem with match5-240 +Your test cases identified the problem with match5-241 +Your test cases identified the problem with match5-242 +Your test cases identified the problem with match5-243 +Your test cases identified the problem with match5-244 +Your test cases identified the problem with match5-245 +Your test cases identified the problem with match5-246 +Your test cases identified the problem with match5-247 +Your test cases identified the problem with match5-248 +Your test cases identified the problem with match5-249 +Your test cases identified the problem with match5-250 +Your test cases identified the problem with match5-251 +Your test cases identified the problem with match5-252 +Your test cases identified the problem with match5-253 +Your test cases identified the problem with match5-254 +Your test cases identified the problem with match5-255 +Your test cases identified the problem with match5-256 +Your test cases identified the problem with match5-257 +Your test cases identified the problem with match5-258 +Your test cases identified the problem with match5-259 +Your test cases identified the problem with match5-260 +Your test cases identified the problem with match5-261 +Your test cases identified the problem with match5-262 +Your test cases identified the problem with match5-263 +Your test cases identified the problem with match5-264 +Your test cases identified the problem with match5-265 +Your test cases identified the problem with match5-266 +Your test cases identified the problem with match5-267 +Your test cases identified the problem with match5-268 +Your test cases identified the problem with match5-269 +Your test cases identified the problem with match5-270 +Your test cases identified the problem with match5-271 +Your test cases identified the problem with match5-272 +Your test cases identified the problem with match5-273 +Your test cases identified the problem with match5-274 +Your test cases identified the problem with match5-275 +Your test cases identified the problem with match5-276 +Your test cases identified the problem with match5-277 +Your test cases identified the problem with match5-278 +Your test cases identified the problem with match5-279 +Your test cases identified the problem with match5-280 +Your test cases identified the problem with match5-281 +Your test cases identified the problem with match5-282 +Your test cases identified the problem with match5-283 +Your test cases identified the problem with match5-284 +Your test cases identified the problem with match5-285 +Your test cases identified the problem with match5-286 +Your test cases identified the problem with match5-287 +Your test cases identified the problem with match5-288 +Your test cases identified the problem with match5-289 +Your test cases identified the problem with match5-290 +Your test cases identified the problem with match5-291 +Your test cases identified the problem with match5-292 +Your test cases identified the problem with match5-293 +Your test cases identified the problem with match5-294 +Your test cases identified the problem with match5-295 +Your test cases identified the problem with match5-296 + +Overall Grade: PASSED diff --git a/09_testing2/run_all.sh b/09_testing2/run_all.sh new file mode 100755 index 0000000..e62c149 --- /dev/null +++ b/09_testing2/run_all.sh @@ -0,0 +1,33 @@ +#!/bin/bash +run_test(){ + prog="$1" + testfile="$2" + IFS=$'\n' + for line in `cat $testfile` + do + IFS=" " correct=`/usr/local/l2p/match5/correct-match5 $line 2>&1` + IFS=" " broken=`$prog $line 2>&1` + if [ "$broken" != "$correct" ] + then + return 0 + fi + done + return 1 +} + +found=0 +notfound=0 +for i in /usr/local/l2p/match5/match5-* +do + run_test $i tests.txt + x="$?" + if [ "$x" != "0" ] + then + echo "Your test cases did not identify the problem with `basename $i`" + let notfound=${notfound}+1 + else + let found=${found}+1 + fi +done +echo "Test cases identified $found problems" +echo "Test cases failed to identify $notfound problems" diff --git a/09_testing2/tests.txt b/09_testing2/tests.txt new file mode 100644 index 0000000..ca82980 --- /dev/null +++ b/09_testing2/tests.txt @@ -0,0 +1,22 @@ +aaaaa bbbbb +aaaaa bbbbc +aaabb bbbbc +aaaaa aaaaa +aaaa bbbbb +aaaaaa bbbbb +aaaaa bbbb +aaaaa bbbbbb +%%&*( 01234 +aaaaa + +&^%$# *&^%$ +aabbc lmddd +----- ~~~~~ +||||| &&&&& +""""" ''''' +NULL 00000 +aaaab bbbbc ddddd +bbbba bbbba +abbbb abbbb +aabbb acbbb +bbbcc bbbca diff --git a/10_gdb/README b/10_gdb/README new file mode 100644 index 0000000..3044c3c --- /dev/null +++ b/10_gdb/README @@ -0,0 +1,80 @@ +For this assignment, you will be practicing with the basics +of gdb. You will want to use gdb extensively during the rest +of the semester, as it is an incredibly useful tool to gather +information during the debugging process. For now, we +are just going to get started with some basic commands. +Be sure you have done the readings and watched +the video on gdb. + +Enclosed, you will find game.c and the compiled +binary game, for the most boring guessing game +ever. In the first round, the program thinks +of a secret number (it is the same every single time), +and asks you to guess it. You get exactly one try. +Note that it thinks of this number by calling +getSecretNumber, which is not included in the source. + +If you get that right, in the second round, +it thinks of another number. It does this by repeatedly +calling getOtherSN (also not shown in the source) and +passing in different numbers. It combines these results +together, and does some math to combine the results into +"total". Afterwards, it asks you for your guess, +and again, you have one chance. + +Before you proceed, try to "play" the game once by running: + +./game + + +For example, I ran it and guessed 4: +$ ./game +I'm thinking of a number... +What number do you guess? +4 +I'm sorry, that is not right. You lose + +It would be pretty boring to play this game +until you actually guess the right number and win, +but fortunately, that isn't the point. The +point is to practice with gdb. + +In emacs, do + +ESC-x gdb + +Emacs will prompt you for how to run gdb (the default should be fine), +and then give you the gdb prompt. +Use the "start" commmand to begin execution, then use "next" +and "print" to find the secret number for round 1. +When the program prompts you for this number, you should be able +to guess the right one from the information you gathered. + +For round 2, you do not want to step through 5000+ iterations of the +loop, so set a breakpoint after the loop, continue execution until you +reach it, and the print out the variable "total". Now you should +be able to win round 2 instantly as well! + +Once you have found the two secret numbers, create a file called input.txt +and place them in that file, one per line (round 1's secret number +on the first line, and round 2's on the second line). + +You should be able to run + +./game < input.txt + +and "win" automatically. That is, you should see this output (without +having to type anything else): + +$ ./game < input.txt +I'm thinking of a number... +What number do you guess? +Correct! You win round1! +Ok, time for round 2. I have another secret number. +Your guess: +You win round 2 also! + + +When you finish, add input.txt to git, then commit, push, and grade. + + diff --git a/10_gdb/game.c b/10_gdb/game.c new file mode 100644 index 0000000..a7459d3 --- /dev/null +++ b/10_gdb/game.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +int getSecretNumber(void); //prototype, implemented elsewhere. + +int getOtherSN(int which); //prototype, implemented elsewhere. + +int main(void) { + int guessesMade = 0; + int yourGuess; + char buffer[1024]; + int myNumber = getSecretNumber(); + + printf("I'm thinking of a number...\n"); + printf("What number do you guess?\n"); + if(fgets(buffer, 1024, stdin) == NULL) { + printf("Oh no, you are giving up? You lose...\n"); + return EXIT_FAILURE; + } + yourGuess = atoi(buffer); + if(yourGuess != myNumber) { + printf("I'm sorry, that is not right. You lose\n"); + return EXIT_FAILURE; + } + printf("Correct! You win round1!\n"); + + int total = 0; + for (int i = 0; i <= 5678; i++) { + total = total ^ getOtherSN(i); + } + printf("Ok, time for round 2. I have another secret number.\n"); + printf("Your guess:\n"); + if(fgets(buffer, 1024, stdin) == NULL) { + printf("Oh no, you are giving up? You lose...\n"); + return EXIT_FAILURE; + } + yourGuess = atoi(buffer); + if (yourGuess == total) { + printf("You win round 2 also!\n"); + return EXIT_SUCCESS; + } + printf("Sorry, you did not win the second round\n"); + return EXIT_FAILURE; +} diff --git a/10_gdb/grade.txt b/10_gdb/grade.txt new file mode 100644 index 0000000..25bb058 --- /dev/null +++ b/10_gdb/grade.txt @@ -0,0 +1,4 @@ +Grading at Mon 29 Nov 2021 02:12:07 AM UTC +Your file matched the expected output + +Overall Grade: PASSED diff --git a/10_gdb/input.txt b/10_gdb/input.txt new file mode 100644 index 0000000..9bbd0ca --- /dev/null +++ b/10_gdb/input.txt @@ -0,0 +1,3 @@ +464384013 +938257400 + diff --git a/11_read_ptr1/.gitignore b/11_read_ptr1/.gitignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/11_read_ptr1/.gitignore @@ -0,0 +1 @@ +test diff --git a/11_read_ptr1/Makefile b/11_read_ptr1/Makefile new file mode 100644 index 0000000..f337094 --- /dev/null +++ b/11_read_ptr1/Makefile @@ -0,0 +1,2 @@ +test: test.c + gcc -o test -pedantic -std=gnu99 -Wall -Werror test.c diff --git a/11_read_ptr1/README b/11_read_ptr1/README new file mode 100644 index 0000000..6a18875 --- /dev/null +++ b/11_read_ptr1/README @@ -0,0 +1,10 @@ + 1. Execute the code in "test.c" by hand, and write the output + printed to the terminal into a file called "answer.txt" + + 2. Create a Makefile to compile test.c into a program called "test" + + 3. Run test and use its output to check your work. + + 4. Submit your Makefile and your answer.txt file + + diff --git a/11_read_ptr1/answer.txt b/11_read_ptr1/answer.txt new file mode 100644 index 0000000..22c9abe --- /dev/null +++ b/11_read_ptr1/answer.txt @@ -0,0 +1,4 @@ +In f, *a = 3, b = 4 +In g, x = 7, *y = 8 +Back in f, *a = 7, b = 0 +In main: x = 7, y = 4 diff --git a/11_read_ptr1/grade.txt b/11_read_ptr1/grade.txt new file mode 100644 index 0000000..ed181ad --- /dev/null +++ b/11_read_ptr1/grade.txt @@ -0,0 +1,8 @@ +Grading at Sun 10 Oct 2021 12:55:58 AM UTC +Attempting to compile test.c +gcc -o test -pedantic -std=gnu99 -Wall -Werror test.c +compiled +Your file matched the expected output +Your output matched what we expected + +Overall Grade: PASSED diff --git a/11_read_ptr1/test.c b/11_read_ptr1/test.c new file mode 100644 index 0000000..5d91622 --- /dev/null +++ b/11_read_ptr1/test.c @@ -0,0 +1,26 @@ +#include <stdio.h> +#include <stdlib.h> + +void g(int x, int * y) { + printf("In g, x = %d, *y = %d\n", x, *y); + x++; + *y = *y - x; + y = &x; +} + +void f(int * a, int b) { + printf("In f, *a = %d, b = %d\n", *a, b); + *a += b; + b *= 2; + g(*a, &b); + printf("Back in f, *a = %d, b = %d\n", *a, b); +} + + +int main(void) { + int x = 3; + int y = 4; + f(&x, y); + printf("In main: x = %d, y = %d\n", x, y); + return EXIT_SUCCESS; +} diff --git a/12_read_ptr2/.gitignore b/12_read_ptr2/.gitignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/12_read_ptr2/.gitignore @@ -0,0 +1 @@ +test diff --git a/12_read_ptr2/Makefile b/12_read_ptr2/Makefile new file mode 100644 index 0000000..f337094 --- /dev/null +++ b/12_read_ptr2/Makefile @@ -0,0 +1,2 @@ +test: test.c + gcc -o test -pedantic -std=gnu99 -Wall -Werror test.c diff --git a/12_read_ptr2/README b/12_read_ptr2/README new file mode 100644 index 0000000..6a18875 --- /dev/null +++ b/12_read_ptr2/README @@ -0,0 +1,10 @@ + 1. Execute the code in "test.c" by hand, and write the output + printed to the terminal into a file called "answer.txt" + + 2. Create a Makefile to compile test.c into a program called "test" + + 3. Run test and use its output to check your work. + + 4. Submit your Makefile and your answer.txt file + + diff --git a/12_read_ptr2/answer.txt b/12_read_ptr2/answer.txt new file mode 100644 index 0000000..b31f233 --- /dev/null +++ b/12_read_ptr2/answer.txt @@ -0,0 +1,7 @@ +**r = 12 +**s = 80 +x = 92 +*p = -7 +*q = 75 +a = 75 +b = -7 diff --git a/12_read_ptr2/grade.txt b/12_read_ptr2/grade.txt new file mode 100644 index 0000000..b31de05 --- /dev/null +++ b/12_read_ptr2/grade.txt @@ -0,0 +1,8 @@ +Grading at Sun 10 Oct 2021 02:24:23 AM UTC +Attempting to compile test.c +gcc -o test -pedantic -std=gnu99 -Wall -Werror test.c +compiled +Your file matched the expected output +Your output matched what we expected + +Overall Grade: PASSED diff --git a/12_read_ptr2/test.c b/12_read_ptr2/test.c new file mode 100644 index 0000000..ffa4754 --- /dev/null +++ b/12_read_ptr2/test.c @@ -0,0 +1,30 @@ +#include <stdio.h> +#include <stdlib.h> + +int f(int ** r, int ** s) { + int temp = ** r; + int temp2 = **s; + int * z = *r; + *r = *s; + *s = z; + printf("**r = %d\n",**r); + printf("**s = %d\n",**s); + *z += 3; + **s -= 8; + **r -= 19; + return temp + temp2; +} + +int main(void) { + int a = 80; + int b = 12; + int * p = &a; + int * q = &b; + int x = f(&p, &q); + printf("x = %d\n", x); + printf("*p = %d\n", *p); + printf("*q = %d\n", *q); + printf("a = %d\n", a); + printf("b = %d\n", b); + return EXIT_SUCCESS; +} diff --git a/13_read_arr1/.gitignore b/13_read_arr1/.gitignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/13_read_arr1/.gitignore @@ -0,0 +1 @@ +test diff --git a/13_read_arr1/Makefile b/13_read_arr1/Makefile new file mode 100644 index 0000000..c6b178d --- /dev/null +++ b/13_read_arr1/Makefile @@ -0,0 +1,2 @@ +test: test.c + gcc -o test -pedantic -std=gnu99 -Wall -Werror -lm -ggdb3 test.c diff --git a/13_read_arr1/README b/13_read_arr1/README new file mode 100644 index 0000000..bae9732 --- /dev/null +++ b/13_read_arr1/README @@ -0,0 +1,10 @@ + + 1. Execute the code in "test.c" by hand, and write the output + printed to the terminal into a file called "answer.txt" + + 2. Create a Makefile to compile test.c into a program called "test" + + 3. Run test and use its output to check your work. + + 4. Submit your Makefile and your answer.txt file. + diff --git a/13_read_arr1/answer.txt b/13_read_arr1/answer.txt new file mode 100644 index 0000000..08771c6 --- /dev/null +++ b/13_read_arr1/answer.txt @@ -0,0 +1,6 @@ +*p = 5 +Now *p = 16 +anArray[0] = 5 +anArray[1] = 42 +anArray[2] = 9 +anArray[3] = 12 diff --git a/13_read_arr1/grade.txt b/13_read_arr1/grade.txt new file mode 100644 index 0000000..0b31ec9 --- /dev/null +++ b/13_read_arr1/grade.txt @@ -0,0 +1,8 @@ +Grading at Tue 12 Oct 2021 02:57:12 AM UTC +Attempting to compile test.c +gcc -o test -pedantic -std=gnu99 -Wall -Werror -lm -ggdb3 test.c +compiled +Your file matched the expected output +Your output matched what we expected + +Overall Grade: A diff --git a/13_read_arr1/test.c b/13_read_arr1/test.c new file mode 100644 index 0000000..824b502 --- /dev/null +++ b/13_read_arr1/test.c @@ -0,0 +1,21 @@ +#include <stdio.h> +#include <stdlib.h> + + +int main(void) { + int anArray[] = {5,16,33,99}; + int * p = anArray; + printf("*p = %d\n", *p); + p++; + printf("Now *p = %d\n", *p); + int * q = &anArray[3]; + int ** x = &q; + **x = 12; + *x = p; + **x = 42; + q[1] = 9; + for (int i =0; i < 4; i++){ + printf("anArray[%d] = %d\n",i, anArray[i]); + } + return EXIT_SUCCESS; +} diff --git a/14_array_max/.gitignore b/14_array_max/.gitignore new file mode 100644 index 0000000..bdf4bbd --- /dev/null +++ b/14_array_max/.gitignore @@ -0,0 +1 @@ +arrayMax diff --git a/14_array_max/Makefile b/14_array_max/Makefile new file mode 100644 index 0000000..51fb361 --- /dev/null +++ b/14_array_max/Makefile @@ -0,0 +1,2 @@ +arrayMax: arrayMax.c + gcc -o arrayMax -pedantic -std=gnu99 -Wall -Werror arrayMax.c diff --git a/14_array_max/README b/14_array_max/README new file mode 100644 index 0000000..e98f467 --- /dev/null +++ b/14_array_max/README @@ -0,0 +1,16 @@ + 1. Open the provided arrayMax.c file and write + the function: + int * arrayMax(int * array, int n); + which returns a pointer to the largest element + in the array passed in (whose length is n). + If the array has no elements (n is 0), this function + should return NULL. + + 2. Compile and test your code. + We have provided a main function which will print test cases + and your function's answer for them. You should get + 99, -3, 425, NULL, and NULL for the 5 test provided. + + 3. Submit your code. + + diff --git a/14_array_max/arrayMax.c b/14_array_max/arrayMax.c new file mode 100644 index 0000000..5fc5d62 --- /dev/null +++ b/14_array_max/arrayMax.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> + +int * arrayMax(int * array, int n) { + if (n == 0){ + return NULL; + } + int maxInt = array[0]; + int * answer = array; + for (int i = 1; i < n; i++) { + if (array[i] > maxInt) { + maxInt = array[i]; + answer = &array[i]; + } + } + return answer; +} + +void doTest(int * array, int n) { + printf("arrayMax("); + if (array == NULL) { + printf("NULL"); + } + else { + printf("{"); + for (int i =0; i < n; i++) { + printf("%d", array[i]); + if (i < n -1) { + printf(", "); + } + } + printf("}"); + } + printf(", %d) is \n", n); + int * p = arrayMax (array, n); + if (p == NULL) { + printf("NULL\n"); + } + else { + printf("%d\n", *p); + } +} + +int main(void) { + int array1[] = { 77, 33, 19, 99, 42, 6, 27, 4}; + int array2[] = { -3, -42, -99, -1000, -999, -88, -77}; + int array3[] = { 425, 59, -3, 77, 0, 36}; + + doTest (array1, 8); + doTest (array2, 7); + doTest (array3, 6); + doTest (NULL, 0); + doTest (array1, 0); + + return EXIT_SUCCESS; +} diff --git a/14_array_max/grade.txt b/14_array_max/grade.txt new file mode 100644 index 0000000..3b969b3 --- /dev/null +++ b/14_array_max/grade.txt @@ -0,0 +1,21 @@ +Grading at Wed 13 Oct 2021 02:00:59 AM UTC +Attempting to compile arrayMax.c +################################################# +testcase1: +Your file matched the expected output +Your output matched what we expected +Removing your main() and replacing it with our own to run more tests... +################################################# +testcase2: +array size:0 was Correct +################################################# +testcase3: +array size:1 was Correct +################################################# +testcase4: +array size:100 was Correct +################################################# +testcase5: +array size:5000 was Correct + +Overall Grade: A diff --git a/15_tests_subseq/README b/15_tests_subseq/README new file mode 100644 index 0000000..9c98da7 --- /dev/null +++ b/15_tests_subseq/README @@ -0,0 +1,24 @@ +For this assignment, you will be writing testcases for +your next assignment (as usual, the instructions for that assignment +can be found in next-README). + +As usual, one correct and many broken implementations can be found +in /usr/local/l2p/subseq. + +As with power, these are provided as compiled object files, and you +should write a C program (in test-subseq.c) whose main function tests +the maxSeq function. As before, it should exit with EXIT_SUCCESS if all +tests pass, and EXIT_FAILURE if any test fails. Note that you will +need to write the prototype for maxSeq: + + size_t maxSeq(int * array, size_t n); + +in your test-subseq.c file, so that the compiler knows about the +maxSeq function. The correct place to put it is after you #include +any .h files you need, but before any other code you write. + +We have provided run_all.sh to help you run your test cases against +all implementations. + +HINT: Think about how can you can vary not just the values in your array +but the size as well. What about how the values change over time? diff --git a/15_tests_subseq/grade.txt b/15_tests_subseq/grade.txt new file mode 100644 index 0000000..37c5f52 --- /dev/null +++ b/15_tests_subseq/grade.txt @@ -0,0 +1,52 @@ +Grading at Thu 14 Oct 2021 02:32:07 AM UTC +**Testing broken implementation 10 ** +------------------------------------- + + +**Testing broken implementation 11 ** +------------------------------------- + + +**Testing broken implementation 1 ** +------------------------------------- + + +**Testing broken implementation 2 ** +------------------------------------- + + +**Testing broken implementation 3 ** +------------------------------------- + + +**Testing broken implementation 4 ** +------------------------------------- + + +**Testing broken implementation 5 ** +------------------------------------- + + +**Testing broken implementation 6 ** +------------------------------------- + + +**Testing broken implementation 7 ** +------------------------------------- + + +**Testing broken implementation 8 ** +------------------------------------- + + +**Testing broken implementation 9 ** +------------------------------------- + + +**Testing correct implementation ** +------------------------------------- + + +All test programs were handled correctly + +Overall Grade: PASSED diff --git a/15_tests_subseq/next-README b/15_tests_subseq/next-README new file mode 100644 index 0000000..73a18f8 --- /dev/null +++ b/15_tests_subseq/next-README @@ -0,0 +1,31 @@ + + 1. Create a file called maxSeq.c and write the function: + size_t maxSeq(int * array, size_t n); + + which returns the length of the maximum increasing contiguous + subsequence in the array. The parameter n specifies the length + of the array For example, if the array passed in were + + { 1, 2, 1, 3, 5, 7, 2, 4, 6, 9} + + this function would return 4 because the longest sequence + of (strictly) increasing numbers in that array is 1, 3, 5, 7 + which has length 4. Note that 1,3,5,7,9 is an increasing + subsequence, but is not contiguous (finding discontiguous + ones efficiently takes techniques we haven't learned yet). + + Note that the subseqence does not need to increase at a + constant rate (or follow any other pattern besides being strictly + increasing). 2, 4, 67, 93, 94, 102 would be a valid increasing + sequence of length 6. + + +2. Compile and test your code using the test-subseq.c you wrote + previously. (as before, compile the .c files separately, and link + them together). + +3. Submit your code for maxSeq.c + + +Hint: + Can you abstract a complex step out into a simple function?
\ No newline at end of file diff --git a/15_tests_subseq/run_all.sh b/15_tests_subseq/run_all.sh new file mode 100755 index 0000000..33e763d --- /dev/null +++ b/15_tests_subseq/run_all.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +for i in /usr/local/l2p/subseq/subseq*.o +do + test=`basename $i | sed 's/subseq//' | sed 's/.o//'` + if [ "$test" == "" ] + then + echo "**Testing correct implementation **" + else + echo "**Testing broken implementation ${test} **" + fi + echo "-------------------------------------" + echo "" + + gcc -o test-subseq test-subseq.c $i + if [ "$?" != "0" ] + then + echo "Could not compile test-subseq.c with $i" > /dev/stderr + exit 1 + fi + ./test-subseq + if [ "$?" != 0 ] + then + if [ "$test" == "" ] + then + echo "Your test program falsely failed the correct implementation!" > /dev/stderr + exit 1 + fi + else + if [ "$test" != "" ] + then + echo "Your test program did not identify $i as broken!" > /dev/stderr + exit 1 + fi + fi + echo "" +done diff --git a/15_tests_subseq/test-subseq b/15_tests_subseq/test-subseq Binary files differnew file mode 100755 index 0000000..c1cc872 --- /dev/null +++ b/15_tests_subseq/test-subseq diff --git a/15_tests_subseq/test-subseq.c b/15_tests_subseq/test-subseq.c new file mode 100644 index 0000000..b239cc9 --- /dev/null +++ b/15_tests_subseq/test-subseq.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +size_t maxSeq(int * array, size_t n); + +int main(void) { + if (maxSeq(NULL, 0)) { + return EXIT_FAILURE; + } + + int array1[] = {1, 2, 3, 2}; + int array2[] = {2, -3, 5, 6, 8}; + int array3[] = {5}; + int array4[] = {2, 4, 3, 6, 10, 15, -1, 7, 8, 2}; + int array5[] = {-2}; + int array6[] = {2,2,2,3}; + + if (maxSeq(array1, 0)) { + return EXIT_FAILURE; + } + if (maxSeq(array1, 4) != 3) { + return EXIT_FAILURE; + } + if (maxSeq(array2, 5) != 4) { + return EXIT_FAILURE; + } + if (maxSeq(array3, 1) != 1) { + return EXIT_FAILURE; + } + if (maxSeq(array4, 10) != 4) { + return EXIT_FAILURE; + } + if (maxSeq(array5, 1) != 1) { + return EXIT_FAILURE; + } + if (maxSeq(array6, 4) != 2) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/16_subseq/.gitignore b/16_subseq/.gitignore new file mode 100644 index 0000000..f721019 --- /dev/null +++ b/16_subseq/.gitignore @@ -0,0 +1,2 @@ +maxSeq +Makefile diff --git a/16_subseq/README b/16_subseq/README new file mode 100644 index 0000000..9966603 --- /dev/null +++ b/16_subseq/README @@ -0,0 +1,34 @@ + + 1. Create a file called maxSeq.c and write the function: + size_t maxSeq(int * array, size_t n); + + which returns the length of the maximum increasing contiguous + subsequence in the array. The parameter n specifies the length + of the array For example, if the array passed in were + + { 1, 2, 1, 3, 5, 7, 2, 4, 6, 9} + + this function would return 4 because the longest sequence + of (strictly) increasing numbers in that array is 1, 3, 5, 7 + which has length 4. Note that 1,3,5,7,9 is an increasing + subsequence, but is not contiguous (finding discontiguous + ones efficiently takes techniques we haven't learned yet). + + Note that the subseqence does not need to increase at a + constant rate (or follow any other pattern besides being strictly + increasing). 2, 4, 67, 93, 94, 102 would be a valid increasing + sequence of length 6. + + Also note that the series consisting of one element is considered an + increasing sequence of length 1. + + +2. Compile and test your code using the test-subseq.c you wrote + previously. (as before, compile the .c files separately, and link + them together). + +3. Submit your code for maxSeq.c + + +Hint: + Can you abstract a complex step out into a simple function? diff --git a/16_subseq/grade.txt b/16_subseq/grade.txt new file mode 100644 index 0000000..05a9ca8 --- /dev/null +++ b/16_subseq/grade.txt @@ -0,0 +1,17 @@ +Grading at Thu 14 Oct 2021 09:19:34 PM UTC +Attempting to compile maxSeq.c +Linking your object file with our test main +################################################# +testcase2: +array size:0 was Correct +################################################# +testcase3: +array size:1 was Correct +################################################# +testcase4: +array size:100 was Correct +################################################# +testcase5: +array size:5000 was Correct + +Overall Grade: A diff --git a/16_subseq/maxSeq.c b/16_subseq/maxSeq.c new file mode 100644 index 0000000..da03171 --- /dev/null +++ b/16_subseq/maxSeq.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <stdlib.h> + +size_t maxSeq(int * array, size_t n) { + if (n == 0) { + return 0; + } + size_t longest_streak_length = 1; + size_t running_streak_length = 1; + int temp = array[0]; + + for (size_t i = 1; i < n; i++) { + if (array[i] > temp) { + running_streak_length++; + if (running_streak_length > longest_streak_length) { + longest_streak_length = running_streak_length; + } + } else { + running_streak_length = 1; + } + temp = array[i]; + } + return longest_streak_length; + +} + + +//int main(void) { +// if (maxSeq(NULL, 0)) { +// return EXIT_FAILURE; +// } +// +// int array1[] = {1, 2, 3, 2}; +// int array2[] = {2, -3, 5, 6, 8}; +// int array3[] = {5}; +// int array4[] = {2, 4, 3, 6, 10, 15, -1, 7, 8, 2}; +// int array5[] = {-2}; +// int array6[] = {2,2,2,3}; +// +// if (maxSeq(array1, 0)) { +// printf("not good!\n"); +// return EXIT_FAILURE; +// } +// if (maxSeq(array1, 4) != 3) { +// printf("not good!\n"); +// return EXIT_FAILURE; +// } +// if (maxSeq(array2, 5) != 4) { +// printf("not good!\n"); +// return EXIT_FAILURE; +// } +// if (maxSeq(array3, 1) != 1) { +// printf("not good!\n"); +// return EXIT_FAILURE; +// } +// if (maxSeq(array4, 10) != 4) { +// printf("not good!\n"); +// return EXIT_FAILURE; +// } +// if (maxSeq(array5, 1) != 1) { +// printf("not good!\n"); +// return EXIT_FAILURE; +// } +// if (maxSeq(array6, 4) != 2) { +// printf("not good!\n"); +// return EXIT_FAILURE; +// } +// +// printf("good!\n"); +// return EXIT_SUCCESS; +//} diff --git a/17_read_arr2/.gitignore b/17_read_arr2/.gitignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/17_read_arr2/.gitignore @@ -0,0 +1 @@ +test diff --git a/17_read_arr2/Makefile b/17_read_arr2/Makefile new file mode 100644 index 0000000..f337094 --- /dev/null +++ b/17_read_arr2/Makefile @@ -0,0 +1,2 @@ +test: test.c + gcc -o test -pedantic -std=gnu99 -Wall -Werror test.c diff --git a/17_read_arr2/README b/17_read_arr2/README new file mode 100644 index 0000000..bcdb734 --- /dev/null +++ b/17_read_arr2/README @@ -0,0 +1,12 @@ + 1. Execute the code in "test.c" by hand, and write the output + into a file called "answer.txt" + + Hint: you may need to consult the man pages for functions + that you are not familiar with. + + 2. Create a Makefile to compile test.c into a program called "test" + + 3. Run test and use its output to check your work. + + 4. Submit your Makefile and answer.txt + diff --git a/17_read_arr2/answer.txt b/17_read_arr2/answer.txt new file mode 100644 index 0000000..93250fc --- /dev/null +++ b/17_read_arr2/answer.txt @@ -0,0 +1,8 @@ +p +l +n +a +bannana has nana 3 characters into it! +r +o +fduurw diff --git a/17_read_arr2/grade.txt b/17_read_arr2/grade.txt new file mode 100644 index 0000000..d949c21 --- /dev/null +++ b/17_read_arr2/grade.txt @@ -0,0 +1,8 @@ +Grading at Fri 15 Oct 2021 02:08:49 AM UTC +Attempting to compile test.c +gcc -o test -pedantic -std=gnu99 -Wall -Werror test.c +compiled +Your file matched the expected output +Your output matched what we expected + +Overall Grade: A diff --git a/17_read_arr2/test.c b/17_read_arr2/test.c new file mode 100644 index 0000000..e0b30b0 --- /dev/null +++ b/17_read_arr2/test.c @@ -0,0 +1,27 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define NSTRS 3 +int main(void) { + const char * strs[NSTRS] = {"apple", "bannana", "carrot"}; + + for (int i = 0; i < NSTRS; i++) { + const char * a = strchr(strs[i], 'a'); + a++; + printf("%c\n", *a); + printf("%c\n", a[2]); + a = strstr(strs[i], "nana"); + if (a != NULL) { + printf("%s has %s %ld characters into it!\n", strs[i], a, a - strs[i]); + } + } + const char * ptr = strs[2]; + while (*ptr != '\0') { + char x = *ptr + 3; + printf("%c", x); + ptr++; + } + printf("\n"); + return EXIT_SUCCESS; +} diff --git a/18_reverse_str/.gitignore b/18_reverse_str/.gitignore new file mode 100644 index 0000000..3ddc7c0 --- /dev/null +++ b/18_reverse_str/.gitignore @@ -0,0 +1 @@ +reverse diff --git a/18_reverse_str/Makefile b/18_reverse_str/Makefile new file mode 100644 index 0000000..784a04a --- /dev/null +++ b/18_reverse_str/Makefile @@ -0,0 +1,2 @@ +reverse: reverse.c + gcc -o reverse -pedantic -std=gnu99 -Wall -Werror reverse.c diff --git a/18_reverse_str/README b/18_reverse_str/README new file mode 100644 index 0000000..af46aa6 --- /dev/null +++ b/18_reverse_str/README @@ -0,0 +1,15 @@ +For this problem, you will write the function + + void reverse(char * str) + +in the provided reverse.c file. This function should reverse the string +passed into it (that is, if given "abc", it should change the contents +of that string to read "cba"). Note that this function's return type +is "void"---it modifies the string passed into it in place. + +We have provided a main function which you can use to test your +reverse function (do you recognize the quotations?). The correct +output for your program can be found in reverse_ans.txt, so you can +diff your program's output against it. + +Submit your reverse.c file for grading. diff --git a/18_reverse_str/grade.txt b/18_reverse_str/grade.txt new file mode 100644 index 0000000..594c87c --- /dev/null +++ b/18_reverse_str/grade.txt @@ -0,0 +1,18 @@ +Grading at Sat 16 Oct 2021 01:39:49 AM UTC +Attempting to compile reverse.c +Your file matched the expected output +Your output matched what we expected +Removing your main() and replacing it with our own to run more tests... +################################################# +testcase2: +nullptr################################################# +testcase3: +Your file matched the expected output +################################################# +testcase4: +Your file matched the expected output +################################################# +testcase5: +Your file matched the expected output + +Overall Grade: A diff --git a/18_reverse_str/reverse.c b/18_reverse_str/reverse.c new file mode 100644 index 0000000..bea6e4e --- /dev/null +++ b/18_reverse_str/reverse.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void reverse(char * str) { + if (!str) { + return; + } + size_t string_length = 0; + char temp; + const char * ptr = str; + // Find string length + while (*ptr != '\0') { + string_length++; + ptr++; + } + + for (size_t i = 0; i < (string_length/2); i++) { + temp = str[i]; + str[i] = str[string_length-1-i]; + str[string_length-1-i] = temp; + } +} + +int main(void) { + char str0[] = ""; + char str1[] = "123"; + char str2[] = "abcd"; + char str3[] = "Captain's log, Stardate 42523.7"; + char str4[] = "Hello, my name is Inigo Montoya."; + char str5[] = "You can be my wingman anyday!"; + char str6[] = "Executor Selendis! Unleash the full power of your forces! There may be no tomorrow!"; + char * array[] = {str0, str1, str2, str3, str4, str5, str6}; + for (int i = 0; i < 7; i++) { + reverse(array[i]); + printf("%s\n", array[i]); + } + return EXIT_SUCCESS; +} diff --git a/18_reverse_str/reverse_ans.txt b/18_reverse_str/reverse_ans.txt new file mode 100644 index 0000000..7b70ecc --- /dev/null +++ b/18_reverse_str/reverse_ans.txt @@ -0,0 +1,7 @@ + +321 +dcba +7.32524 etadratS ,gol s'niatpaC +.ayotnoM oginI si eman ym ,olleH +!yadyna namgniw ym eb nac uoY +!worromot on eb yam erehT !secrof ruoy fo rewop lluf eht hsaelnU !sidneleS rotucexE diff --git a/19_bits_arr/.gitignore b/19_bits_arr/.gitignore new file mode 100644 index 0000000..1be726c --- /dev/null +++ b/19_bits_arr/.gitignore @@ -0,0 +1 @@ +numToBits diff --git a/19_bits_arr/Makefile b/19_bits_arr/Makefile new file mode 100644 index 0000000..b0fe89a --- /dev/null +++ b/19_bits_arr/Makefile @@ -0,0 +1,2 @@ +numToBits: numToBits.c + gcc -o numToBits -pedantic -std=gnu99 -Wall -Werror numToBits.c diff --git a/19_bits_arr/README b/19_bits_arr/README new file mode 100644 index 0000000..019d6cf --- /dev/null +++ b/19_bits_arr/README @@ -0,0 +1,47 @@ +For this problem, you will be splitting numbers (a 32 bit integer) +up into their individual bits. I have provided a function for you +(getNthBit) which will return a specific bit from a number. For example, +getNthBit(x,0) would return the first (0th) bit, getNthBit(x,1) would +return the next bit, and so on. + +While we normally use "int" for our numbers, we are using "uint32_t". +This is just like "int" except that they are unsigned ints which are +guaranteed to be 32 bits long (by contrast, the normal "int" type +is signed, and there are no guarantees as to how many bits are in it). +We are doing this to be precise and correct: you can use a uint32_t +in much the same way as an int. + +1. Open the file numToBits.c + Find the function + +void numToBits(uint32_t * nums, int nNums, int * bits, int nBits) ; + + This function takes in two arrays: nums (of length nNums), and + bits (of length nBits). This function should: + - Check that there is enough space in bits to hold all the bits + of "nums". Note that each number in "nums" will results in 32 + bits in "bits". If this is not true, your function should + print a message with the format: + "Invalid call to numToBits! nBits is %d, nNums is %d\n", + (where the first %d is nBits, and the second %d is nNums) + then return without doing anything else. + + - Put the individual bits of each number into the "bits" array. + The bits put into this array should be ordered so that the first + 32 bits represent nums[0], the next 32 bits are nums[1], and so + on. Within each number, the most significant bit (bit 31) should + come first, and the least significant bit (bit 0) should come last. + That is, bits[0] should be bit 31 of nums[0], bits[1] should + be bit 30 of nums[0], and so on. + + + + 2. Compile and test your code. + We have provided a main function which will print test cases + and your function's answer for them. We have provided the + correct output in bits_ans.txt + + 3. Submit as usual + + + diff --git a/19_bits_arr/bits_ans.txt b/19_bits_arr/bits_ans.txt new file mode 100644 index 0000000..9702a22 --- /dev/null +++ b/19_bits_arr/bits_ans.txt @@ -0,0 +1,10 @@ + 1 ( 1) => 00000000000000000000000000000001 + 2 ( 2) => 00000000000000000000000000000010 + 3 ( 3) => 00000000000000000000000000000011 + 4 ( 4) => 00000000000000000000000000000100 + 5 ( 5) => 00000000000000000000000000000101 + 15 ( F) => 00000000000000000000000000001111 + 109 ( 6D) => 00000000000000000000000001101101 + 123456789 ( 75BCD15) => 00000111010110111100110100010101 + 987654321 (3ADE68B1) => 00111010110111100110100010110001 +Invalid call to numToBits! nBits is 223, nNums is 7 diff --git a/19_bits_arr/grade.txt b/19_bits_arr/grade.txt new file mode 100644 index 0000000..54495d6 --- /dev/null +++ b/19_bits_arr/grade.txt @@ -0,0 +1,19 @@ +Grading at Wed 20 Oct 2021 02:04:01 AM UTC +Attempting to compile numToBits.c +Your file matched the expected output +Your output matched what we expected +Removing your main() and replacing it with our own to run more tests... +################################################# +testcase2: +array size:0 was Correct +################################################# +testcase3: +array size:1 was Correct +################################################# +testcase4: +array size:100 was Correct +################################################# +testcase5: +array size:5000 was Correct + +Overall Grade: A diff --git a/19_bits_arr/numToBits.c b/19_bits_arr/numToBits.c new file mode 100644 index 0000000..c7538da --- /dev/null +++ b/19_bits_arr/numToBits.c @@ -0,0 +1,70 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +/* + * Helper function that retrieves numbers 'bit' value + * ie: 1's 31st bit is 1 + */ +int getNthBit(uint32_t number, int bit) { + if (bit <0 || bit >= 32) { + printf("Bit %d is invalid\n", bit); + exit (EXIT_FAILURE); + } + return (number & (1<<bit)) != 0; +} + +/* + * + * This function takes in two arrays: nums (of length nNums), and + * bits (of length nBits). This function should: + * + * - Check that there is enough space in bits to hold all the bits + * of "nums". Note that each number in "nums" will results in 32 + * bits in "bits". If this is not true, your function should + * print a message with the format: + * "Invalid call to numToBits! nBits is %d, nNums is %d\n", + * (where the first %d is nBits, and the second %d is nNums) + * then return without doing anything else. + * + * - Put the individual bits of each number into the "bits" array. + * The bits put into this array should be ordered so that the first + * 32 bits represent nums[0], the next 32 bits are nums[1], and so + * on. Within each number, the most significant bit (bit 31) should + * come first, and the least significant bit (bit 0) should come last. + * That is, bits[0] should be bit 31 of nums[0], bits[1] should + * be bit 30 of nums[0], and so on. + */ +void numToBits(uint32_t * nums, int nNums, int * bits, int nBits) { + if (nBits != nNums * 32) { + printf("Invalid call to numToBits! nBits is %d, nNums is %d\n", nBits, nNums); + return; + } + for (int i = 0; i < nNums; i++) { + for (int j = 0; j < 32; j++) { + bits[i*32 + j] = getNthBit(nums[i], 31 - j); + } + } +} + +void doTest(uint32_t * nums, int n) { + int bits[n *32]; + numToBits(nums, n, bits, n*32); + for (int i =0; i < n; i++) { + printf(" %9d (%8X) => ", nums[i], nums[i]); + for (int j = 0; j < 32; j++) { + printf("%d", bits[i*32 + j]); + } + printf("\n"); + } +} + +int main(void) { + uint32_t array1[] = { 1, 2, 3, 4, 5, 15, 109}; + uint32_t array2[] = { 123456789, 987654321 }; + int bits[7*32-1]; + doTest (array1, 7); + doTest (array2, 2); + numToBits(array1,7, bits , 7*32-1); + return EXIT_SUCCESS; +} diff --git a/20_rot_matrix/.gitignore b/20_rot_matrix/.gitignore new file mode 100644 index 0000000..7889cbc --- /dev/null +++ b/20_rot_matrix/.gitignore @@ -0,0 +1 @@ +rotate diff --git a/20_rot_matrix/README b/20_rot_matrix/README new file mode 100644 index 0000000..8e0f90b --- /dev/null +++ b/20_rot_matrix/README @@ -0,0 +1,37 @@ +For this problem, you will be writing a function which +performs a 90 degree clockwise rotation of a 10x10 matrix. +There is nothing special about a 10x10 matrix---we are just +fixing the size so that you can read the input in a future +assignment after you have learned about reading files, +but before you have learned about dynamic memory allocation. + +In particular, you should write + + void rotate(char matrix[10][10]) + +in a file called rotate.c + +This function takes a 10 by 10 matrix of characters and rotates +it 90 degrees clockwise, updating the matrix that was passed in +(remember that arrays are pointers, so you will modify +the array in the frame where it was created). + +As you have not yet learned to read from files, we have +provided a compiled object file, read-matrix.o. This +object file has a main function which will read +the input file (specified as a command line arugments +to your program), call your rotate function, and +then print the result. + +If you compiled your code (and linked with read-matrix.o) +into a program called rotate-matrix, you might run it as + +./rotate-matrix sample.txt + +It will then print the resulting matrix, which in this case +should look like the contents of the file sample.out. +(Remember that you can use > to redirect the output +of a program to a file, and use diff to compare +the contents of two files). + +Note that you do not have to complete the rotation 'in place'. diff --git a/20_rot_matrix/grade.txt b/20_rot_matrix/grade.txt new file mode 100644 index 0000000..dbcb1bd --- /dev/null +++ b/20_rot_matrix/grade.txt @@ -0,0 +1,13 @@ +Grading at Mon 25 Oct 2021 02:26:46 AM UTC +Attempting to compile rotate.c +Running testcase 1 +Your file matched the expected output +testcase1 passed +Running testcase 1 +Your file matched the expected output +testcase1 passed +Running testcase 1 +Your file matched the expected output +testcase1 passed + +Overall Grade: A diff --git a/20_rot_matrix/read-matrix.o b/20_rot_matrix/read-matrix.o Binary files differnew file mode 100644 index 0000000..03b1ca1 --- /dev/null +++ b/20_rot_matrix/read-matrix.o diff --git a/20_rot_matrix/rotate-matrix b/20_rot_matrix/rotate-matrix Binary files differnew file mode 100755 index 0000000..1826b1c --- /dev/null +++ b/20_rot_matrix/rotate-matrix diff --git a/20_rot_matrix/rotate.c b/20_rot_matrix/rotate.c new file mode 100644 index 0000000..79d7f3b --- /dev/null +++ b/20_rot_matrix/rotate.c @@ -0,0 +1,24 @@ +#include <stdio.h> +#include <stdlib.h> + +void rotate(char matrix[10][10]) { + int layer = 0; + char temp1; + char temp2; + char temp3; + + while (layer <= 10/2) { + for (int i = layer; i < 10 - 1 - layer; i++) { + temp1 = matrix[i][10-1-layer]; + temp2 = matrix[10-1-layer][10-1-i]; + temp3 = matrix[10-1-i][layer]; + + matrix[i][10-1-layer] = matrix[layer][i]; + matrix[10-1-layer][10-1-i] = temp1; + matrix[10-1-i][layer] = temp2; + matrix[layer][i] = temp3; + } + layer++; + } + +} diff --git a/20_rot_matrix/sample.out b/20_rot_matrix/sample.out new file mode 100644 index 0000000..6280f8c --- /dev/null +++ b/20_rot_matrix/sample.out @@ -0,0 +1,10 @@ +CH.....*a0 +oe....*.b1 +dl...*..c2 +il..*...d3 +no.*....e4 +gW*.....f5 + o......g6 +Fr......h7 +ul......i8 +nd......j9 diff --git a/20_rot_matrix/sample.txt b/20_rot_matrix/sample.txt new file mode 100644 index 0000000..767b4c3 --- /dev/null +++ b/20_rot_matrix/sample.txt @@ -0,0 +1,10 @@ +0123456789 +abcdefghij +*......... +.*........ +..*....... +...*...... +....*..... +.....*.... +HelloWorld +Coding Fun diff --git a/21_read_rec1/.gitignore b/21_read_rec1/.gitignore new file mode 100644 index 0000000..08001c7 --- /dev/null +++ b/21_read_rec1/.gitignore @@ -0,0 +1,2 @@ +test +Makefile diff --git a/21_read_rec1/README b/21_read_rec1/README new file mode 100644 index 0000000..bebd9b8 --- /dev/null +++ b/21_read_rec1/README @@ -0,0 +1,4 @@ +Execute the code in test.c (by hand). Write the resulting output in a file +called "answer.txt". + +Check your work, and submit as usual. diff --git a/21_read_rec1/answer.txt b/21_read_rec1/answer.txt new file mode 100644 index 0000000..d83d20b --- /dev/null +++ b/21_read_rec1/answer.txt @@ -0,0 +1,4 @@ +a=29, b=7 +a=2, b=9 +a=0, b=2 +297 diff --git a/21_read_rec1/grade.txt b/21_read_rec1/grade.txt new file mode 100644 index 0000000..27dbba2 --- /dev/null +++ b/21_read_rec1/grade.txt @@ -0,0 +1,5 @@ +Grading at Fri 29 Oct 2021 02:12:30 AM UTC +Your file matched the expected output +Your output matched what we expected + +Overall Grade: A diff --git a/21_read_rec1/test.c b/21_read_rec1/test.c new file mode 100644 index 0000000..52fd4e4 --- /dev/null +++ b/21_read_rec1/test.c @@ -0,0 +1,28 @@ +#include <stdio.h> +#include <stdlib.h> + +void printDigits(int x) { + if (x == 0) { + printf("0"); + } + else if (x < 0) { + printf("-"); + printDigits(-x); + } + else { + int a = x/10; + int b = x %10; + printf("a=%d, b=%d\n",a,b); + if (a != 0) { + printDigits(a); + } + printf("%d",b); + } +} + + +int main(void) { + printDigits(297); + printf("\n"); + return EXIT_SUCCESS; +} diff --git a/22_tests_power/.gitignore b/22_tests_power/.gitignore new file mode 100644 index 0000000..2177b03 --- /dev/null +++ b/22_tests_power/.gitignore @@ -0,0 +1 @@ +test_power diff --git a/22_tests_power/README b/22_tests_power/README new file mode 100644 index 0000000..24b1fd9 --- /dev/null +++ b/22_tests_power/README @@ -0,0 +1,46 @@ +For this assignment, you will be writing test cases for + +unsigned power (unsigned x, unsigned y); + +which you will be writing in the next assignment (if you want to read +the instructions for the next assignment, they are provided in next-README). + +Unlike your previous testing assignments, you will be writing +C code to perform the tests. In particular, you should create a file +called test-power.c, which has a main function that performs the tests. + +If the power function passes all test cases, your program should exit +with EXIT_SUCCESS. If the power function fails any test case, your program +should exit with EXIT_FAILURE. Note that your program's exit status is the +return value from main, if main returns. However, you can make your program +exit immediately (wherever it is) by calling exit, passing in either EXIT_SUCCESS +or EXIT_FAILURE, e.g., + +exit(EXIT_FAILURE); + +A few notes about doing this assignment: + (1) You will want to write the prototype for power in your test-power.c + file before you call power, to let the compiler know the signature + of this function, and that the implementation will be found elsewhere. + (2) One correct and many broken implementations of power are provided + in the form of compiled object files in /usr/local/l2p/power/. + Of these, power.o is correct, and the others are broken. + (3) We have provided run_all.sh, which iterates over the object + files in /usr/local/l2p/power, and compiles your test code + and links it with each object file. It will make sure that + the correct implementation passes all of your test cases, + and that each broken implementation fails at least one test case. + (4) When I did this, I wrote the following helper function: + void run_check(unsigned x, unsigned y, unsigned expected_ans) + which calls power, checks that the result is expected_ans, + and if not, prints a message and calls exit(EXIT_FAILURE). + (5) You need your own way to provide the expected answers. + You might come up with them by hand, or find some other + means to produce them. However, there is no direct way + to invoke the correct implementation. + (6) As before, these broken implementations were created by making + small modifications to the correct implementation. All of them + can be found by reasonably crafted tests. The one that is likely + to be the most tricky arises due to the programmer using a variable + of an incorrect type somewhere (hint)... +You should submit test-power.c when you are finished. diff --git a/22_tests_power/grade.txt b/22_tests_power/grade.txt new file mode 100644 index 0000000..594e9a4 --- /dev/null +++ b/22_tests_power/grade.txt @@ -0,0 +1,53 @@ +Grading at Sat 30 Oct 2021 01:44:08 AM UTC +**Testing broken implementation 10 ** +------------------------------------- + + +**Testing broken implementation 11 ** +------------------------------------- + + +**Testing broken implementation 1 ** +------------------------------------- + + +**Testing broken implementation 2 ** +------------------------------------- + + +**Testing broken implementation 3 ** +------------------------------------- + + +**Testing broken implementation 4 ** +------------------------------------- + + +**Testing broken implementation 5 ** +------------------------------------- + + +**Testing broken implementation 6 ** +------------------------------------- + + +**Testing broken implementation 7 ** +------------------------------------- + + +**Testing broken implementation 8 ** +------------------------------------- + + +**Testing broken implementation 9 ** +------------------------------------- + + +**Testing correct implementation ** +------------------------------------- + + +All tests were ok. + + +Overall Grade: PASSED diff --git a/22_tests_power/next-README b/22_tests_power/next-README new file mode 100644 index 0000000..60bc3f1 --- /dev/null +++ b/22_tests_power/next-README @@ -0,0 +1,18 @@ +Write a recursive function unsigned power(unsigned x, unsigned y) which computes x +to the y power. Note that while 0 to the 0 is undefined in mathematics, +we specify that 0 to the 0 shall be 1 for this function. + +Save it into a file called power.c + +You MUST use recursion (no iteration). + + +Use your test-power.c from your previous assignment to test your implementation +of power. You can symlink the file from the previous assignment into this directory: + +ln -s ../22_tests_power/test-power.c ./ + +You should then write a Makefile which will compile each C file separately +to an object file, and like them together. + + diff --git a/22_tests_power/run_all.sh b/22_tests_power/run_all.sh new file mode 100755 index 0000000..68f709d --- /dev/null +++ b/22_tests_power/run_all.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +for i in /usr/local/l2p/power/power*.o +do + test=`basename $i | sed 's/power//' | sed 's/.o//'` + if [ "$test" == "" ] + then + echo "**Testing correct implementation **" + else + echo "**Testing broken implementation ${test} **" + fi + echo "-------------------------------------" + echo "" + gcc -o test-power test-power.c $i + if [ "$?" != "0" ] + then + echo "Could not compile test-power.c with $i" > /dev/stderr + exit 1 + fi + ./test-power + if [ "$?" != 0 ] + then + if [ "$test" == "" ] + then + echo "Your test program falsely failed the correct implementation!" > /dev/stderr + exit 1 + fi + else + if [ "$test" != "" ] + then + echo "Your test program did not identify $i as broken!" > /dev/stderr + exit 1 + fi + fi + echo "" +done diff --git a/22_tests_power/test-power b/22_tests_power/test-power Binary files differnew file mode 100755 index 0000000..8b4cab0 --- /dev/null +++ b/22_tests_power/test-power diff --git a/22_tests_power/test-power.c b/22_tests_power/test-power.c new file mode 100644 index 0000000..95cb54e --- /dev/null +++ b/22_tests_power/test-power.c @@ -0,0 +1,88 @@ +#include <stdio.h> +#include <stdlib.h> + +unsigned power (unsigned x, unsigned y); + +int main() { + unsigned x; + unsigned y; + unsigned ans; + + x = 2; + y = 0; + ans = 1; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + x = 1; + y = 0; + ans = 1; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = 1; + y = 1; + ans = 1; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = 2; + y = 1; + ans = 2; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = 2; + y = 3; + ans = 8; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = 3; + y = 3; + ans = 27; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = 1; + y = 3; + ans = 1; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = 0; + y = 0; + ans = 1; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = 3; + y = 2; + ans = 9; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = -3; + y = 2; + ans = 9; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + x = -2; + y = 3; + ans = -8; + if (ans != power(x, y)) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/23_power_rec/.gitignore b/23_power_rec/.gitignore new file mode 100644 index 0000000..d343b3c --- /dev/null +++ b/23_power_rec/.gitignore @@ -0,0 +1,2 @@ +power +Makefile diff --git a/23_power_rec/README b/23_power_rec/README new file mode 100644 index 0000000..3eb89f0 --- /dev/null +++ b/23_power_rec/README @@ -0,0 +1,19 @@ +Write a recursive function unsigned power(unsigned x, unsigned y) which computes x +to the y power. Note the function signature (unsigned ints). +Note that while 0 to the 0 is undefined in mathematics, +we specify that 0 to the 0 shall be 1 for this function. + +Save it into a file called power.c + +You MUST use recursion (no iteration). + + +Use your test-power.c from your previous assignment to test your implementation +of power. You can symlink the file from the previous assignment into this directory: + +ln -s ../22_tests_power/test-power.c ./ + +You should then write a Makefile which will compile each C file separately +to an object file, and like them together. + + diff --git a/23_power_rec/grade.txt b/23_power_rec/grade.txt new file mode 100644 index 0000000..6ee2635 --- /dev/null +++ b/23_power_rec/grade.txt @@ -0,0 +1,45 @@ +Grading at Sat 30 Oct 2021 02:41:44 AM UTC +Attempting to compile power.c +Attempting to compile power.o with our main +Checking for unsigned power (unsigned x, unsigned y) +Found on line 4, column 1 +Checking for no iteration (do, while, for) +Checking that power is recursive +0^0 was Correct +0^1 was Correct +0^2 was Correct +0^6 was Correct +0^8 was Correct +0^11 was Correct +1^0 was Correct +1^1 was Correct +1^2 was Correct +1^6 was Correct +1^8 was Correct +1^11 was Correct +4^0 was Correct +4^1 was Correct +4^2 was Correct +4^6 was Correct +4^8 was Correct +4^11 was Correct +5^0 was Correct +5^1 was Correct +5^2 was Correct +5^6 was Correct +5^8 was Correct +5^11 was Correct +9^0 was Correct +9^1 was Correct +9^2 was Correct +9^6 was Correct +9^8 was Correct +9^11 was Correct +12^0 was Correct +12^1 was Correct +12^2 was Correct +12^6 was Correct +12^8 was Correct +12^11 was Correct + +Overall Grade: A diff --git a/23_power_rec/power.c b/23_power_rec/power.c new file mode 100644 index 0000000..6be0c74 --- /dev/null +++ b/23_power_rec/power.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#include <stdlib.h> + +unsigned power(unsigned x, unsigned y) { + if (y == 0) { + return 1; + } + if (y == 1) { + return x; + } + return x * power(x, y-1); +} diff --git a/23_power_rec/power.o b/23_power_rec/power.o Binary files differnew file mode 100644 index 0000000..58b2c78 --- /dev/null +++ b/23_power_rec/power.o diff --git a/23_power_rec/test-power b/23_power_rec/test-power Binary files differnew file mode 100755 index 0000000..8c63568 --- /dev/null +++ b/23_power_rec/test-power diff --git a/23_power_rec/test-power.c b/23_power_rec/test-power.c new file mode 120000 index 0000000..7480020 --- /dev/null +++ b/23_power_rec/test-power.c @@ -0,0 +1 @@ +../22_tests_power/test-power.c
\ No newline at end of file diff --git a/24_read_arr3/README b/24_read_arr3/README new file mode 100644 index 0000000..3329694 --- /dev/null +++ b/24_read_arr3/README @@ -0,0 +1,3 @@ +Execute the code in test.c by hand, and place the resulting +output in a file called "answer.txt". +As always, compile and run test.c to check your work, and submit. diff --git a/24_read_arr3/answer.txt b/24_read_arr3/answer.txt new file mode 100644 index 0000000..7057c8e --- /dev/null +++ b/24_read_arr3/answer.txt @@ -0,0 +1,13 @@ +x = 1 +*p = 7 +**q= 4 +1 +2 +3 +99 +5 +6 +42 +8 +9 +*q=9 diff --git a/24_read_arr3/grade.txt b/24_read_arr3/grade.txt new file mode 100644 index 0000000..1f697dc --- /dev/null +++ b/24_read_arr3/grade.txt @@ -0,0 +1,5 @@ +Grading at Sat 20 Nov 2021 09:23:08 PM UTC +Your file matched the expected output +Your output matched what we expected + +Overall Grade: A diff --git a/24_read_arr3/test.c b/24_read_arr3/test.c new file mode 100644 index 0000000..c91dcfb --- /dev/null +++ b/24_read_arr3/test.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> + +int* aFunction(int x, int *p, int ** q) { + printf("x = %d\n", x); + printf("*p = %d\n", *p); + printf("**q= %d\n", **q); + *p = 42; + **q = 99; + *q = &p[1]; + return &p[2]; +} + +int main (void) { + int anArray[3][3] = { {1,2,3}, + {4,5,6}, + {7,8,9} }; + + int * p = anArray[1]; + int * q = aFunction(anArray[0][0], + anArray[2], + &p); + for (int i =0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + printf("%d\n", anArray[i][j]); + } + } + printf("*q=%d\n", *q); + + return EXIT_SUCCESS; +} diff --git a/25_break_encr/Makefile b/25_break_encr/Makefile new file mode 100644 index 0000000..00ce3b5 --- /dev/null +++ b/25_break_encr/Makefile @@ -0,0 +1,4 @@ +CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99 + +breaker: breaker.c + gcc -o breaker breaker.c diff --git a/25_break_encr/Makefile~ b/25_break_encr/Makefile~ new file mode 100644 index 0000000..84bf195 --- /dev/null +++ b/25_break_encr/Makefile~ @@ -0,0 +1,8 @@ +CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99 + +test-eval: deck.o eval.o eval-c4.o test-eval.o deck-c4.o cards.o input.o future.o + gcc -o test-eval -ggdb3 deck.o deck-c4.o eval-c4.o eval.o test-eval.o cards.o input.o future.o +poker: $(GIVEN_OBJS) $(MY_OBJS) + gcc -o poker -ggdb3 $(MY_OBJS) $(GIVEN_OBJS) +clean: + rm -f test poker cards.o my-test-main.o *~ diff --git a/25_break_encr/README b/25_break_encr/README new file mode 100644 index 0000000..fdbc68d --- /dev/null +++ b/25_break_encr/README @@ -0,0 +1,51 @@ + In the last problem, you saw an implementation of a simple +"encryption" program. In this problem, you will write a program +that breaks that encryption---that is, it will take as input +a text file encrypted with the encryption program you just +saw, and prints out the key used to encrypt it! + +Breaking the Caesar Cipher uses a technique called "frequency counting." +This technique relies on the fact that the distribution of letters +in the English alphabet is far from uniform: 'e' is by far the most +common letter (~13%), followed by 't' (9%), and 'a' (8%). Note +that the average frequency is 100/26 ~= 4%. + +This frequency distribution means that if you know (or suspect) +that a file contains English text encrypted with a Caesar Cipher, +you can simply count the frequency of all letters in it, and guess +that the letter which occurs most often is 'e'. Once you know +which letter is 'e', you can backsolve for the key and decrypt +the file. Note that in practice this requires a large enough +text that "the law of large numbers" applies---and while it is +not guaranteed to work, it typically does. + + +Requirements: +============= + + - Your program will take one command line argument: the name + of a file to read as input + - Your program will then perform frequency counting on the letters + in that text file. Your program should ignore all non-letter + characters (those un-modified by your problem 1 program). + - Your program should use the frequency count information to + determine which letter is 'e', and solve for the key. + - On success, your program should print a single line of output to + stdout, which should contain one decimal (base 10) integer (followed by a + newline character). This number should be the encryption key used + on the text. It should be in the range [0,26). That is, the + number you print should obey 0 <= answer < 26. + - On failure, your program should print an appropriate error + message to stderr, then exit with EXIT_FAILURE. + - Provide a Makefile which compiles your program into + a binary called "breaker" +Hints: + - Divide this problem into sub-problems. You should probably + write at least two functions (other than main) to do this. + - Think about how you want to represent your data. An array + might be handy somewhere. + - You may find a function you wrote in a previous classwork + useful for this assignment. Feel free to use or adapt it. + - Remember that everything (including characters) are numbers. + You might look back at the "Read encryption" assignment + to see an example of doing math on characters. diff --git a/25_break_encr/breaker b/25_break_encr/breaker Binary files differnew file mode 100755 index 0000000..00c5a4a --- /dev/null +++ b/25_break_encr/breaker diff --git a/25_break_encr/breaker.c b/25_break_encr/breaker.c new file mode 100644 index 0000000..1f71d2c --- /dev/null +++ b/25_break_encr/breaker.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +size_t max(int * letters, size_t n) { + int maxCount = letters[0]; + int maxElementIndex = 0; + + for (size_t i = 1; i < n; i++) { + if (letters[i] > maxCount) { + maxCount = letters[i]; + maxElementIndex = i; + } + } + return maxElementIndex; +} + +int decrypt(FILE * f) { + int c; + int letters[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + while ((c = fgetc(f)) != EOF) { + if (isalpha(c)) { + c = tolower(c); + c -= 'a'; + letters[c] = letters[c] + 1; + } + } + + size_t maxElement = max(letters, 26); + int ans; + + if (maxElement >= 4) { + ans = maxElement - 4; + } else { + ans = 26 - (4 - maxElement); + } + return ans; +} + +int main(int argc, char ** argv) { + if (argc != 2) { + fprintf(stderr,"Usage: breaker inputFileName\n"); + return EXIT_FAILURE; + } + + FILE * f = fopen(argv[1], "r"); + if (f == NULL) { + perror("Could not open file"); + return EXIT_FAILURE; + } + size_t key = decrypt(f); + + printf("%d\n", key); + + return EXIT_SUCCESS; +} diff --git a/25_break_encr/encrypt b/25_break_encr/encrypt Binary files differnew file mode 100755 index 0000000..a85af2f --- /dev/null +++ b/25_break_encr/encrypt diff --git a/25_break_encr/encryption.c b/25_break_encr/encryption.c new file mode 100644 index 0000000..3e3b6b1 --- /dev/null +++ b/25_break_encr/encryption.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +void encrypt(FILE * f, int key) { + int c; + while ((c = fgetc(f)) != EOF) { + if (isalpha(c)) { + c = tolower(c); + c -= 'a'; + c += key; + c %= 26; + c += 'a'; + } + printf("%c", c); + } +} + +int main(int argc, char ** argv) { + if (argc != 3) { + fprintf(stderr,"Usage: encrypt key inputFileName\n"); + return EXIT_FAILURE; + } + int key = atoi(argv[1]); + if (key == 0) { + fprintf(stderr,"Invalid key (%s): must be a non-zero integer\n", argv[1]); + return EXIT_FAILURE; + } + FILE * f = fopen(argv[2], "r"); + if (f == NULL) { + perror("Could not open file"); + return EXIT_FAILURE; + } + encrypt(f,key); + if (fclose(f) != 0) { + perror("Failed to close the input file!"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/25_break_encr/grade.txt b/25_break_encr/grade.txt new file mode 100644 index 0000000..e7e3b44 --- /dev/null +++ b/25_break_encr/grade.txt @@ -0,0 +1,15 @@ +Grading at Mon 22 Nov 2021 03:21:32 AM UTC +Attempting to compile breaker.c +gcc -o breaker breaker.c +testcase1 passed +################################################# +testcase2: +testcase2 passed +################################################# +testcase3: +testcase3 passed +################################################# +testcase4: +testcase4 passed + +Overall Grade: A diff --git a/25_break_encr/test.txt b/25_break_encr/test.txt new file mode 100644 index 0000000..52d88ee --- /dev/null +++ b/25_break_encr/test.txt @@ -0,0 +1,51 @@ + pu aol shza wyvislt, fvb zhd hu ptwsltluahapvu vm h zptwsl +"lujyfwapvu" wyvnyht. pu aopz wyvislt, fvb dpss dypal h wyvnyht +aoha iylhrz aoha lujyfwapvu---aoha pz, pa dpss ahrl hz puwba +h alea mpsl lujyfwalk dpao aol lujyfwapvu wyvnyht fvb qbza +zhd, huk wypuaz vba aol rlf bzlk av lujyfwa pa! + +iylhrpun aol jhlzhy jpwoly bzlz h aljoupxbl jhsslk "mylxblujf jvbuapun." +aopz aljoupxbl ylsplz vu aol mhja aoha aol kpzaypibapvu vm slaalyz +pu aol lunspzo hswohila pz mhy myvt bupmvyt: 'l' pz if mhy aol tvza +jvttvu slaaly (~13%), mvssvdlk if 'a' (9%), huk 'h' (8%). uval +aoha aol hclyhnl mylxblujf pz 100/26 ~= 4%. + +aopz mylxblujf kpzaypibapvu tlhuz aoha pm fvb ruvd (vy zbzwlja) +aoha h mpsl jvuahpuz lunspzo alea lujyfwalk dpao h jhlzhy jpwoly, +fvb jhu zptwsf jvbua aol mylxblujf vm hss slaalyz pu pa, huk nblzz +aoha aol slaaly dopjo vjjbyz tvza vmalu pz 'l'. vujl fvb ruvd +dopjo slaaly pz 'l', fvb jhu ihjrzvscl mvy aol rlf huk kljyfwa +aol mpsl. uval aoha pu wyhjapjl aopz ylxbpylz h shynl luvbno +alea aoha "aol shd vm shynl ubtilyz" hwwsplz---huk dopsl pa pz +uva nbhyhuallk av dvyr, pa afwpjhssf kvlz. + + +ylxbpyltluaz: +============= + + - fvby wyvnyht dpss ahrl vul jvtthuk spul hynbtlua: aol uhtl + vm h mpsl av ylhk hz puwba + - fvby wyvnyht dpss aolu wlymvyt mylxblujf jvbuapun vu aol slaalyz + pu aoha alea mpsl. fvby wyvnyht zovbsk pnuvyl hss uvu-slaaly + johyhjalyz (aovzl bu-tvkpmplk if fvby wyvislt 1 wyvnyht). + - fvby wyvnyht zovbsk bzl aol mylxblujf jvbua pumvythapvu av + klalytpul dopjo slaaly pz 'l', huk zvscl mvy aol rlf. + - vu zbjjlzz, fvby wyvnyht zovbsk wypua h zpunsl spul vm vbawba av + zakvba, dopjo zovbsk jvuahpu vul kljpths (ihzl 10) pualnly (mvssvdlk if h + uldspul johyhjaly). aopz ubtily zovbsk il aol lujyfwapvu rlf bzlk + vu aol alea. pa zovbsk il pu aol yhunl [0,26). aoha pz, aol + ubtily fvb wypua zovbsk vilf 0 <= huzdly < 26. + - vu mhpsbyl, fvby wyvnyht zovbsk wypua hu hwwyvwyphal lyyvy + tlzzhnl av zaklyy, aolu lepa dpao lepa_mhpsbyl. + - wyvcpkl h thrlmpsl dopjo jvtwpslz fvby wyvnyht puav + h ipuhyf jhsslk "iylhrly" +opuaz: + - kpcpkl aopz wyvislt puav zbi-wyvisltz. fvb zovbsk wyvihisf + dypal ha slhza adv mbujapvuz (vaoly aohu thpu) av kv aopz. + - aopur hivba ovd fvb dhua av ylwylzlua fvby khah. hu hyyhf + tpnoa il ohukf zvtldolyl. + - fvb thf mpuk h mbujapvu fvb dyval pu h wylcpvbz jshzzdvyr + bzlmbs mvy aopz hzzpnutlua. mlls myll av bzl vy hkhwa pa. + - yltltily aoha lclyfaopun (pujsbkpun johyhjalyz) hyl ubtilyz. + fvb tpnoa svvr ihjr ha aol "ylhk lujyfwapvu" hzzpnutlua + av zll hu lehtwsl vm kvpun thao vu johyhjalyz. diff --git a/26_tests_matrix_input/README b/26_tests_matrix_input/README new file mode 100644 index 0000000..e1b7431 --- /dev/null +++ b/26_tests_matrix_input/README @@ -0,0 +1,51 @@ +For this assignment, you will be writing test cases for your next +assignment. As usual, the instructions for the next assignment are +in next-README. + +For this assignment, we have created compiled binaries (in +/usr/local/l2p/rot_matrix/ where rotateMatrix is correct, +and the numbered ones are each broken in some way). + +As with 09_testing2, you will write a file called tests.txt, +which will list the command line arguments you want to use to +run the programs. However, unlike 09_testing2, you will +also want to create a wide variety of input files. You can +name them anything you want, as long as you save them in the +current (26_tests_matrix_input) directory, and submit them +along with tests.txt. + +As usual, we have provided run_all.sh + +Hint 1: think about various error cases that the programmer +might have forgotten! + +Hint 2: The trickiest of these is one in which the programmer +did not pay attention to a rather subtle, but common mistake +pointed out in your reading titled 'Reading a File'! + +Hint 3: If you find yourself needing to create an input +file with non-typable/non-printable characters in it, +you will want to do a few things. + +First, (after you have the file you want to edit open), you +will want to force emacs to change the encoding it uses +(so that it won't try to rewrite things in Unicode, for example): + +M-x revert-buffer-with-coding-system +raw-text + +Once you have done this, you can do + +M-x hexl-mode + +to put emacs in hex editor mode. + +Then you will see hex values on the left, and their printable +interpreations (or . for non-printable characters) on the right. +Move the point to where you want to put a particular value, and do + +C-M-x + +then type the hex value (one byte, so two hex digits) that you want, +and hit enter. It will overwrite the current character with that value. +Then you can save the file. diff --git a/26_tests_matrix_input/grade.txt b/26_tests_matrix_input/grade.txt new file mode 100644 index 0000000..727e7c2 --- /dev/null +++ b/26_tests_matrix_input/grade.txt @@ -0,0 +1,20 @@ +Grading at Thu 02 Dec 2021 03:14:19 AM UTC +Checking rotateMatrix1 +Your tests identified the problem with rotateMatrix1 +Checking rotateMatrix2 +Your tests identified the problem with rotateMatrix2 +Checking rotateMatrix3 +Your tests identified the problem with rotateMatrix3 +Checking rotateMatrix4 +Your tests identified the problem with rotateMatrix4 +Checking rotateMatrix5 +Your tests identified the problem with rotateMatrix5 +Checking rotateMatrix6 +Your tests identified the problem with rotateMatrix6 +Checking rotateMatrix7 +Your tests identified the problem with rotateMatrix7 +Checking rotateMatrix8 +Your tests identified the problem with rotateMatrix8 +Your tests identified problems with all broken programs + +Overall Grade: PASSED diff --git a/26_tests_matrix_input/input.1 b/26_tests_matrix_input/input.1 new file mode 100644 index 0000000..104bde6 --- /dev/null +++ b/26_tests_matrix_input/input.1 @@ -0,0 +1,10 @@ +1234567890 +/n/n/n/n/n +%fdsfddgfg +afsafsjhgh +dgdgfgfgfg +addjfkga01 + fdsfdbvbd +ashfshflks +sajlasjfls +gjgjjhjhjj diff --git a/26_tests_matrix_input/input.10 b/26_tests_matrix_input/input.10 new file mode 100644 index 0000000..4a664e4 --- /dev/null +++ b/26_tests_matrix_input/input.10 @@ -0,0 +1 @@ +123456782345678 diff --git a/26_tests_matrix_input/next-README b/26_tests_matrix_input/next-README new file mode 100644 index 0000000..3484c1a --- /dev/null +++ b/26_tests_matrix_input/next-README @@ -0,0 +1,46 @@ +In a previous function, you write a function + + void rotate(char matrix[10][10]) + +which performed 90 degree clockwise rotation of a 10x10 +matrix. In that assignment, we gave you a compiled +object file which read the input matrix from a file, +called your function to do the rotation, and then +printed the result to the screen. + +In this assignment, you will write the code that we +previously gave you, making the complete program on your own. +You are encouraged to make use of your previously written +rotate function in this assignment. + +For this problem, you will be writing a program which +performs a 90 degree clockwise rotation of a 10x10 matrix. +There is nothing special about a 10x10 matrix---I just need +to fix the matrix size, since we have not learned about dynamic +memory allocation yet, so we do not have the knowledge needed +to read in any size of matrix. + +To keep the input processing simple, the matrix will be a matrix +of characters (so you will have something like + char matrix[10][10] +in your program), which will be read from a file. Each line +in the input file should contain 10 characters (plus a newline). + +Requirements: +============= + - Create a file called rotateMatrix.c + - Your program will take one command line argument, a string + specifying the input file to read. + - The input file should contain 10 lines, each of which + have 10 (non-newline) characters (plus a newline). + - Your program should then rotate this 90 degrees clockwise, + and print the result on stdout. + Note that sample.txt provides sample input, and + sample.out provides sample output. + - If there are any errors, your program should print an + appropriate message to stderr, and exit with EXIT_FAILURE. + +Hints: +------ + - You may find the strchr useful for error checking that + you read a proper line (10 non-newline characters, then a newline). diff --git a/26_tests_matrix_input/run_all.sh b/26_tests_matrix_input/run_all.sh new file mode 100755 index 0000000..f13fdf0 --- /dev/null +++ b/26_tests_matrix_input/run_all.sh @@ -0,0 +1,30 @@ +#!/bin/bash +run_test() { + prog="$1" + testfile="$2" + IFS=$'\n' + for line in `cat $testfile | sed 's/^$/ /'` + do + IFS=" " correct=`/usr/local/l2p/rot_matrix/rotateMatrix $line 2>&1` + IFS=" " broken=`$prog $line 2>&1` + if [ "$broken" != "$correct" ] + then + return 0 + fi + done + return 1 +} + +for i in /usr/local/l2p/rot_matrix/rotateMatrix* +do + if [ "$i" != "/usr/local/l2p/rot_matrix/rotateMatrix" ] + then + echo "Checking `basename $i`" + run_test $i tests.txt + x="$?" + if [ "$x" != "0" ] + then + echo "***Your tests failed to show that `basename $i` was broken!" + fi + fi +done diff --git a/26_tests_matrix_input/tests.txt b/26_tests_matrix_input/tests.txt new file mode 100644 index 0000000..b68a6cf --- /dev/null +++ b/26_tests_matrix_input/tests.txt @@ -0,0 +1,15 @@ + +input.x +input.1 +input.2 +input.3 +input.4 +input.5 +empty trick +input.6 +input.7 +input.8 +input.9 +input.10 +fake.fake + diff --git a/27_matrix_input/Makefile b/27_matrix_input/Makefile new file mode 100644 index 0000000..f6b6c00 --- /dev/null +++ b/27_matrix_input/Makefile @@ -0,0 +1,4 @@ +CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99 + +rotateMatrix: rotateMatrix.c + gcc ${CFLAGS} -o rotateMatrix rotateMatrix.c diff --git a/27_matrix_input/README b/27_matrix_input/README new file mode 100644 index 0000000..26031a6 --- /dev/null +++ b/27_matrix_input/README @@ -0,0 +1,47 @@ +In a previous project, you wrote a function + + void rotate(char matrix[10][10]) + +which performed 90 degree clockwise rotation of a 10x10 +matrix. In that assignment, we gave you a compiled +object file which read the input matrix from a file, +called your function to do the rotation, and then +printed the result to the screen. + +In this assignment, you will write the code that we +previously gave you, making the complete program on your own. +You are encouraged to make use of your previously written +rotate function in this assignment. + +For this problem, you will be writing a program which +performs a 90 degree clockwise rotation of a 10x10 matrix. +There is nothing special about a 10x10 matrix---I just need +to fix the matrix size, since we have not learned about dynamic +memory allocation yet, so we do not have the knowledge needed +to read in any size of matrix. + +To keep the input processing simple, the matrix will be a matrix +of characters (so you will have something like + char matrix[10][10] +in your program), which will be read from a file. Each line +in the input file should contain 10 characters (plus a newline). + +Requirements: +============= + - Create a file called rotateMatrix.c + - Your program will take one command line argument, a string + specifying the input file to read. + - The input file should contain 10 lines, each of which + have 10 (non-newline) characters (plus a newline). + - Your program should then rotate this 90 degrees clockwise, + and print the result on stdout. + Note that sample.txt provides sample input, and + sample.out provides sample output. + - If there are any errors, your program should print an + appropriate message to stderr, and exit with EXIT_FAILURE. + +Hints: +------ + - You may find the strchr useful for error checking that + you read a proper line (10 non-newline characters, then a newline). + diff --git a/27_matrix_input/blank.txt b/27_matrix_input/blank.txt new file mode 100644 index 0000000..139597f --- /dev/null +++ b/27_matrix_input/blank.txt @@ -0,0 +1,2 @@ + + diff --git a/27_matrix_input/f b/27_matrix_input/f new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/27_matrix_input/f diff --git a/27_matrix_input/grade.txt b/27_matrix_input/grade.txt new file mode 100644 index 0000000..14df468 --- /dev/null +++ b/27_matrix_input/grade.txt @@ -0,0 +1,53 @@ +Grading at Mon 13 Dec 2021 02:22:53 AM UTC +Attempting to compile rotateMatrix.c +testcase1 passed +################################################# +testcase2: NonExistentFile + (should indicate an error) +testcase2 passed +################################################# +testcase3: blank.txt + (should indicate an error) +testcase3 passed +################################################# +testcase4: short-line.txt + (should indicate an error) +testcase4 passed +################################################# +testcase5: short-file.txt + (should indicate an error) +testcase5 passed +################################################# +testcase6: long-line.txt + (should indicate an error) +testcase6 passed +################################################# +testcase7: long-file.txt + (should indicate an error) +testcase7 passed +################################################# +testcase8: long-line-2.txt + (should indicate an error) +testcase8 passed +################################################# +testcase9: normal1.txt normal2.txt + (should indicate an error) +testcase9 passed +################################################# +testcase10: normal1.txt +Your file matched the expected output +testcase10 passed +################################################# +testcase10: normal2.txt +Your file matched the expected output +testcase10 passed +################################################# +testcase10: normal3.txt +Your file matched the expected output +testcase10 passed +################################################# +testcase10: eof.txt +Your file matched the expected output +testcase10 passed + +Overall Grade: A diff --git a/27_matrix_input/rotateMatrix b/27_matrix_input/rotateMatrix Binary files differnew file mode 100755 index 0000000..f810ebf --- /dev/null +++ b/27_matrix_input/rotateMatrix diff --git a/27_matrix_input/rotateMatrix.c b/27_matrix_input/rotateMatrix.c new file mode 100644 index 0000000..8697a0d --- /dev/null +++ b/27_matrix_input/rotateMatrix.c @@ -0,0 +1,79 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define LINE_SIZE 12 + +void rotate(char matrix[10][10]) { + int layer = 0; + char temp1; + char temp2; + char temp3; + + while (layer <= 10 / 2) { + for (int i = layer; i < 10 - 1 - layer; i++) { + temp1 = matrix[i][10 - 1 - layer]; + temp2 = matrix[10 - 1 - layer][10 - 1 - i]; + temp3 = matrix[10 - 1 - i][layer]; + + matrix[i][10 - 1 - layer] = matrix[layer][i]; + matrix[10 - 1 - layer][10 - 1 - i] = temp1; + matrix[10 - 1 - i][layer] = temp2; + matrix[layer][i] = temp3; + } + layer++; + } +} + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: rotateMatrix inputFileName\n"); + return EXIT_FAILURE; + } + + FILE *f = fopen(argv[1], "r"); + if (f == NULL) { + fprintf(stderr, "Could not open file\n"); + return EXIT_FAILURE; + } + char line[LINE_SIZE]; + char matrix[10][10]; + int lineNumber = 0; + while (fgets(line, LINE_SIZE, f) != NULL) { + if (lineNumber >= 10) { + fprintf(stderr, "Too many lines!\n"); + return EXIT_FAILURE; + } + if (strchr(line, '\n') == NULL) { + fprintf(stderr, "Line is too long!\n"); + return EXIT_FAILURE; + } + if ((strchr(line, '\n') - line) != 10) { + fprintf(stderr, "Line is too short!\n"); + return EXIT_FAILURE; + } + for (int j = 0; j < 10; j++) { + if (line[j] == '\n') { + fprintf(stderr, "Line is too short!\n"); + return EXIT_FAILURE; + } + matrix[lineNumber][j] = line[j]; + } + lineNumber++; + } + + if (lineNumber != 10) { + fprintf(stderr, "Not enough number of lines\n"); + return EXIT_FAILURE; + } + + rotate(matrix); + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + printf("%c", matrix[i][j]); + } + printf("\n"); + } + + return EXIT_SUCCESS; +} diff --git a/27_matrix_input/rotateMatrix.c~ b/27_matrix_input/rotateMatrix.c~ new file mode 100644 index 0000000..3aa97bc --- /dev/null +++ b/27_matrix_input/rotateMatrix.c~ @@ -0,0 +1,72 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define LINE_SIZE 12 + +void rotate(char matrix[10][10]) { + int layer = 0; + char temp1; + char temp2; + char temp3; + + while (layer <= 10/2) { + for (int i = layer; i < 10 - 1 - layer; i++) { + temp1 = matrix[i][10-1-layer]; + temp2 = matrix[10-1-layer][10-1-i]; + temp3 = matrix[10-1-i][layer]; + + matrix[i][10-1-layer] = matrix[layer][i]; + matrix[10-1-layer][10-1-i] = temp1; + matrix[10-1-i][layer] = temp2; + matrix[layer][i] = temp3; + } + layer++; + } + +} + +int main(int argc, char ** argv) { + if (argc != 2) { + fprintf(stderr,"Usage: rotateMatrix inputFileName\n"); + return EXIT_FAILURE; + } + + FILE * f = fopen(argv[1], "r"); + if (f == NULL) { + perror("Could not open file"); + return EXIT_FAILURE; + } + char line[LINE_SIZE]; + char matrix[10][10]; + int lineNumber = 0; + while (fgets(line, LINE_SIZE, f) != NULL && lineNumber < 10) { + if (strchr(line, '\n') == NULL) { + printf("Line is too long!\n"); + return EXIT_FAILURE; + } + for (int j = 0; j<10; j++) { + if (line[j] == '\n') { + printf("Line is too short!\n"); + return EXIT_FAILURE; + } + matrix[lineNumber][j] = line[j]; + //printf("%c", matrix[i][j]); + } + lineNumber++; + } + if (lineNumber < 9) { + printf("Not enough number of lines\n"); + return EXIT_FAILURE; + } + + rotate(matrix); + for (int i=0; i<10; i++) { + for (int j=0; j<10; j++) { + printf("%c", matrix[i][j]); + } + printf("\n"); + } + + return EXIT_SUCCESS; +} diff --git a/27_matrix_input/sample.out b/27_matrix_input/sample.out new file mode 100644 index 0000000..6280f8c --- /dev/null +++ b/27_matrix_input/sample.out @@ -0,0 +1,10 @@ +CH.....*a0 +oe....*.b1 +dl...*..c2 +il..*...d3 +no.*....e4 +gW*.....f5 + o......g6 +Fr......h7 +ul......i8 +nd......j9 diff --git a/27_matrix_input/sample.txt b/27_matrix_input/sample.txt new file mode 100644 index 0000000..767b4c3 --- /dev/null +++ b/27_matrix_input/sample.txt @@ -0,0 +1,10 @@ +0123456789 +abcdefghij +*......... +.*........ +..*....... +...*...... +....*..... +.....*.... +HelloWorld +Coding Fun diff --git a/28_fix_vg_encr/Makefile b/28_fix_vg_encr/Makefile new file mode 100644 index 0000000..f08edbe --- /dev/null +++ b/28_fix_vg_encr/Makefile @@ -0,0 +1,5 @@ +CFLAGS=-ggdb3 -Wall -Werror -std=gnu99 -pedantic +encrypt: encrypt.c + gcc $(CFLAGS) -o encrypt encrypt.c +clean: + rm -f encrypt *~ diff --git a/28_fix_vg_encr/README b/28_fix_vg_encr/README new file mode 100644 index 0000000..5d44bb1 --- /dev/null +++ b/28_fix_vg_encr/README @@ -0,0 +1,22 @@ +In a previous problem, you executed a Ceaser Cipher encryption program by hand. +That program read an input file, and wrote to standard output. + +In this problem, you are going to work on a slightly modified version of that program, +which is is included in encrypt.c. The major difference between this version +of the program and the previous one is that rather than printing to stdout, +this program appends ".enc" to the input file name, and writes its output to that +file (for example, if your input file is called "input.txt", it will write to "input.txt.enc"). +Additionally, rather than using fgetc to read one character at a time, this version +of the program uses getline to read an entire line at a time. + +This program has the basic algorithm correct, but makes a variety of errors---all of which +valgrind will detect. Your job for this problem is to fix the program by making it +valgrind cleanly. + +Hint: Start from the first valgrind error. Read and understand the error. It will + tell you on what line of code valgrind detected the problem. Understand the + error, and why it is occuring (drawing some pictures will likely help here). + Fix the error, make, and re-run. Repeat the process until all valgrind errors are + gone. Don't forget that gdb may be useful as well. + + diff --git a/28_fix_vg_encr/encrypt.c b/28_fix_vg_encr/encrypt.c new file mode 100644 index 0000000..71b7156 --- /dev/null +++ b/28_fix_vg_encr/encrypt.c @@ -0,0 +1,60 @@ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> + +void encrypt(FILE * f, int key, FILE * outfile){ + char * line=NULL; + size_t sz=0; + while (getline(&line,&sz, f) >= 0) { + char * ptr = line; + while (*ptr != '\0') { + int c = *ptr; + if (isalpha(c)) { + c = tolower(c); + c -= 'a'; + c += key; + c %= 26; + c += 'a'; + } + *ptr = c; + ptr++; + } + fprintf(outfile, "%s", line); + } + free(line); +} + +int main(int argc, char ** argv) { + if (argc != 3) { + fprintf(stderr,"Usage: encrypt key inputFileName\n"); + return EXIT_FAILURE; + } + int key = atoi(argv[1]); + if (key == 0) { + fprintf(stderr,"Invalid key (%s): must be a non-zero integer\n", argv[1]); + return EXIT_FAILURE; + } + FILE * f = fopen(argv[2], "r"); + if (f == NULL) { + perror("Could not open file"); + return EXIT_FAILURE; + } + //outfileNAme is argv[2] + ".txt", so add 4 to its length. + char * outFileName = malloc((strlen(argv[2]) + 5) * sizeof(*outFileName)); + strcpy(outFileName, argv[2]); + strcat(outFileName, ".enc"); + FILE * outFile = fopen(outFileName, "w"); + encrypt(f,key, outFile); + if (fclose(outFile) != 0) { + perror("Failed to close the input file!"); + return EXIT_FAILURE; + } + if (fclose(f) != 0) { + perror("Failed to close the input file!"); + return EXIT_FAILURE; + } + free(outFileName); + + return EXIT_SUCCESS; +} diff --git a/28_fix_vg_encr/grade.txt b/28_fix_vg_encr/grade.txt new file mode 100644 index 0000000..389f7f2 --- /dev/null +++ b/28_fix_vg_encr/grade.txt @@ -0,0 +1,28 @@ +Grading at Tue 14 Dec 2021 02:37:37 AM UTC +Attempting to compile encrypt.c +testcase1: +your output was correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase4: + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase5: + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase6: + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/28_fix_vg_encr/input.txt b/28_fix_vg_encr/input.txt new file mode 100644 index 0000000..76a327a --- /dev/null +++ b/28_fix_vg_encr/input.txt @@ -0,0 +1,2 @@ +An example +Of the input. diff --git a/28_fix_vg_encr/input.txt.enc b/28_fix_vg_encr/input.txt.enc new file mode 100644 index 0000000..4d4e357 --- /dev/null +++ b/28_fix_vg_encr/input.txt.enc @@ -0,0 +1,2 @@ +hu lehtwsl +vm aol puwba. diff --git a/29_outname/Makefile b/29_outname/Makefile new file mode 100644 index 0000000..7cdf5f1 --- /dev/null +++ b/29_outname/Makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror -std=gnu99 -pedantic -ggdb3 +OBJS=outname.o outname_test.o +PROGRAM=outname_test + +$(PROGRAM): $(OBJS) + gcc $(CFLAGS) -o $@ $(OBJS) + +%.o: %.c outname.h + gcc -c $(CFLAGS) $< + +clean: + rm -f $(OBJS) $(PROGRAM) *~ diff --git a/29_outname/README b/29_outname/README new file mode 100644 index 0000000..735972e --- /dev/null +++ b/29_outname/README @@ -0,0 +1,18 @@ +In a future assignment, you are going to write a program which reads +some input, does some manipulations, and produces output in another file. +Right now, you are going to write a function which will be useful to you +in that assignment, which takes the input filename, and produces the output +file name. The output file name should be the same as the input file name +with ".counts" on the end. So, for example, if the input filename (inputName) +is "input.txt", your function should return "input.txt.counts". + +Note that your function needs to use malloc to allocate memory to hold +the string that it will return as its answer. + +Your function should have the following signature: + + char * computeOutputFileName(const char * inputName) + +and you should write it in the outname.c file. +You can make and test with the main function found in outname_test.c. +As always, be sure your program valgrinds cleanly. diff --git a/29_outname/grade.txt b/29_outname/grade.txt new file mode 100644 index 0000000..12148a6 --- /dev/null +++ b/29_outname/grade.txt @@ -0,0 +1,19 @@ +Grading at Tue 14 Dec 2021 02:54:10 AM UTC +Attempting to compile: +################################################# +testcase1: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/29_outname/outname.c b/29_outname/outname.c new file mode 100644 index 0000000..7cc4346 --- /dev/null +++ b/29_outname/outname.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "outname.h" + +char * computeOutputFileName(const char * inputName) { + char * outFileName = malloc((strlen(inputName) + 8) * sizeof(*outFileName)); + strcpy(outFileName, inputName); + strcat(outFileName, ".counts"); + return outFileName; +} diff --git a/29_outname/outname.h b/29_outname/outname.h new file mode 100644 index 0000000..acd1f03 --- /dev/null +++ b/29_outname/outname.h @@ -0,0 +1,6 @@ +#ifndef __OUTNAME_H__ +#define __OUTNAME_H__ + +char * computeOutputFileName(const char * inputName); + +#endif diff --git a/29_outname/outname_test.c b/29_outname/outname_test.c new file mode 100644 index 0000000..6a9493a --- /dev/null +++ b/29_outname/outname_test.c @@ -0,0 +1,18 @@ +#include "outname.h" +#include <stdio.h> +#include <stdlib.h> + + +#define NUM_TESTS 3 +int main(void) { + char * testNames[NUM_TESTS] = {"input.txt", + "anotherTestFileName.txt", + "somethingelse"}; + + for (int i = 0; i < NUM_TESTS; i++) { + char * outName = computeOutputFileName(testNames[i]); + printf("'%s' => '%s'\n", testNames[i], outName); + free(outName); + } + return EXIT_SUCCESS; +} diff --git a/30_sort_lines/Makefile b/30_sort_lines/Makefile new file mode 100644 index 0000000..28452a5 --- /dev/null +++ b/30_sort_lines/Makefile @@ -0,0 +1,6 @@ +CFLAGS=-ggdb3 -Wall -Werror -std=gnu99 -pedantic +sortLines: sortLines.c + gcc $(CFLAGS) -o sortLines sortLines.c + +clean: + rm -f sortLines *~ diff --git a/30_sort_lines/README b/30_sort_lines/README new file mode 100644 index 0000000..c5dcb2a --- /dev/null +++ b/30_sort_lines/README @@ -0,0 +1,43 @@ +For this problem, you will write a program (by modifying the provided +sortLines.c file) which sorts strings from input files. As we have not +yet covered sorting, we have provided the code that does the acutal +sorting. You can just call this function, which will sort the data. + + void sortData(char ** data, size_t count); + +The sortData function takes two arguments. The first is an array of strings. +The second is the length of that array. It will re-order the elements of the +array, such that they are sorted. + +Your task in this problem primarily centers around reading the data into +the array from the input file(s), so that it can be sorted. You will also +need to print the data after it is sorted, and free all of the memory you have allocated. + +Specifically, this program should take 0 or more command line arguments. + - If no arguments (other than its own name) are provided (argc ==1), then + your program should read from standard input, sort the lines of input, + print the results, free memory, and exit successfully. + - If 1 or more arguments are provided (argc > 1), then your program should + treat each argument as an input file name. It should open that file, + read all of the lines of data in it, sort the lines, print the results, + free the memory, and close the file. If any errors occur, your program + should print an appropriate error message and exit with EXIT_FAILURE. + If no errors occur, your program should indicate its success after processing + all of the files. + +Note that we now place *no* restriction on the length of any individual line of input. +You should therefore use the getline function to read an arbitrarily long line of +input, dynamically allocating space for it as needed. See the man page for getline +for more details. + +You should make sure your program valgrinds cleanly, including no memory leaks +before you submit it. As always, submit your code for grading. + +We've provided one simple test for you to use to test your program. Run it with: +./test.sh + +Hints: + - Don't forget to abstract code out into smaller function. In my solution, + I wrote 3 functions other than main (plus the 2 that are provided). + - Don't forget to draw pictures! They are even more important + as you use pointers more and more. diff --git a/30_sort_lines/grade.txt b/30_sort_lines/grade.txt new file mode 100644 index 0000000..19df8c9 --- /dev/null +++ b/30_sort_lines/grade.txt @@ -0,0 +1,24 @@ +Grading at Fri 17 Dec 2021 02:53:30 PM UTC +Attempting to compile sortLines.c +################################################# +testcase1: +testcase1 passed, your program successfully indicated a failure + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase4: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/30_sort_lines/sortLines.c b/30_sort_lines/sortLines.c new file mode 100644 index 0000000..3ef65ad --- /dev/null +++ b/30_sort_lines/sortLines.c @@ -0,0 +1,70 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +//This function is used to figure out the ordering +//of the strings in qsort. You do not need +//to modify it. +int stringOrder(const void * vp1, const void * vp2) { + const char * const * p1 = vp1; + const char * const * p2 = vp2; + return strcmp(*p1, *p2); +} +//This function will sort and print data (whose length is count). +void sortData(char ** data, size_t count) { + qsort(data, count, sizeof(char *), stringOrder); +} + +void processFile(FILE * f) { + char ** lines = NULL; + char * curr = NULL; + size_t sz; + size_t i = 0; + + //processing: building string array + while (getline(&curr, &sz, f) >= 0) { + lines = realloc(lines, (i+1) * sizeof(*lines)); + lines[i] = curr; + curr = NULL; + i++; + } + + //sorting + free(curr); + sortData(lines, i); + + //printing then freeing each line + for (size_t j = 0; j < i; j++) { + printf("%s", lines[j]); + free(lines[j]); + } + + //clean up + free(lines); +} + +int main(int argc, char ** argv) { + + if (argc == 1) { + // stdin + processFile(stdin); + } + else { + for (int i = 1; i < argc; i++) { + // process each file one by one + FILE *f = fopen(argv[i], "r"); + if (f == NULL) { + fprintf(stderr, "Could not open file\n"); + return EXIT_FAILURE; + } + processFile(f); + if (fclose(f) != 0) { + fprintf(stderr, "Could not close file\n"); + return EXIT_FAILURE; + } + } + } + + return EXIT_SUCCESS; +} diff --git a/30_sort_lines/test.sh b/30_sort_lines/test.sh new file mode 100755 index 0000000..2d9b268 --- /dev/null +++ b/30_sort_lines/test.sh @@ -0,0 +1 @@ +printf "%s\n%s\n%s\n" "This is a sample test case" "it checks your program's one argument behavior" "go!" | tee | ./sortLines diff --git a/31_minesweeper/Makefile b/31_minesweeper/Makefile new file mode 100644 index 0000000..7c65731 --- /dev/null +++ b/31_minesweeper/Makefile @@ -0,0 +1,3 @@ +CCFLAGS=-Wall -pedantic -std=gnu99 -Werror -ggdb3 +minesweeper: minesweeper.c + gcc -o minesweeper $(CCFLAGS) minesweeper.c diff --git a/31_minesweeper/README b/31_minesweeper/README new file mode 100644 index 0000000..14b4bfa --- /dev/null +++ b/31_minesweeper/README @@ -0,0 +1,80 @@ + +********************************************************************* +** REMINDER: your programs MUST valgrind cleanly for full credit! ** +********************************************************************* + +For this problem, you will be completing a partially written +minesweeper game. This game will be played on a text interface +(not a GUI---we haven't learned anything about those). + +If you are not familiar with the game of minesweeper, you might +take a minute to read up about it on the internet, but you don't +need much game expertise to do this assignment. + +I have provided code for an almost working minesweeper, except +that I have deleted the code for 4 functions: + +board_t * makeBoard(int w, int h, int numMines) +int countMines(board_t * b, int x, int y) +int checkWin(board_t * b) +void freeBoard(board_t * b) + + +Your job is to implement each of these functions (which all have a +//WRITE ME comment to make them easy to find). A brief description +of each follows: + + + - makeBoard: this function should malloc and initialize a board_t + representing the board. The parameters specify the width + and height of the board, as well as the number of mines. + You will also need to call malloc (multiple times) + to allocate space for the 2D array "board". + This function should fill in all squares on the board with + UNKNOWN, then call addRandomMine an appropriate number of times + (i.e., numMines) to "randomly" place mines on the board. + Note that the fields of your board_t must be initailzed before + you call addRandomMine. + Also note that the mine generation is pseudo random and will not + change if you re-run the program multiple times with the same + parameters. + + Note that the layout of b->board should be such that it is indexed + b->board[y][x] + where y is between 0 and the height and x is between 0 and the width. + + - countMines: this funciton takes a board_t, and an (x,y) coordinate. + It should count the mines in the 8 squares around that (x,y) + coordinate, and return that count. Note that a mine may be + indicated by a square on the board either being HAS_MINE or + KNOWN_MINE. You can use the IS_MINE macro to test both cases: + IS_MINE(b->board[ny][nx]) + (where b is the board_t, and (nx,ny) are the coordinates you + want to check). Be careful not to go out of bounds of the array. + + - checkWin: this funciton takes a board_t and see if the game has + been won. The game is won when no squares are UNKNOWN. Return 0 + if the game has not been won, 1 if it has. + + - freeBoard: This function takes a board_t and frees all memory + associated with it (including the array inside of it). That is, + freeBoard should undo all the allocations made by a call to makeBoard. + +Note: You should NOT change any of the other provided functions! + + +Once you have these all working, you should have a playable game of +minesweeper. Note that there are a few differences in game play +from the "standard" game: + + - You select a square by entering its x (column) and y (row) coordinate. + The x coordinates are listed across the top and the y are listed + down the left side to reduce counting. + + - The game will automatically figure out the "obvious" squares: + both mines and non-mined spaces. It will reveal these too you + as soon as it considers them trivial to figure out. + + - You cannot manually mark a square that you suspect has a mine + +Once your code is complete, submit minesweeper.c diff --git a/31_minesweeper/grade.txt b/31_minesweeper/grade.txt new file mode 100644 index 0000000..b4cf79d --- /dev/null +++ b/31_minesweeper/grade.txt @@ -0,0 +1,24 @@ +Grading at Sun 19 Dec 2021 12:56:12 AM UTC +Attempting to compile minesweeper.c +################################################# +testcase1: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase4: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/31_minesweeper/minesweeper.c b/31_minesweeper/minesweeper.c new file mode 100644 index 0000000..3ea9490 --- /dev/null +++ b/31_minesweeper/minesweeper.c @@ -0,0 +1,335 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <limits.h> + +#define CLICK_KNOWN_MINE -2 +#define CLICK_INVALID -1 +#define CLICK_CONTINUE 0 +#define CLICK_LOSE 1 + +#define KNOWN_MINE -3 +#define HAS_MINE -2 +#define UNKNOWN -1 + +#define IS_MINE(x) ((x) == HAS_MINE || (x) == KNOWN_MINE) + + +struct _board_t { + int ** board; + int width; + int height; + int totalMines; +}; + +typedef struct _board_t board_t; + +void addRandomMine(board_t * b) { + int x; + int y; + //we could have a board too small for the number + //of mines that we request. try w*h*10 times before + //we give up + int limit = b->width * b->height * 10; + do { + x = random() % b->width; + y = random() % b->height; + assert(limit > 0); + limit--; + } while(b->board[y][x] == HAS_MINE); + b->board[y][x] = HAS_MINE; +} + +board_t * makeBoard(int w, int h, int numMines) { + board_t * b = malloc(sizeof(board_t)); + b->width = w; + b->height = h; + b->totalMines = numMines; + + b->board = malloc(h*sizeof(int *)); + for (int i = 0; i < h; i++) { + b->board[i] = malloc(w * sizeof(int)); + } + + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + b->board[i][j] = UNKNOWN; + } + } + + for (int i = 0; i < numMines; i++) { + addRandomMine(b); + } + return b; +} + +void printBoard(board_t * b) { + int found = 0; + printf(" "); + for (int x = 0; x < b->width; x++) { + printf("%d",x/10); + } + printf("\n "); + for (int x = 0; x < b->width; x++) { + printf("%d",x%10); + } + printf("\n----"); + for (int x = 0; x < b->width; x++) { + printf("-"); + } + printf("\n"); + for (int y = 0; y < b->height; y++) { + printf("%2d: ", y %100); + for (int x = 0; x < b->width; x++) { + if (b->board[y][x] == KNOWN_MINE) { + printf("*"); + found++; + } + else if (b->board[y][x] < 0) { + printf("?"); + } + else if (b->board[y][x] == 0) { + printf(" "); + } + else { + printf("%d", b->board[y][x]); + } + } + printf("\n"); + } + printf("\n----"); + for (int x = 0; x < b->width; x++) { + printf("-"); + } + printf("\n"); + + printf(" "); + for (int x = 0; x < b->width; x++) { + printf("%d",x/10); + } + printf("\n "); + for (int x = 0; x < b->width; x++) { + printf("%d",x%10); + } + printf("\nFound %d of %d mines\n", found, b->totalMines); +} +int countMines(board_t * b, int x, int y) { + int count = 0; + + for (int i = -1; i < 2; i++) { + for (int j = -1; j < 2; j++) { + if (x + i >=0 && x+i <= b->width-1) { + if (y + j >=0 && y+j <= b->height-1) { + if (IS_MINE(b->board[y+j][x+i])){ + count++; + } + } + } + } + } + return count; +} +int click (board_t * b, int x, int y) { + if (x < 0 || x >= b->width || + y < 0 || y >= b->height) { + return CLICK_INVALID; + } + if (b->board[y][x] == KNOWN_MINE) { + return CLICK_KNOWN_MINE; + } + if (b->board[y][x] == HAS_MINE) { + return CLICK_LOSE; + } + if (b->board[y][x] != UNKNOWN) { + return CLICK_CONTINUE; + } + + b->board[y][x] = countMines(b,x,y); + return CLICK_CONTINUE; +} + +int checkWin(board_t * b) { + for (int i = 0; i < b->width; i++) { + for (int j = 0; j < b->height; j++) { + if (b->board[j][i] == UNKNOWN) { + return 0; + } + } + } + return 1; +} + +void freeBoard(board_t * b) { + for (int i = 0; i < b->height; i++) { + free(b->board[i]); + } + free(b->board); + free(b); +} + +int readInt(char ** linep, size_t * lineszp) { + if (getline (linep, lineszp, stdin) == -1) { + fprintf (stderr,"End of file from keyboard reading a number. Quitting\n"); + exit(EXIT_FAILURE); + } + char * endptr = NULL; + long int x = strtol (*linep, &endptr, 10); + if (endptr == *linep) { + fprintf (stderr,"You did not enter any valid number\n"); + printf ("Please try again\n"); + return readInt (linep, lineszp); + } + if (*endptr != '\n') { + fprintf( stderr, + "Input was not entirely a number (junk at end)\n"); + printf ("Please try again\n"); + return readInt (linep, lineszp); + } + if (x > INT_MAX) { + fprintf(stderr,"%ld is too big for an int!\n", x); + printf("Please try again\n"); + return readInt(linep, lineszp); + } + return x; +} + +void doReveal(board_t * b, int x, int y, int revealMines){ + for (int dy = -1; dy <=1 ; dy++) { + for (int dx = -1; dx <=1 ; dx++) { + int nx = x + dx; + int ny = y + dy; + if (nx >= 0 && nx < b->width && + ny >= 0 && ny < b->height) { + if (revealMines) { + assert(b->board[ny][nx] != UNKNOWN); + if (b->board[ny][nx] == HAS_MINE){ + b->board[ny][nx] = KNOWN_MINE; + } + } + else { + assert(b->board[ny][nx] != HAS_MINE); + if (b->board[ny][nx] == UNKNOWN) { + b->board[ny][nx] = countMines(b,nx,ny); + } + } + } + } + } +} + +int maybeReveal(board_t * b, int x, int y) { + int unknownSquares = 0; + int knownMines = 0; + for (int dy = -1; dy <=1 ; dy++) { + for (int dx = -1; dx <=1 ; dx++) { + int nx = x + dx; + int ny = y + dy; + if (nx >= 0 && nx < b->width && + ny >= 0 && ny < b->height) { + if (b->board[ny][nx] == UNKNOWN || + b->board[ny][nx] == HAS_MINE) { + unknownSquares++; + } + else if(b->board[ny][nx] == KNOWN_MINE) { + knownMines++; + } + } + } + } + assert(knownMines + unknownSquares >= b->board[y][x]); + assert(knownMines <= b->board[y][x]); + if (unknownSquares > 0) { + int revealMines = (knownMines + unknownSquares == + b->board[y][x]); + int allKnown = knownMines == b->board[y][x]; + if(revealMines || allKnown) { + assert(!revealMines || !allKnown); + doReveal(b,x,y, revealMines); + return 1; + } + } + return 0; +} +void determineKnownMines(board_t * b) { + int foundMore = 0; + for (int y = 0; y < b->height; y++) { + for (int x = 0; x < b->width; x++) { + if (b->board[y][x] >= 0) { + foundMore = maybeReveal(b,x,y) || foundMore; + } + } + } + if (foundMore) { + determineKnownMines(b); + } +} + +void revealMines(board_t * b) { + for (int y = 0; y < b->height; y++) { + for (int x = 0; x < b->width; x++) { + if (b->board[y][x] == HAS_MINE) { + b->board[y][x] = KNOWN_MINE; + } + } + } +} +int playTurn(board_t * b, char ** linep, size_t *lineszp) { + printf("Current board:\n"); + printBoard(b); + printf("x coordinate:\n"); + int x = readInt(linep, lineszp); + printf("y coordinate:\n"); + int y = readInt(linep, lineszp); + int result = click(b,x,y); + determineKnownMines(b); + if (result == CLICK_LOSE) { + printf("Oh no! That square had a mine. You lose!\n"); + revealMines(b); + printBoard(b); + return 1; + } + else if (result == CLICK_INVALID) { + printf("That is not a valid square, please try again\n"); + } + else if (result == CLICK_KNOWN_MINE) { + printf("You already know there is a mine there!\n"); + } + else if(checkWin(b)) { + printBoard(b); + printf("You win!\n"); + return 1; + } + return 0; +} + + +int main(int argc, char ** argv) { + if (argc != 4) { + fprintf(stderr,"Usage: minesweeper width height numMines\n"); + return EXIT_FAILURE; + } + int width = atoi(argv[1]); + int height = atoi(argv[2]); + int numMines = atoi(argv[3]); + if (width <= 0 || height <= 0 || numMines <= 0) { + fprintf(stderr, + "Width, height, and numMines must all be positive ints\n"); + return EXIT_FAILURE; + } + char * line = NULL; + size_t linesz = 0; + + do { + board_t * b = makeBoard (width, height, numMines); + int gameOver = 0; + while (!gameOver) { + gameOver = playTurn(b, &line, &linesz); + } + freeBoard(b); + do { + printf("Do you want to play again?\n"); + } while(getline(&line, &linesz, stdin) == -1); + } while(line[0] == 'Y' || line[0] == 'y'); + free(line); + return EXIT_SUCCESS; +} diff --git a/32_kvs/Makefile b/32_kvs/Makefile new file mode 100644 index 0000000..38f5d54 --- /dev/null +++ b/32_kvs/Makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror -std=gnu99 -pedantic -ggdb3 +OBJS=kv_test.o kv.o +PROGRAM=kv_test + +$(PROGRAM): $(OBJS) + gcc $(CFLAGS) -o $@ $(OBJS) + +%.o: %.c kv.h + gcc -c $(CFLAGS) $< + +clean: + rm -f $(OBJS) $(PROGRAM) *~ diff --git a/32_kvs/README b/32_kvs/README new file mode 100644 index 0000000..35b0a18 --- /dev/null +++ b/32_kvs/README @@ -0,0 +1,118 @@ +For the next 4 problems, you will be doing one slightly larger program, which +we will cut up into 4 discretely testable pieces. + +The big picture is that your program will read two types of input files. +The first type of input file (which your program will read one of) will have the format: + +key1=value1 +key2=value2 +.... +keyN=valueN + +That is, it might say + +Jean Luc Picard=Captain +Will Riker=Commander +Beverly Crusher=Commander +Data=Lt. Commander +Geordi LaForge=Lt. Commander +Worf=Lt. Commander +Deanna Troi=Commander + +Note that the division between the key and the value is the first equals sign (the +values could have = in them, but the keys cannot. So a=b=c, would have a key of a, and +a value of b=c). + +The second type of input file will contain a list of lines (which will typically match +the keys from the first input file). Your program will read one or more of this +type of file. For example, it might contain: + +Jean Luc Picard +Will Riker +Worf +Deanna Troi +Q + +For each such input file that your program reads, it will print out the counts +of the values for the corresponding keys (or <unknown> for anything that did not +match any known key from the first input file). E.g. given the above to input files, +it would print to the corresponding output file (which will be named the same +as the input file, but with ".count" appended to the name). + +Captain: 1 +Commander: 2 +Lt. Commander: 1 +<unknown> : 1 + + + + +In thinking about our program, we might come up with the following +generalized high-level algorithm: + + //read the key/value pairs from the file named by argv[1] (call the result kv) + //count from 2 to argc (call the number you count i) + //count the values that appear in the file named by argv[i], using kv as the key/value pair + // (call this result c) + //compute the output file name from argv[i] (call this outName) + //open the file named by outName (call that f) + //print the counts from c into the FILE f + //close f + //free the memory for outName and c + //free the memory for kv + +This high-level algorithm suggests many functions which we can split our task into. +We will cut them up into 4 groups to make the 4 problems of this assignment: + +The first step (this problem): + - read the key/value pairs from a file + - free the memory for the key/value pairs + +The second step (next problem): + - compute the output file name + +The third step (problem after that): + - print the counts to a file + - free the memory for the counts + +The fourth step (the problem after that): + - compute the counts of values that appear in a particular input file + +Each subsequent problem will have more details about it. + +For this particular problem, you will need to: + + - read the key/value pairs from a file + - free the memory for the key/value pairs + +To start with this problem, you are going to want to define two structs, in the +file kv.h. The first one (struct _kvpair_t) should define the structure for +one key/value pair. The second should define the structure for an +array of key/value pairs (hint: you will want to include the length of the +array in this structure). + +Now you will want to write the four functions in kv.c. + +In readKVs, you will want to open the file, read the lines of text, split them into +key/value pairs, add the resulting pairs to an array (hint: realloc it to make it larger +each time), close the file, and return the kvarray_t * that has your array. + +Remember that you will want to abstract out complex steps into functions (you should +see at least 2 pieces to naturally pull out into their own functions). + +Next, you will write freeKVs, which should free all the memory allocated by readKVs. +That is, freeKVs(readKVs(filename)) should not leak any memory. + +Third, write printKVs which should take a kvarray_t *, and print out + + "key = '%s' value = '%s'\n" +for each key/value pair in the array, with the first %s being whatever the key is, +and the second being whatever value (e.g., key = 'Jean Luc Picard' value = 'Captain'). + +Finally, write the lookupValue function, which takes a kvarray_t * and a char * (string). +The char * that is passed in represents a key. This function searches the kvarray_t +for a matching key, and if found, returns the corresponding value. If no match is found, +this function returns NULL. + +Once you complete these functions, test them using the main in kv_test.c before +proceeding to the next problem. diff --git a/32_kvs/README~ b/32_kvs/README~ new file mode 100644 index 0000000..b4ee3c6 --- /dev/null +++ b/32_kvs/README~ @@ -0,0 +1,118 @@ +For the next 4 problems, you will be doing one slightly larger program, which +we will cut up into 4 discretely testable pieces. + +The big picture it that your program will read two types of input files. +The first type of input file (which your program will read one of) will have the format: + +key1=value1 +key2=value2 +.... +keyN=valueN + +That is, it might say + +Jean Luc Picard=Captain +Will Riker=Commander +Beverly Crusher=Commander +Data=Lt. Commander +Geordi LaForge=Lt. Commander +Worf=Lt. Commander +Deanna Troi=Commander + +Not that the division between the key and the value is the first equals sign (the +values could have = in them, but the keys cannot. So a=b=c, would have a key of a, and +a value of b=c). + +The second type of input file will contain a list of lines (which will typically match +the keys from the first input file). Your program will read one or more of this +type of file. For example, it might contain: + +Jean Luc Picard +Will Riker +Worf +Deanna Troi +Q + +For each such input file that your program reads, it will print out the counts +of the values for the corresponding keys (or <unknown> for anything that did not +match any known key from the first input file). E.g. given the above to input files, +it would print to the corresponding output file (which will be named the same +as the input file, but with ".count" appended to the name). + +Captain: 1 +Commander: 2 +Lt. Commander: 1 +<unknown> : 1 + + + + +In thinking about our program, we might come up with the following +generalized high-level algorithm: + + //read the key/value pairs from the file named by argv[1] (call the result kv) + //count from 2 to argc (call the number you count i) + //count the values that appear in the file named by argv[i], using kv as the key/value pair + // (call this result c) + //compute the output file name from argv[i] (call this outName) + //open the file named by outName (call that f) + //print the counts from c into the FILE f + //close f + //free the memory for outName and c + //free the memory for kv + +This high-level algorithm suggests many functions which we can split our task into. +We will cut them up into 4 groups to make the 4 problems of this assignment: + +The first step (this problem): + - read the key/value pairs from a file + - free the memory for the key/value pairs + +The second step (next problem): + - compute the output file name + +The third step (problem after that): + - print the counts to a file + - free the memory for the counts + +The fourth step (the problem after that): + - compute the counts of values that appear in a particular input file + +Each subsequent problem will have more details about it. + +For this particular problem, you will need to: + + - read the key/value pairs from a file + - free the memory for the key/value pairs + +To start with this problem, you are going to want to define two structs, in the +file kv.h. The first one (struct _kvpair_t) should define the structure for +one key/value pair. The second should define the structure for an +array of key/value pairs (hint: you will want to include the length of the +array in this structure). + +Now you will want to write the four functions in kv.c. + +In readKVs, you will want to open the file, read the lines of text, split them into +key/value pairs, add the resulting pairs to an array (hint: realloc it to make it larger +each time), close the file, and return the kvarray_t * that has your array. + +Remember that you will want to abstract out complex steps into functions (you should +see at least 2 pieces to naturally pull out into their own functions). + +Next, you will write freeKVs, which should free all the memory allocated by readKVs. +That is, freeKVs(readKVs(filename)) should not leak any memory. + +Third, write printKVs which should take a kvarray_t *, and print out + + "key = '%s' value = '%s'\n" +for each key/value pair in the array, with the first %s being whatever the key is, +and the second being whatever value (e.g., key = 'Jean Luc Picard' value = 'Captain'). + +Finally, write the lookupValue function, which takes a kvarray_t * and a char * (string). +The char * that is passed in represents a key. This function searches the kvarray_t +for a matching key, and if found, returns the corresponding value. If no match is found, +this function returns NULL. + +Once you complete these functions, test them using the main in kv_test.c before +proceeding to the next problem. diff --git a/32_kvs/grade.txt b/32_kvs/grade.txt new file mode 100644 index 0000000..241c564 --- /dev/null +++ b/32_kvs/grade.txt @@ -0,0 +1,19 @@ +Grading at Fri 24 Dec 2021 08:54:52 PM UTC +Attempting to compile: +################################################# +testcase1: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/32_kvs/kv.c b/32_kvs/kv.c new file mode 100644 index 0000000..00958c5 --- /dev/null +++ b/32_kvs/kv.c @@ -0,0 +1,87 @@ +#include "kv.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char *splitLine2KV(char *line, const char *delim) { + char *v = strstr(line, delim); + + if (v == NULL) + return NULL; + + *v = '\0'; + + v = v + strlen(delim); + strtok(v, "\n"); + + char *ans = malloc((strlen(v) + 1) * sizeof(*ans)); + strcpy(ans, v); + // return v + strlen(delim); + return ans; +} + +kvarray_t *readKVs(const char *fname) { + FILE *f = fopen(fname, "r"); + if (f == NULL) { + fprintf(stderr, "Could not open file\n"); + return NULL; + } + + kvarray_t *kvArray = malloc(sizeof(*kvArray)); + kvArray->kvarray = NULL; + kvArray->kvarrayLength = 0; + char *line = NULL; + size_t sz = 0; + int i = 0; + char *v = NULL; + + while (getline(&line, &sz, f) >= 0) { + v = splitLine2KV(line, "="); + if (v) { + kvpair_t *kvPair = malloc(sizeof(*kvPair)); + kvPair->key = malloc((strlen(line) + 1) * sizeof(kvPair->key)); + kvPair->value = malloc((strlen(v) + 1) * sizeof(kvPair->value)); + strcpy(kvPair->key, line); + strcpy(kvPair->value, v); + kvArray->kvarray = realloc(kvArray->kvarray, (i + 1) * sizeof(kvpair_t)); + kvArray->kvarray[i] = *kvPair; + i++; + kvArray->kvarrayLength = i; + free(kvPair); + } + free(v); + } + free(line); + + if (fclose(f) != 0) { + fprintf(stderr, "Could not close file\n"); + return NULL; + } + + return kvArray; +} + +void freeKVs(kvarray_t *pairs) { + for (int i = 0; i < pairs->kvarrayLength; i++) { + free(pairs->kvarray[i].key); + free(pairs->kvarray[i].value); + } + free(pairs->kvarray); + free(pairs); +} + +void printKVs(kvarray_t *pairs) { + for (int i = 0; i < pairs->kvarrayLength; i++) { + printf("key = '%s' value = '%s'\n", pairs->kvarray[i].key, + pairs->kvarray[i].value); + } +} + +char *lookupValue(kvarray_t *pairs, const char *key) { + for (int i = 0; i < pairs->kvarrayLength; i++) { + if (strcmp(pairs->kvarray[i].key, key) == 0) { + return pairs->kvarray[i].value; + } + } + return NULL; +} diff --git a/32_kvs/kv.c~ b/32_kvs/kv.c~ new file mode 100644 index 0000000..d215207 --- /dev/null +++ b/32_kvs/kv.c~ @@ -0,0 +1,81 @@ +#include "kv.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char *splitLine2KV(char *line, const char *delim) { + char *v = strstr(line, delim); + + if (v == NULL) + return NULL; + + *v = '\0'; + return v + strlen(delim); +} + +kvarray_t *readKVs(const char *fname) { + FILE *f = fopen(fname, "r"); + if (f == NULL) { + fprintf(stderr, "Could not open file\n"); + return NULL; + } + + kvarray_t *kvArray = malloc(sizeof(*kvArray)); + kvArray->kvarray = NULL; + char *line = NULL; + size_t sz = 0; + int i = 0; + + while (getline(&line, &sz, f) >= 0) { + char *v; + v = splitLine2KV(line, "="); + if (v) { + char *value = malloc((strlen(v) + 1) * sizeof(*value)); + strcpy(value, strtok(v, "\n")); + char *key = malloc((strlen(line) + 1) * sizeof(*key)); + strcpy(key, line); + + kvpair_t *kvPair = malloc(sizeof(kvPair)); + kvPair->key = key; + kvPair->value = value; + kvArray->kvarray = realloc(kvArray->kvarray, (i + 1) * sizeof(kvpair_t)); + kvArray->kvarray[i] = *kvPair; + free(kvPair); + i++; + kvArray->kvarrayLength = i; + } + } + free(line); + + if (fclose(f) != 0) { + fprintf(stderr, "Could not close file\n"); + return NULL; + } + + return kvArray; +} + +void freeKVs(kvarray_t *pairs) { + for (int i = 0; i < pairs->kvarrayLength; i++) { + free(pairs->kvarray[i].key); + free(pairs->kvarray[i].value); + } + free(pairs->kvarray); + free(pairs); +} + +void printKVs(kvarray_t *pairs) { + for (int i = 0; i < pairs->kvarrayLength; i++) { + printf("key = '%s' value = '%s'\n", pairs->kvarray[i].key, + pairs->kvarray[i].value); + } +} + +char *lookupValue(kvarray_t *pairs, const char *key) { + for (int i = 0; i < pairs->kvarrayLength; i++) { + if (strcmp(pairs->kvarray[i].key, key) == 0) { + return pairs->kvarray[i].value; + } + } + return NULL; +} diff --git a/32_kvs/kv.h b/32_kvs/kv.h new file mode 100644 index 0000000..51ccbb1 --- /dev/null +++ b/32_kvs/kv.h @@ -0,0 +1,26 @@ +#ifndef __KV_H__ +#define __KV_H__ + + +struct _kvpair_t { + char * key; + char * value; +}; +typedef struct _kvpair_t kvpair_t; + +struct _kvarray_t { + kvpair_t * kvarray; + int kvarrayLength; +}; +typedef struct _kvarray_t kvarray_t; + + +kvarray_t * readKVs(const char * fname); + +void freeKVs(kvarray_t * pairs); + +void printKVs(kvarray_t * pairs); + +char * lookupValue(kvarray_t * pairs, const char * key); + +#endif diff --git a/32_kvs/kv.o b/32_kvs/kv.o Binary files differnew file mode 100644 index 0000000..017f5db --- /dev/null +++ b/32_kvs/kv.o diff --git a/32_kvs/kv_test b/32_kvs/kv_test Binary files differnew file mode 100755 index 0000000..3aa5b6e --- /dev/null +++ b/32_kvs/kv_test diff --git a/32_kvs/kv_test.c b/32_kvs/kv_test.c new file mode 100644 index 0000000..5532512 --- /dev/null +++ b/32_kvs/kv_test.c @@ -0,0 +1,17 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "kv.h" + +#define NUM_LOOKUPS 5 +int main(void) { + kvarray_t * array = readKVs("test.txt"); + printf("Printing all keys\n\n"); + printKVs(array); + char *tests[NUM_LOOKUPS] = {"banana", "grapes", "cantaloupe", "lettuce", "orange"}; + for (int i = 0; i < NUM_LOOKUPS; i++) { + printf("lookupValue('%s')=%s\n", tests[i], lookupValue(array,tests[i])); + } + freeKVs(array); + return EXIT_SUCCESS; +} diff --git a/32_kvs/kv_test.o b/32_kvs/kv_test.o Binary files differnew file mode 100644 index 0000000..458acf1 --- /dev/null +++ b/32_kvs/kv_test.o diff --git a/32_kvs/test.old b/32_kvs/test.old new file mode 100644 index 0000000..782743e --- /dev/null +++ b/32_kvs/test.old @@ -0,0 +1,6 @@ +apple=red +banana=yellow +orange=orange +grapes=purple +carrot=orange +eggplant=purple diff --git a/32_kvs/test.txt b/32_kvs/test.txt new file mode 100644 index 0000000..c812bb6 --- /dev/null +++ b/32_kvs/test.txt @@ -0,0 +1,3 @@ +a +bc +df diff --git a/33_counts/Makefile b/33_counts/Makefile new file mode 100644 index 0000000..700ebd4 --- /dev/null +++ b/33_counts/Makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror -std=gnu99 -pedantic -ggdb3 +OBJS=counts.o counts_test.o +PROGRAM=counts_test + +$(PROGRAM): $(OBJS) + gcc $(CFLAGS) -o $@ $(OBJS) + +%.o: %.c counts.h + gcc -c $(CFLAGS) $< + +clean: + rm -f $(OBJS) $(PROGRAM) *~ diff --git a/33_counts/README b/33_counts/README new file mode 100644 index 0000000..986af21 --- /dev/null +++ b/33_counts/README @@ -0,0 +1,58 @@ +For this problem, we will address the following tasks: + + - print the counts to a file + - free the memory for the counts + +We'll note that we are not going to write the part of this program where +we read the input file and compute the counts until the next problem. However, we will +still want to be able to test our code. We can do this, by having a main +function which constructs the counts from a hard coded set of data, skipping +the details of the actual program (this is an example of a test scaffold). + +Our test scaffold can benefit from some functionality that (if we think a bit ahead) +will be useful to abstract out into a couple functions, so we can re-use that code +in the next problem. (Abstracting all of this code out into function is also good because +it hides the implementation details: none of the code in the main function +we provide cares what the names/types of the fields in the counts_t structure +are, which you will make shortly). + +First, go to counts.h. Here, you will find two empty struct declarations. You will +need to fill these in. The first should reflect the information about one count. +That is, for some particular string, how many times have we seen it so far. +The second, should have an array of the first, as well as the size of that array. +You should also include a field in this struct to count unknown names. + +Next, you should go to counts.c, and write the four functions there. + +The first, createCounts should allocate memory for a counts_t structure, and initialize +it to represent that nothing has been counted yet. + +The next function, addCount, should increment the count for the corresponding name. Note +that name will be NULL in the case of something that is unknown, so your code must account +for this case. + +The third function, printCounts takes a counts_t and prints that information to +the FILE outFile. Recall from the description of the entire problem, that this +function should print in the format: + +Captain: 1 +Commander: 2 +Lt. Commander: 1 +<unknown> : 1 + +These should appear in the order that the name is first added, with unknown always +appearing last. + +***If there are no unknown values, you should not print a line for unknown. That +is, you should NEVEr print +<unknown> : 0 + + +Finally, you should write freeCounts, which should free all the memory associated with +a counts_t. + +We have provided a main in countsTestc which creates a counts_t (using your createCounts +function), adds some names to it (using your addCount function), prints the result +to stdout (using your printCounts) function, then frees the memory (using your freeCounts). + +Test and debug these functions before proceeding. diff --git a/33_counts/counts.c b/33_counts/counts.c new file mode 100644 index 0000000..c69f9aa --- /dev/null +++ b/33_counts/counts.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "counts.h" +counts_t * createCounts(void) { + counts_t * c = malloc(sizeof(* c)); + c->countArray = NULL; + c->arraySize = 0; + c->count_of_unknowns = 0; + return c; +} + +void addCount(counts_t * c, const char * name) { + if (name == NULL) { + c->count_of_unknowns++; + return; + } + + for (int i = 0; i < c->arraySize; i++) { + if (strcmp(name, c->countArray[i].string) == 0) { + c->countArray[i].count++; + return; + } + } + + one_count_t * newCount = malloc(sizeof(one_count_t)); + newCount->string = malloc((strlen(name) + 1) * sizeof(char)); + strcpy(newCount->string, name); + newCount->count = 1; + c->countArray = realloc(c->countArray, (c->arraySize + 1) * sizeof(one_count_t)); + c->countArray[c->arraySize] = *newCount; + c->arraySize++; + free(newCount); + +} +void printCounts(counts_t * c, FILE * outFile) { + for (int i = 0; i < c->arraySize; i++) { + fprintf(outFile, "%s: %d\n", c->countArray[i].string, c->countArray[i].count); + } + + if (c->count_of_unknowns > 0) { + fprintf(outFile, "%s: %d\n", "<unknown> ", c->count_of_unknowns); + } + + if(fclose(outFile) != 0) { + fprintf(stderr, "oh no, couldn't close the file!\n"); + } +} + +void freeCounts(counts_t * c) { + for (int i = 0; i < c->arraySize; i++) { + free(c->countArray[i].string); + } + free(c->countArray); + free(c); +} diff --git a/33_counts/counts.c~ b/33_counts/counts.c~ new file mode 100644 index 0000000..819726a --- /dev/null +++ b/33_counts/counts.c~ @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "counts.h" +counts_t * createCounts(void) { + counts_t c = malloc(sizeof(counts_t)); + c.countArray = NULL; + c.arraySize = 0; + c.count_of_unknowns = 0; +} + +void addCount(counts_t * c, const char * name) { + if (name == NULL) { + c.count_of_unknowns++; + return; + } + + for (int i = 0; i < c.arraySize; i++) { + if (strcmp(name, c.countArray[i].string) == 0) { + c.countArray[i].count++; + return; + } + } +} +void printCounts(counts_t * c, FILE * outFile) { + //WRITE ME +} + +void freeCounts(counts_t * c) { + //WRITE ME +} diff --git a/33_counts/counts.h b/33_counts/counts.h new file mode 100644 index 0000000..cf0783c --- /dev/null +++ b/33_counts/counts.h @@ -0,0 +1,23 @@ +#include <stdio.h> +#ifndef __COUNTS_H__ +#define __COUNTS_H__ +struct _one_count_t { + char * string; + int count; +}; +typedef struct _one_count_t one_count_t; + +struct _counts_t { + one_count_t * countArray; + int arraySize; + int count_of_unknowns; +}; +typedef struct _counts_t counts_t; + +counts_t * createCounts(void); +void addCount(counts_t * c, const char * name); +void printCounts(counts_t * c, FILE * outFile); + +void freeCounts(counts_t * c); + +#endif diff --git a/33_counts/counts.h~ b/33_counts/counts.h~ new file mode 100644 index 0000000..18f28c4 --- /dev/null +++ b/33_counts/counts.h~ @@ -0,0 +1,20 @@ +#ifndef __COUNTS_H__ +#define __COUNTS_H__ +struct _one_count_t { + //DEFINE ME + +}; +typedef struct _one_count_t one_count_t; + +struct _counts_t { + //DEFINE ME +}; +typedef struct _counts_t counts_t; + +counts_t * createCounts(void); +void addCount(counts_t * c, const char * name); +void printCounts(counts_t * c, FILE * outFile); + +void freeCounts(counts_t * c); + +#endif diff --git a/33_counts/counts.o b/33_counts/counts.o Binary files differnew file mode 100644 index 0000000..00cf023 --- /dev/null +++ b/33_counts/counts.o diff --git a/33_counts/counts_test b/33_counts/counts_test Binary files differnew file mode 100755 index 0000000..fd87286 --- /dev/null +++ b/33_counts/counts_test diff --git a/33_counts/counts_test.c b/33_counts/counts_test.c new file mode 100644 index 0000000..905d918 --- /dev/null +++ b/33_counts/counts_test.c @@ -0,0 +1,18 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "counts.h" + +#define NUM_TESTS 12 +int main(void) { + char * testData[NUM_TESTS] = {"apple", "banana", NULL,"apple", + "frog","sword","bear",NULL, + "frog","apple", "zebra", "knight"}; + counts_t * testCounts= createCounts(); + for(int i =0; i < NUM_TESTS; i++) { + addCount(testCounts,testData[i]); + } + printCounts(testCounts, stdout); + freeCounts(testCounts); + return EXIT_SUCCESS; +} diff --git a/33_counts/counts_test.o b/33_counts/counts_test.o Binary files differnew file mode 100644 index 0000000..6da765e --- /dev/null +++ b/33_counts/counts_test.o diff --git a/33_counts/grade.txt b/33_counts/grade.txt new file mode 100644 index 0000000..844521f --- /dev/null +++ b/33_counts/grade.txt @@ -0,0 +1,19 @@ +Grading at Sat 25 Dec 2021 01:42:38 AM UTC +Attempting to compile: +################################################# +testcase1: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/34_put_together/Makefile b/34_put_together/Makefile new file mode 100644 index 0000000..9281640 --- /dev/null +++ b/34_put_together/Makefile @@ -0,0 +1,20 @@ +CFLAGS=-Wall -Werror -std=gnu99 -pedantic -ggdb3 +SRCS=$(wildcard *.c) +OBJS=$(patsubst %.c, %.o, $(SRCS)) +PROGRAM=count_values + +$(PROGRAM): $(OBJS) + gcc $(CFLAGS) -o $@ $(OBJS) + +%.o: %.c + gcc -c $(CFLAGS) $< + +clean: + rm -f $(OBJS) $(PROGRAM) *~ + +counts.o: counts.h +outname.o: outname.h +kv.o: kv.h +main.o: kv.h +main.o: outname.h +main.o: counts.h diff --git a/34_put_together/README b/34_put_together/README new file mode 100644 index 0000000..b438ead --- /dev/null +++ b/34_put_together/README @@ -0,0 +1,41 @@ +We are now ready for the last piece: + - compute the counts of values that appear in a particular input file + +And then to put all the pieces together. Before you start, notice that +we have placed symlinks (short for "symbolic links") to the files you worked on +in the previous problems. Symbolic links basically mean that when you open +the file, it will open the file it links to (so opening counts.c will open +../27_counts/counts.c ). + +For this problem, you will start by writing the function: + + counts_t * countFile(const char * filename, kvarray_t * kvPairs) + +in the main.c file. Note that you will find it quite helpful to use several of the functions +you wrote in the previous problems (in fact, much of the work should already be done). + +Once you have written countFile, it is time to write your main function. You +will also write this function in the main.c file. Note that we have already +written the high-level algorithm for the main function as comments, so you can +just translate this algorithm to code. You will also need to add some error +checking. + +Once you finish writing these two functions, you should have a working program! +Compile, test, and debug it. + +We have provided two test cases, and the correct output for them. + +The first test case: + ./count_values kvs1.txt list1a.txt list1b.txt + +should produce two output files (list1a.txt.counts and list1b.txt.counts). +The correct contents can be found in list1a.txt.ans and list1b.txt.ans. + +The second test case: + ./count_values kvs2.txt list2a.txt list2b.txt list2c.txt + +should produce 3 files (named appropriately) and the answers can be found in +similarly named .ans files. + +Use git add . to submit your work. + diff --git a/34_put_together/count_values b/34_put_together/count_values Binary files differnew file mode 100755 index 0000000..772972a --- /dev/null +++ b/34_put_together/count_values diff --git a/34_put_together/counts.c b/34_put_together/counts.c new file mode 120000 index 0000000..6315a63 --- /dev/null +++ b/34_put_together/counts.c @@ -0,0 +1 @@ +../33_counts/counts.c
\ No newline at end of file diff --git a/34_put_together/counts.h b/34_put_together/counts.h new file mode 120000 index 0000000..12e8e77 --- /dev/null +++ b/34_put_together/counts.h @@ -0,0 +1 @@ +../33_counts/counts.h
\ No newline at end of file diff --git a/34_put_together/counts.o b/34_put_together/counts.o Binary files differnew file mode 100644 index 0000000..2ef87cd --- /dev/null +++ b/34_put_together/counts.o diff --git a/34_put_together/grade.txt b/34_put_together/grade.txt new file mode 100644 index 0000000..9b57db2 --- /dev/null +++ b/34_put_together/grade.txt @@ -0,0 +1,45 @@ +Grading at Sat 25 Dec 2021 08:12:05 PM UTC +Attempting to compile: +rm -f outname.o counts.o main.o kv.o count_values *~ +gcc -c -Wall -Werror -std=gnu99 -pedantic -ggdb3 outname.c +gcc -c -Wall -Werror -std=gnu99 -pedantic -ggdb3 counts.c +gcc -c -Wall -Werror -std=gnu99 -pedantic -ggdb3 main.c +gcc -c -Wall -Werror -std=gnu99 -pedantic -ggdb3 kv.c +gcc -Wall -Werror -std=gnu99 -pedantic -ggdb3 -o count_values outname.o counts.o main.o kv.o +################################################# +testcase1: +testcase1 passed, your program successfully indicated a failure + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: +Your file matched the expected output +Comparing file list1a.txt.counts with answer +Your output is correct +Comparing file list1b.txt.counts with answer +Your file matched the expected output +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: +Your file matched the expected output +Comparing file list2a.txt.counts with answer +Your output is correct +Comparing file list2b.txt.counts with answer +Your file matched the expected output +Your output is correct +Comparing file list2c.txt.counts with answer +Your file matched the expected output +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase4: +Your file matched the expected output +Comparing file list3a.txt.counts with answer +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/34_put_together/kv.c b/34_put_together/kv.c new file mode 120000 index 0000000..2c9f389 --- /dev/null +++ b/34_put_together/kv.c @@ -0,0 +1 @@ +../32_kvs/kv.c
\ No newline at end of file diff --git a/34_put_together/kv.h b/34_put_together/kv.h new file mode 120000 index 0000000..11e307b --- /dev/null +++ b/34_put_together/kv.h @@ -0,0 +1 @@ +../32_kvs/kv.h
\ No newline at end of file diff --git a/34_put_together/kv.o b/34_put_together/kv.o Binary files differnew file mode 100644 index 0000000..c3fef3a --- /dev/null +++ b/34_put_together/kv.o diff --git a/34_put_together/kvs1.txt b/34_put_together/kvs1.txt new file mode 100644 index 0000000..a51bda3 --- /dev/null +++ b/34_put_together/kvs1.txt @@ -0,0 +1,21 @@ +apple=red +apricot=yellow +avacado=green +banana=yellow +blueberry=blue +carrot=orange +cherry=red +cranberry=red +dates=brown +eggplant=purple +grapefruit=pink +grapes=purple +kiwi=green +lime=green +orange=orange +peach=yellow +pineapple=yellow +plums=purple +pomegranate=red +strawberry=red +tomato=red diff --git a/34_put_together/kvs2.txt b/34_put_together/kvs2.txt new file mode 100644 index 0000000..14b41db --- /dev/null +++ b/34_put_together/kvs2.txt @@ -0,0 +1,12 @@ +Jean Luc Picard=Captain +Will Riker=Commander +Beverly Crusher=Commander +Data=Lt. Commander +Geordi LaForge=Lt. Commander +Worf=Lt. Commander +Deanna Troi=Commander +Tasha Yar=Lieutenant +Wesley Crusher=Ensign +Ro Laren=Ensign +Reginald Barclay=Lieutenant +Guinan=Bartender diff --git a/34_put_together/list1a.txt b/34_put_together/list1a.txt new file mode 100644 index 0000000..aea3f25 --- /dev/null +++ b/34_put_together/list1a.txt @@ -0,0 +1,11 @@ +apple +avacado +raspberry +blueberry +cherry +eggplant +grapes +peach +pineapple +strawberry +fig diff --git a/34_put_together/list1a.txt.ans b/34_put_together/list1a.txt.ans new file mode 100644 index 0000000..2c282ef --- /dev/null +++ b/34_put_together/list1a.txt.ans @@ -0,0 +1,6 @@ +red: 3 +green: 1 +blue: 1 +purple: 2 +yellow: 2 +<unknown> : 2 diff --git a/34_put_together/list1a.txt.counts b/34_put_together/list1a.txt.counts new file mode 100644 index 0000000..2c282ef --- /dev/null +++ b/34_put_together/list1a.txt.counts @@ -0,0 +1,6 @@ +red: 3 +green: 1 +blue: 1 +purple: 2 +yellow: 2 +<unknown> : 2 diff --git a/34_put_together/list1b.txt b/34_put_together/list1b.txt new file mode 100644 index 0000000..db512c9 --- /dev/null +++ b/34_put_together/list1b.txt @@ -0,0 +1,10 @@ +kiwi +lime +pineapple +pomegranate +raisins +apple +blueberry +carrot +cherry +dates diff --git a/34_put_together/list1b.txt.ans b/34_put_together/list1b.txt.ans new file mode 100644 index 0000000..868b5d0 --- /dev/null +++ b/34_put_together/list1b.txt.ans @@ -0,0 +1,7 @@ +green: 2 +yellow: 1 +red: 3 +blue: 1 +orange: 1 +brown: 1 +<unknown> : 1 diff --git a/34_put_together/list1b.txt.counts b/34_put_together/list1b.txt.counts new file mode 100644 index 0000000..868b5d0 --- /dev/null +++ b/34_put_together/list1b.txt.counts @@ -0,0 +1,7 @@ +green: 2 +yellow: 1 +red: 3 +blue: 1 +orange: 1 +brown: 1 +<unknown> : 1 diff --git a/34_put_together/list2a.txt b/34_put_together/list2a.txt new file mode 100644 index 0000000..ae4e862 --- /dev/null +++ b/34_put_together/list2a.txt @@ -0,0 +1,5 @@ +Will Riker +Worf +Tasha Yar +Guinan +Ro Laren diff --git a/34_put_together/list2a.txt.ans b/34_put_together/list2a.txt.ans new file mode 100644 index 0000000..bcdabbc --- /dev/null +++ b/34_put_together/list2a.txt.ans @@ -0,0 +1,5 @@ +Commander: 1 +Lt. Commander: 1 +Lieutenant: 1 +Bartender: 1 +Ensign: 1 diff --git a/34_put_together/list2b.txt b/34_put_together/list2b.txt new file mode 100644 index 0000000..219ed60 --- /dev/null +++ b/34_put_together/list2b.txt @@ -0,0 +1,8 @@ +Jean Luc Picard +Q +Geordi LaForge +Some guy in a red shirt +Reginald Barclay +Beverly Crusher +Data +Worf diff --git a/34_put_together/list2b.txt.ans b/34_put_together/list2b.txt.ans new file mode 100644 index 0000000..b2abd8e --- /dev/null +++ b/34_put_together/list2b.txt.ans @@ -0,0 +1,5 @@ +Captain: 1 +Lt. Commander: 3 +Lieutenant: 1 +Commander: 1 +<unknown> : 2 diff --git a/34_put_together/list2c.txt b/34_put_together/list2c.txt new file mode 100644 index 0000000..f6e8463 --- /dev/null +++ b/34_put_together/list2c.txt @@ -0,0 +1,8 @@ +Data +Geordi LaForge +Jean Luc Picard +Tasha Yar +Ro Laren +Spock +James T Kirk +Katherine Janeway diff --git a/34_put_together/list2c.txt.ans b/34_put_together/list2c.txt.ans new file mode 100644 index 0000000..3f33b39 --- /dev/null +++ b/34_put_together/list2c.txt.ans @@ -0,0 +1,5 @@ +Lt. Commander: 2 +Captain: 1 +Lieutenant: 1 +Ensign: 1 +<unknown> : 3 diff --git a/34_put_together/main.c b/34_put_together/main.c new file mode 100644 index 0000000..6e4f508 --- /dev/null +++ b/34_put_together/main.c @@ -0,0 +1,69 @@ +#include "counts.h" +#include "kv.h" +#include "outname.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +counts_t *countFile(const char *filename, kvarray_t *kvPairs) { + FILE *f = fopen(filename, "r"); + if (f == NULL) { + fprintf(stderr, "Could not open file!\n"); + return NULL; + } + + counts_t *c = createCounts(); + + char *line = NULL; + size_t sz; + + while (getline(&line, &sz, f) >= 0) { + strtok(line, "\n"); + addCount(c, lookupValue(kvPairs, line)); + } + free(line); + + if (fclose(f) != 0) { + fprintf(stderr, "Could not close file!\n"); + return NULL; + } + return c; +} + +int main(int argc, char **argv) { + // read the key/value pairs from the file named by argv[1] (call the result + // kv) + if (argc == 1) { + fprintf(stderr, "no parameters\n"); + return EXIT_FAILURE; + } + kvarray_t *kv = readKVs(argv[1]); + + // count from 2 to argc (call the number you count i) + for (int i = 2; i < argc; i++) { + // count the values that appear in the file named by argv[i], using kv as + // the key/value pair + // (call this result c) + counts_t * c = countFile(argv[i], kv); + + // compute the output file name from argv[i] (call this outName) + char *outName = computeOutputFileName(argv[i]); + + // open the file named by outName (call that f) + FILE *f = fopen(outName, "w"); + + // print the counts from c into the FILE f + printCounts(c, f); + + // close f + + // free the memory for outName and c + freeCounts(c); + free(outName); + } + + // free the memory for kv + freeKVs(kv); + + return EXIT_SUCCESS; +} diff --git a/34_put_together/main.c~ b/34_put_together/main.c~ new file mode 100644 index 0000000..4a3ac74 --- /dev/null +++ b/34_put_together/main.c~ @@ -0,0 +1,49 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "kv.h" +#include "counts.h" +#include "outname.h" + +counts_t * countFile(const char * filename, kvarray_t * kvPairs) { + FILE *f = fopen(filename, "r"); + if (f == NULL) { + fprintf(stderr, "Could not open file!\n"); + return NULL; + } + + counts_t * c = createCounts(); + + if (fclose(f) != 0) { + fprintf(stderr, "Could not close file!\n"); + return NULL; + } + return c; +} + +int main(int argc, char ** argv) { + //WRITE ME (plus add appropriate error checking!) + //read the key/value pairs from the file named by argv[1] (call the result kv) + + //count from 2 to argc (call the number you count i) + + //count the values that appear in the file named by argv[i], using kv as the key/value pair + // (call this result c) + + //compute the output file name from argv[i] (call this outName) + + + //open the file named by outName (call that f) + + //print the counts from c into the FILE f + + //close f + + //free the memory for outName and c + + + + //free the memory for kv + + return EXIT_SUCCESS; +} diff --git a/34_put_together/main.o b/34_put_together/main.o Binary files differnew file mode 100644 index 0000000..5754813 --- /dev/null +++ b/34_put_together/main.o diff --git a/34_put_together/outname.c b/34_put_together/outname.c new file mode 120000 index 0000000..d4e49b9 --- /dev/null +++ b/34_put_together/outname.c @@ -0,0 +1 @@ +../29_outname/outname.c
\ No newline at end of file diff --git a/34_put_together/outname.h b/34_put_together/outname.h new file mode 120000 index 0000000..782a064 --- /dev/null +++ b/34_put_together/outname.h @@ -0,0 +1 @@ +../29_outname/outname.h
\ No newline at end of file diff --git a/34_put_together/outname.o b/34_put_together/outname.o Binary files differnew file mode 100644 index 0000000..bc7aa49 --- /dev/null +++ b/34_put_together/outname.o diff --git a/34_put_together/vgcore.49132 b/34_put_together/vgcore.49132 Binary files differnew file mode 100644 index 0000000..f65d775 --- /dev/null +++ b/34_put_together/vgcore.49132 diff --git a/34_put_together/vgcore.49206 b/34_put_together/vgcore.49206 Binary files differnew file mode 100644 index 0000000..43d8df9 --- /dev/null +++ b/34_put_together/vgcore.49206 @@ -0,0 +1,14 @@ +Welcome to the Practice Programming Environment. + +This is where +This is your directory for the assignments in this +specialization. To do the first assignment: + +cd 00_hello + +There, you will find a README with instructions. +Once you do them and pass that assignment, +the Practice Programming Environment will +automatically give you the next assignment. +You should then continue readings and videos +in Coursera until you are ready for that assignment. diff --git a/c2prj1_cards/.gitignore b/c2prj1_cards/.gitignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/c2prj1_cards/.gitignore @@ -0,0 +1 @@ +test diff --git a/c2prj1_cards/Makefile b/c2prj1_cards/Makefile new file mode 100644 index 0000000..be1c5b4 --- /dev/null +++ b/c2prj1_cards/Makefile @@ -0,0 +1,9 @@ +CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99 +GIVEN_OBJS=deck.o eval.o future.o input.o main.o eval-c4.o deck-c4.o + +test: cards.o my-test-main.o + gcc -o test -ggdb3 cards.o my-test-main.o +poker: $(GIVEN_OBJS) cards.o + gcc -o poker -ggdb3 cards.o $(GIVEN_OBJS) +clean: + rm test poker cards.o my-test-main.o *~ diff --git a/c2prj1_cards/README b/c2prj1_cards/README new file mode 100644 index 0000000..73848b1 --- /dev/null +++ b/c2prj1_cards/README @@ -0,0 +1,179 @@ +At the end of each course, you will be working on building +a program that estimates the chances of each hand +winning in poker in a situation described by an input file. + +In this portion of the project, you are going write some +functions that work with cards (specifically, a struct +that represents a card): printing them +in human-readable format, converting the pair of letters +that describe a card back into a struct (which gets +used to read the input from a file), etc. + +There is a lot that will be required to complete +the project that you will learn in the later +courses (e.g., arrays, strings, dynamic memory allocation, +file IO). To make it so you can still run the poker +simulation when you complete this project, we have provided +object files (.o) for the later parts. The included +Makefile will build your cards.c with our .o files +if you do: + +make poker + +You'll write all these parts later on, when you +finish Courses 3 and 4 and have learned the +corresponding concepts. + +In the meantime, you can test your functions +for this assignment by writing any code you +want in my-test-main.c. If you do "make" +(or "make test") then the included Makefile +will build this and link it with your cards.o +(compiling that if needed). + +To get started, take a look at cards.h. + +You will see that it starts by defining +an enum suits (SPADES, HEARTS, DIAMONDS, +and CLUBS). This enum also has NUM_SUITS, +which will have a numeric value of 4 (indicating +how many suits there are), and can also +be used to indicate an invalid suit. + +Next, you will see a struct for a card. +This struct has two parts, a value +(2,3,4,5,6,7,8,9,10,J,Q,K,A) and a suit (s,h,d,c). +Following the struct declaration, there +are some #defines for constants for +the values of Ace, King, Queen, and Jack. +Accordingly, a card's value should +be between 2 and 14 (inclusive). + +There is also an enum for the hand +ranking (what kind of poker hand you get). +We won't be doing anything with these +at this point, except for writing a function +to convert from the enumerated values +to a string. + +Last are some function prototypes. +You will write each of these in cards.c. + +Now go into cards.c, and write each of these +functions. Here are the specifics: + +- void assert_card_valid(card_t c); + This function should use assert() to check + that the card passed in has valid values. + In particular, its value should be between + 2 and VALUE_ACE (inclusive of both), + and its suit should be between SPADES + and CLUBS (inclusive of both). + +- const char * ranking_to_string(hand_ranking_t r); + This function should convert the + hand_ranking_t enumerated value passed + in to a string that describes it. Remember + that Drew showed you a nice way to do this + with emacs keyboard macros! + +- char value_letter(card_t c); + This function should return the character that textually represents + the value of the passed-in card. For values 2-9, this should + be that digit. For 10, it should be '0', and for Jack, Queen, King, and Ace, + it should be 'J', 'Q', 'K', and 'A' respectively. + Hint: remember everything is a number. + For example, the character '0' has the decimal value 48, + and the character '5' has the decimal value 53, so you could represent + '5' as '0' + 5. + +- char suit_letter(card_t c); + This function should return the letter that textually represents + the suit of the card passed in ('s', 'h', 'd', or 'c' for SPADES, + HEARTS, DIAMONDS, or CLUBS). + +- void print_card(card_t c); + This function should print out the textual + representation of the card (hint: use the functions + you previously wrote). It should print + the value first, then the suit. For example, + As (for Ace of spades) + 0d (for 10 of diamonds) + Kc (for King of clubs) etc. + This function should not print any additional + spaces or newlines after the card's text. + +- card_t card_from_letters(char value_let, char suit_let); + This function should make and return a + card_t whose value and suit correspond + to the letters passed in. If the values passed + in are invalid, you should use assert() + or print an error message and exit(EXIT_FAILURE). + +- card_t card_from_num(unsigned c); + This function should take a number from 0 (inclusive) + to 52 (exclusive) and map it uniquely to + a card value/suit combination. Exactly + how you map the numbers to values/suits + is up to you, but you must guarantee + that each valid value/suit combination + corresponds to exactly one input value + in the range [0,52). Hint: you may want to use the mod + operator % to find the remainder of a number divided by 13. + (In Course 3, this function will be used + to make a deck of cards by iterating + over that range and calling it once + for each value--you just need + to learn about arrays first so you + have a place to put all those + cards.) + +---------------------------------------------------- +Once you have done all of these (and tested +them to your satisfaction with my-test-main.c), +you can + +make poker + +and try out the poker odds computation. It +requires one command line argument--the input file to read. +In the input file, +each line corresponds to one hand and lists +the cards (with textual representation +you were working with above). It also +has placeholders for future cards, which +are a ? followed by a number. For example, +this input: + +As Ah Kc Qd 6c ?0 ?1 +2c 3d Kc Qd 6c ?0 ?1 +Ks Qs Kc Qd 6c ?0 ?1 + +describes 3 hands (as might occur +in a game of Texas Hold'em). All +three hands share the King of clubs, +the Queen of diamonds, and the 6 +of clubs (called the "flop" +in Texas Hold'em--these are the +3rd, 4th, and 5th cards). Each +hand has its own private cards +to start (the first has the +Ace of Spades and the Ace of Hearts, +for example). + +The remainder of the hand will be +played by dealing two more cards +(?0 and ?1), which will be shared +by the three hands. + +You could also craft an input +where each player's cards are private +(no cards shared), such as this: + +As Kh ?0 ?1 ?2 +Ac Kc ?3 ?4 ?5 +Ad Ah ?6 ?7 ?8 + +9 cards remain in the future (?0 +through ?8), each appearing exactly +once in one hand. diff --git a/c2prj1_cards/cards.c b/c2prj1_cards/cards.c new file mode 100644 index 0000000..c335826 --- /dev/null +++ b/c2prj1_cards/cards.c @@ -0,0 +1,131 @@ +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> +#include "cards.h" + + +void assert_card_valid(card_t c) { + assert(c.value >= 2 && c.value <= VALUE_ACE); + assert(c.suit >= SPADES && c.suit <= CLUBS); +} + +const char * ranking_to_string(hand_ranking_t r) { + switch (r) { + case STRAIGHT_FLUSH: + return "STRAIGHT_FLUSH"; + case FOUR_OF_A_KIND: + return "FOUR_OF_A_KIND"; + case FULL_HOUSE: + return "FULL_HOUSE"; + case FLUSH: + return "FLUSH"; + case STRAIGHT: + return "STRAIGHT"; + case THREE_OF_A_KIND: + return "THREE_OF_A_KIND"; + case TWO_PAIR: + return "TWO_PAIR"; + case PAIR: + return "PAIR"; + default: + return "NOTHING"; + } +} + +char value_letter(card_t c) { + switch(c.value) { + case VALUE_ACE: + return 'A'; + case VALUE_KING: + return 'K'; + case VALUE_QUEEN: + return 'Q'; + case VALUE_JACK: + return 'J'; + case 10: + return '0'; + default: + return '0' + c.value; + } +} + + +char suit_letter(card_t c) { + switch(c.suit) { + case SPADES: + return 's'; + case HEARTS: + return 'h'; + case DIAMONDS: + return 'd'; + default: + return 'c'; + } + +} + +void print_card(card_t c) { + printf("%c%c", value_letter(c), suit_letter(c)); +} + +card_t card_from_letters(char value_let, char suit_let) { + card_t temp; + switch(value_let) { + case 'A': + temp.value = VALUE_ACE; + break; + case 'K': + temp.value = VALUE_KING; + break; + case 'Q': + temp.value = VALUE_QUEEN; + break; + case 'J': + temp.value = VALUE_JACK; + break; + case '0': + temp.value = 10; + break; + default: + temp.value = value_let - '0'; + break; + } + switch(suit_let) { + case 's': + temp.suit = SPADES; + break; + case 'h': + temp.suit = HEARTS; + break; + case 'd': + temp.suit = DIAMONDS; + break; + case 'c': + temp.suit = CLUBS; + break; + } + assert_card_valid(temp); + return temp; +} + +card_t card_from_num(unsigned c) { + card_t temp; + if (c <= 12) { + temp.value = c + 2; + temp.suit = SPADES; + } + else if (c > 12 && c <= 25) { + temp.value = c % 13 + 2; + temp.suit = HEARTS; + } + else if (c > 25 && c <= 38) { + temp.value = c % 13 + 2; + temp.suit = DIAMONDS; + } + else { + temp.value = c % 13 + 2; + temp.suit = CLUBS; + } + assert_card_valid(temp); + return temp; +} diff --git a/c2prj1_cards/cards.h b/c2prj1_cards/cards.h new file mode 100644 index 0000000..fef0529 --- /dev/null +++ b/c2prj1_cards/cards.h @@ -0,0 +1,38 @@ +#ifndef CARD_H +#define CARD_H +#define VALUE_ACE 14 +#define VALUE_KING 13 +#define VALUE_QUEEN 12 +#define VALUE_JACK 11 +typedef enum { + SPADES, + HEARTS, + DIAMONDS, + CLUBS, + NUM_SUITS +} suit_t; + +struct card_tag { + unsigned value; + suit_t suit; +}; +typedef struct card_tag card_t; +typedef enum { + STRAIGHT_FLUSH, + FOUR_OF_A_KIND, + FULL_HOUSE, + FLUSH, + STRAIGHT, + THREE_OF_A_KIND, + TWO_PAIR, + PAIR, + NOTHING +} hand_ranking_t; +card_t card_from_num(unsigned c); +void assert_card_valid(card_t c); +const char * ranking_to_string(hand_ranking_t r) ; +char value_letter(card_t c); +char suit_letter(card_t c) ; +void print_card(card_t c); +card_t card_from_letters(char value_let, char suit_let); +#endif diff --git a/c2prj1_cards/deck-c4.o b/c2prj1_cards/deck-c4.o Binary files differnew file mode 100755 index 0000000..5fc5541 --- /dev/null +++ b/c2prj1_cards/deck-c4.o diff --git a/c2prj1_cards/deck.o b/c2prj1_cards/deck.o Binary files differnew file mode 100644 index 0000000..bddad7c --- /dev/null +++ b/c2prj1_cards/deck.o diff --git a/c2prj1_cards/eval-c4.o b/c2prj1_cards/eval-c4.o Binary files differnew file mode 100755 index 0000000..8cca00b --- /dev/null +++ b/c2prj1_cards/eval-c4.o diff --git a/c2prj1_cards/eval.o b/c2prj1_cards/eval.o Binary files differnew file mode 100644 index 0000000..364ceb4 --- /dev/null +++ b/c2prj1_cards/eval.o diff --git a/c2prj1_cards/future.o b/c2prj1_cards/future.o Binary files differnew file mode 100644 index 0000000..a770c6a --- /dev/null +++ b/c2prj1_cards/future.o diff --git a/c2prj1_cards/grade.txt b/c2prj1_cards/grade.txt new file mode 100644 index 0000000..8a52657 --- /dev/null +++ b/c2prj1_cards/grade.txt @@ -0,0 +1,25 @@ +Grading at Mon 29 Nov 2021 02:19:48 AM UTC +Compiling cards.c +Testing card_from_letters +Passed +Testing value_letter and suit_letter +Passed +Testing print_card +Passed +Testing card_from_num +Passed +Testing ranking_to_string +ranking_to_string(STRAIGHT_FLUSH) resulted in STRAIGHT_FLUSH (Correct) +ranking_to_string(FOUR_OF_A_KIND) resulted in FOUR_OF_A_KIND (Correct) +ranking_to_string(FULL_HOUSE) resulted in FULL_HOUSE (Correct) +ranking_to_string(FLUSH) resulted in FLUSH (Correct) +ranking_to_string(STRAIGHT) resulted in STRAIGHT (Correct) +ranking_to_string(THREE_OF_A_KIND) resulted in THREE_OF_A_KIND (Correct) +ranking_to_string(TWO_PAIR) resulted in TWO_PAIR (Correct) +ranking_to_string(PAIR) resulted in PAIR (Correct) +ranking_to_string(NOTHING) resulted in NOTHING (Correct) +Passed +Testing assert_card_valid +Passed + +Overall Grade: PASSED diff --git a/c2prj1_cards/input.o b/c2prj1_cards/input.o Binary files differnew file mode 100644 index 0000000..65cc44b --- /dev/null +++ b/c2prj1_cards/input.o diff --git a/c2prj1_cards/main.o b/c2prj1_cards/main.o Binary files differnew file mode 100644 index 0000000..0f486ec --- /dev/null +++ b/c2prj1_cards/main.o diff --git a/c2prj1_cards/my-test-main.c b/c2prj1_cards/my-test-main.c new file mode 100644 index 0000000..fefe47e --- /dev/null +++ b/c2prj1_cards/my-test-main.c @@ -0,0 +1,5 @@ +#include "cards.h" + +int main(void) { + +} diff --git a/c2prj2_testing/README b/c2prj2_testing/README new file mode 100644 index 0000000..17a11a6 --- /dev/null +++ b/c2prj2_testing/README @@ -0,0 +1,122 @@ +The second part of this course's poker project is to write +test cases for what you will do in the next course. + +In particular, one of the things you will do in your +project in Course 3 is write the code to evaluate +which poker hand wins between two complete hands. +This involves writing all the code to figure out +what kind of hand (straight flush, full house, etc.) +is in a hand, and which 5 cards ultimately make it up. +For example, if one hand is + +0c 0s 8s 7d 6d 6s 5c + +and the other is + +Js 0s 8s 7d 6s 5c 4c + +your code in the next course will figure out that +the first hand has two pairs (10s and 6s) with an 8 +as the tie-breaking card (called the "kicker"), +and that the second hand has a straight (8 7 6 5 4). +The straight beats the two pairs, so hand 2 wins. + +We have provided you with test-eval, which reads +a file containing lines with one pair of hands +on each line and prints out the details of evaluating +that hand. Each line has one hand, a semi-colon, +then the other hand, so the input for the above would +be: + +0c 0s 8s 7d 6d 6s 5c; Js 0s 8s 7d 6s 5c 4c + +We have put this in example.txt. If you run + +./test-eval example.txt + +Then you will get the following output: + +Hand 1: +-------- +0c 0s 8s 7d 6d 6s 5c + - No flush + - The most of a kind is 2 of a kind (at index 0 / value 0) + - Secondary pair at index 4 (value 6) + - evaluate_hand's ranking: TWO_PAIR + - 5 cards used for hand: 0c 0s 6d 6s 8s +Hand 2: +-------- +Js 0s 8s 7d 6s 5c 4c + - No flush + - Straight at index 2 + - The most of a kind is 1 of a kind (at index 0 / value J) + - No secondary pair + - evaluate_hand's ranking: STRAIGHT + - 5 cards used for hand: 8s 7d 6s 5c 4c +Comparison : +-------------- +Hand 2 wins! +============================ + +You can see that for each hand, this program not only prints +the overall ranking (STRAIGHT, TWO_PAIR, etc), but also the +results of various parts of the evaluation that went into +the decision: Was there a flush? Was there a straight (if +so, where?) How many of a kind were there? etc. + +As with other testing assignments, we have written +some broken implementations and placed them in +/usr/local/l2p/poker/ + +Your goal is to write testcases in tests.txt +that test this problem sufficiently to identify +the problem in each broken implementation we provided. + +You can use the run_all.sh script that we provided +to run your test cases against all implementations. + +Here are some hints: +==================== + + - Straights are tricky. Think about various ways that a programmer + might mess up in finding a straight. These problems could include + both figuring out if there is a straight as well as copying out the + cards that make up the straight (or straight flush). + + There could even be an off-by-one bug in where to look for a straight + in the hand ("count from 0 to the number of cards in the hand minus + [something], call it i. Check if a straight starts at position i" + In such an algorithm, [something] could be off by one) + + - Think about ways in which a programmer might mis-think about what + they need to do. For example, one might think you can check for a + straight flush by checking for a straight AND a flush, but that is + not correct (with more than 5 cards, you could have some that are a + straight but others of the same suit). + + - Be sure to just provide simple coverage of the basic cases (each + type of hand outcome, etc). + + - The suits are numbers, and can be iterated across )where do you + think we iterate over all the suits?). What if we counted wrong + when iterating over the suits? + + + - Two pairs have some subtle cases in terms of selecting the right 5 + cards for the final hand. Remember from the reading that the way + tie breaking works requires the final 5 card hand to be ordered: + (larger pair) (smaller pair) (tiebreaker) + + - Think about everywhere the programer could be off-by-one. + This might include such things as counting through all the + positions in the hand (either missing the start or the end), + or being off-by-one in how many cards are required + for a particular hand (e.g., only requiring 4 + cards meet a particular condition instead of 5). + + - Note that you may be able to 'game' your way into passing all + the tests locally, but if you do this you won't actually pass the + assignment. The only way to pass is to provide good tests. + + - Note additionally that you do not need to use invalid cards + in your tests. diff --git a/c2prj2_testing/example.txt b/c2prj2_testing/example.txt new file mode 100644 index 0000000..b6f6824 --- /dev/null +++ b/c2prj2_testing/example.txt @@ -0,0 +1 @@ +0c 0s 8s 7d 6d 6s 5c; Js 0s 8s 7d 6s 5c 4c diff --git a/c2prj2_testing/grade.txt b/c2prj2_testing/grade.txt new file mode 100644 index 0000000..02ff23b --- /dev/null +++ b/c2prj2_testing/grade.txt @@ -0,0 +1,26 @@ +Grading at Mon 29 Nov 2021 02:22:00 AM UTC +Your test cases identified the problem with test-eval-0000 +Your test cases identified the problem with test-eval-0001 +Your test cases identified the problem with test-eval-0002 +Your test cases identified the problem with test-eval-0003 +Your test cases identified the problem with test-eval-0004 +Your test cases identified the problem with test-eval-0005 +Your test cases identified the problem with test-eval-0006 +Your test cases identified the problem with test-eval-0007 +Your test cases identified the problem with test-eval-0008 +Your test cases identified the problem with test-eval-0009 +Your test cases identified the problem with test-eval-0010 +Your test cases identified the problem with test-eval-0011 +Your test cases identified the problem with test-eval-0012 +Your test cases identified the problem with test-eval-0013 +Your test cases identified the problem with test-eval-0014 +Your test cases identified the problem with test-eval-0015 +Your test cases identified the problem with test-eval-0016 +Your test cases identified the problem with test-eval-0017 +Your test cases identified the problem with test-eval-0018 +Your test cases identified the problem with test-eval-0019 +Your test cases identified the problem with test-eval-0020 +Your test cases identified the problem with test-eval-0021 +Your test cases identified the problem with test-eval-0022 + +Overall Grade: PASSED diff --git a/c2prj2_testing/run_all.sh b/c2prj2_testing/run_all.sh new file mode 100755 index 0000000..a963b62 --- /dev/null +++ b/c2prj2_testing/run_all.sh @@ -0,0 +1,30 @@ +#!/bin/bash +run_test(){ + prog="$1" + testfile="$2" + IFS=$'\n' + IFS=" " correct=`/usr/local/l2p/poker/correct-test-eval $testfile 2>&1` + IFS=" " broken=`$prog $testfile 2>&1` + if [ "$broken" != "$correct" ] + then + return 0 + fi + return 1 +} + +found=0 +notfound=0 +for i in /usr/local/l2p/poker/test-eval-* +do + run_test $i tests.txt + x="$?" + if [ "$x" != "0" ] + then + echo "Your test cases did not identify the problem with `basename $i`" + let notfound=${notfound}+1 + else + let found=${found}+1 + fi +done +echo "Test cases identified $found problems" +echo "Test cases failed to identify $notfound problems" diff --git a/c2prj2_testing/test-eval b/c2prj2_testing/test-eval Binary files differnew file mode 100755 index 0000000..bc28c9b --- /dev/null +++ b/c2prj2_testing/test-eval diff --git a/c2prj2_testing/tests.txt b/c2prj2_testing/tests.txt new file mode 100644 index 0000000..63059d5 --- /dev/null +++ b/c2prj2_testing/tests.txt @@ -0,0 +1,30 @@ +Kc Qs Jd 9h 8c 7s 6d; Ac Qs Jd 9h 8c 7s 6d +Kh Ac Kc 8c 7h 3d 6s; Kh As 7h 3s 5d 6h Ks +As Ah Ks Kd 2h 3d 6s; Ac Ad Kh Kc Jd 3d 6s +Kh Kc Kd Ac 3s 6h 2s; Kh Kc Kd Ac 7h 6s 3d +Ks Qd Js 0h 6h 9d 2s; 0h 5d 8s 4s 3c 2h Ah +Ah Qh 5s 6d 9h 7h 2h; 4s 6s 5s 7d 0s Qs As +Kc Ks 3d 0c 0s Kh 8d; 9h Jd 9s Js 9d 3d 0c +0c 0s 0h 2d 7c 0d 2h; Kc Kd Kh Ks 3c 4h 5d +As 2d 3c Ks Qs Js 0s; 5s 4s 3s 2d Jc 2s As +As Ks 4d 5d Jd 0d Qd; Kd Qd Js 0s 9s 4s 5s +Qd Jd 0d 9s 9h 8h 8c; Jd 0d 9d 8s 8h 7h 7c +0c 0s 8s 7d 6d 6s 5c; Js 0s 8s 7d 6s 5c 4c +2d 3d 6d 8d 7c As Js; 2d 3d 6d 8d 7c Ah Ac +Ac 2d 3c 0s 4d 5s 0h; Ac 2d 3c 0s 4d 8h Jh +6c 3c 6d 4h Qs As 2d; 6c 3c 6d 4h Qs 2h Jh +6c 3c 6d 4h Qs 6h 2d; 6c 3c 6d 4h Qs 2h Jh +6c 3c 6d 4h 6h Qs 2d; 6c 3c 6d 4h Qs 6s Jh +6c 3c 6d 4h Qs 6h 2d; 6c 3c 6d 4h Qs 6s Ac +2d 3c 3d Jh Qs Js 3h; 2d 3c 3d Jh Qs Jd 3c +2d 3c 3d Jh Qs Js 2s; 2d 3c 3d Jh Qs Jd 3c +7d 2c 8h Ah 2h 9h 0h; 7d 2c 8h Ah 2h Jh Qh +6h 7h 8d 9d Jd 0d Qh; 6h 7h 8d 9d Jd 2c 9s +2c 5d 9h 8h 7h 3d As; 2c 5d 9h 8h 7h 0h Jh +Ah 2c 3c 7h 4s 5s 0d; Ah 2c 3c 7h 4s 0s 0h +4s 3s 8h 2s 9d As 5s; 4s 3s 8h 2s 9d 9h 9s +9d 9h 9s 8c 9c 0h Ah; 9d 9h 9s 8c 9c 0c As +9d 9h 8h 9c 7h 6h 5h; 9d 9h 8h 9c 7h 6c 5c +2s 3s 4s 6s 5h 8s 9h; As 2s 3s 4s 5s 8h 9h +2s 3s 4h 5s 6s 4s 0h; 2s 3s 4h 5s 6s 8d Kh +Kc Ac 2c 3c 2s Qc 7c; Kc Ac 2c As 2s 8c 5c diff --git a/c3prj1_deck/.gitignore b/c3prj1_deck/.gitignore new file mode 100644 index 0000000..d7502ed --- /dev/null +++ b/c3prj1_deck/.gitignore @@ -0,0 +1,3 @@ +deck.o +cards.o +test-deck diff --git a/c3prj1_deck/Makefile b/c3prj1_deck/Makefile new file mode 100644 index 0000000..28b3c52 --- /dev/null +++ b/c3prj1_deck/Makefile @@ -0,0 +1,8 @@ +CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99 +GIVEN_OBJS=deck-c4.o eval-c4.o future.o input.o main.o +MY_OBJS=cards.o deck.o eval.o + +test-deck: deck.o test-deck.o deck-c4.o cards.o + gcc -o test-deck -ggdb3 deck.o test-deck.o deck-c4.o cards.o +clean: + rm test poker cards.o my-test-main.o *~ diff --git a/c3prj1_deck/README b/c3prj1_deck/README new file mode 100644 index 0000000..1697fc6 --- /dev/null +++ b/c3prj1_deck/README @@ -0,0 +1,176 @@ +Decks (sets of cards) +--------------------- + +Note: if you have not completed the course 2 poker projects, +please use the fast-forward command to complete them first! + +Now that you have learned about arrays, you are ready +to start working with decks and hands of cards (represented +as arrays of cards). You will be using the card.c +file from your Course 2 project, as this project builds +on the same card_t type. If you look in deck.h, +you will find the type declaration for a deck of cards: + +struct deck_tag { + card_t ** cards; + size_t n_cards; +}; +typedef struct deck_tag deck_t; + +We'll use the same type for a deck of cards or a hand +of cards, since both are just a set of cards. + +We'll note that we could have chosen to make an array +of cards (card_t * cards) but instead decided to make +an array of card pointers (card_t ** cards). You may +wonder why we selected this design. With this design, +when you shuffle an array, you will move the pointers +around, but they will point to card_ts that stay in the +same place. This means that if you have OTHER pointers +(as you will have in Course 4 to handle unknown cards), +they will still point to the right place. + +For example, if you have (Ah,Ks,Qc,?0): + + Ah Ks Qc ?0<----to_replace + ^ ^ ^ ^ + | | | | + | | | | + | | | | + +--|--+--|--+--|--+--|--+ +arr->| | | | | | | | | + +-----+-----+-----+-----+ + +and you shuffle the pointers in the array +(yielding, e.g, Ks, ?0, Ah, Qc) : + + /------\ + V \ + Ah Ks | Qc ?0<----to_replace + ^ | ^ ^ + ____/ \ \ / + / ___\___\___/ + / / \ --- + +--|--+--|--+--\--+--\--+ +arr->| | | | | | | | | + +-----+-----+-----+-----+ + +the to_replace pointer still points at ?0 +with no other changes. If we had an array +of cards and shuffled them directly, it would +be much harder to do the card replacement later. + + +First, you will write four functions in deck.c: + + - void print_hand(deck_t * hand); + This should print out the contents of a hand. + It should print each card (recall that + you wrote print_card in Course 2), and + a space after each card. Do not put + a newline after the hand, as this + function gets called to print a hand + in the middle of a line of output. + + + - int deck_contains(deck_t * d, card_t c); + This function should check if a deck + contains a particular card or not. If + the deck does contain the card, this + function should return 1. Otherwise, + it should return 0. + (You will use this later to + build the deck of remaining cards + which are not in any player's hand). + + - void shuffle(deck_t * d); + This function takes in a deck an shuffles + it, randomly permuting the order of the cards. + There are MANY valid ways to shuffle a deck + of cards---we'll leave the specifics + of the algorithm design up to you. However, + you will want to use random() to generate + pseudo-random numbers. (Pseudo-random + numbers are quite sufficient here, + since they are not used for security + purposes). Note that you should not need to + use the 'srand' function. + + We will note that in trying to devise + this algorithm, you should not + try to shuffle a deck of cards "normally". + Instead, you should take a small number + of cards, and think about ways + to shuffle them that involve using + random numbers to swap their order, + or pick positions for them, or + similar principles. + +- void assert_full_deck(deck_t * d); + This function should check that + the passed in deck contains ever + valid card exactly once. If + the deck has any problems, this function + should fail an assert. This will + be used to help you test your deck + shuffling: we will shuffle + a full deck, then call assert_full_deck, + so that you can identfiy problems with + the deck. You can print + any error messages you want + if there is a problem. + Hint: you already wrote deck_contains. + +------------ +Once you have completed these functions, you should run + +make test-deck + +This will build the test-deck program which we +have provided which runs some test cases on your functions. +There is no one single right output, as you may shuffle +your deck any way that you want. However, you should +read through the output and see if things make sense. +The first deck is built by using your card_from_num +function (from Course 2) for each value in the +range [0,52). Then the deck is shuffled +a couple times, with the results printed. +We call assert_full_deck on each of these. + +Next we make a 5 card hand, and test +deck_contains on it, shuffle, and repeat +the process a few times. + +The last thing we do is take the 5 card +hand and shuffle it 50,000,000 (50 Million) +times, counting how often each hand occurs. +In an ideal case, each of the 120 possible +5-card hands would appear equally often (0.833% +of the time). If your shuffle is close +to this, then it is good. If it is drastically +off, that is bad. + +Since this can take a while, the test +program will print a '.' ever 500,000 +shuffles to let you know it isn't stuck. + +When it finishes, it will print out the +frequency (and ordering) of the most and least +common hands. For my shuffling algorithm, +these were 0.836496% and 0.829262% respectively, +which is quite good. If you end up with +things in the 0.823% (min) to 0.843% (max) range, that's +great. If its in the 0.818%(min) to 0.848% (max) range, +that's good enough. If you are outside of that, you +should try to work on your shuffling algorithm +to make sure you get good results from your poker +simulator. + +We provide that hands that appear most and least +often in case it helps you debug. + +Once you are satsified with the functionality +of your code for this part, run grade. +When you pass, you get the hand evaluation in +the next part. + diff --git a/c3prj1_deck/cards.c b/c3prj1_deck/cards.c new file mode 120000 index 0000000..1b5fce4 --- /dev/null +++ b/c3prj1_deck/cards.c @@ -0,0 +1 @@ +../c2prj1_cards/cards.c
\ No newline at end of file diff --git a/c3prj1_deck/cards.h b/c3prj1_deck/cards.h new file mode 120000 index 0000000..7a280fd --- /dev/null +++ b/c3prj1_deck/cards.h @@ -0,0 +1 @@ +../c2prj1_cards/cards.h
\ No newline at end of file diff --git a/c3prj1_deck/deck-c4.o b/c3prj1_deck/deck-c4.o Binary files differnew file mode 100644 index 0000000..5fc5541 --- /dev/null +++ b/c3prj1_deck/deck-c4.o diff --git a/c3prj1_deck/deck.c b/c3prj1_deck/deck.c new file mode 100644 index 0000000..2757a3c --- /dev/null +++ b/c3prj1_deck/deck.c @@ -0,0 +1,75 @@ +#include "deck.h" +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +void print_hand(deck_t *hand) { + for (size_t i = 0; i < hand->n_cards; i++) { + print_card(*hand->cards[i]); + printf(" "); + } +} + +int deck_contains(deck_t *d, card_t c) { + for (size_t i = 0; i < d->n_cards; i++) { + if (d->cards[i]->value == c.value && d->cards[i]->suit == c.suit) { + return 1; + } + } + return 0; +} + +void shuffle(deck_t *d) { + card_t c; + for (size_t i = d->n_cards; i > 0; i--) { + int r = rand() % i; + c = *d->cards[i - 1]; + *d->cards[i - 1] = *d->cards[r]; + // d[i-1] = d[r]; + *d->cards[r] = c; + } +} + +void assert_full_deck(deck_t *d) { + card_t temp; + for (int i = 0; i <= 51; i++) { + temp = card_from_num(i); + assert(deck_contains(d, temp) == 1); + } +} + +void add_card_to(deck_t *deck, card_t c) { + deck->n_cards++; + deck->cards = realloc(deck->cards, deck->n_cards * sizeof(*card_t)); + deck->cards[deck->n_cards - 1] = &c; +} + +card_t *add_empty_card(deck_t *deck) { + card_t *c = malloc(sizeof(card_t)); + c->value = 0; + c->suit = 0; + add_card_to(deck, *c); + return c; +} + +deck_t *make_deck_exclude(deck_t *excluded_cards) { + deck_t *deck = malloc(sizeof(deck_t)); + deck->n_cards = 0; + card_t *c = malloc(sizeof(card_t)); + for (int i = 0; i < 52; i++) { + *c = card_from_num(i); + if (deck_contains(excluded_cards, c) == 1) { + continue; + } else { + deck->n_cards++; + deck->cards = realloc(deck->cards, deck->n_cards * sizeof(*card_t)); + deck->cards[deck->n_cards - 1] = c; + } + } + free(c); + return deck; +} + +deck_t * build_remaining_deck(deck_t ** hands, size_t n_hands) { + +} diff --git a/c3prj1_deck/deck.h b/c3prj1_deck/deck.h new file mode 100644 index 0000000..aace099 --- /dev/null +++ b/c3prj1_deck/deck.h @@ -0,0 +1,22 @@ +#ifndef DECK_H +#define DECK_H +#include "cards.h" +#include <stdlib.h> +struct deck_tag { + card_t **cards; + size_t n_cards; +}; +typedef struct deck_tag deck_t; + +void print_hand(deck_t *hand); +int deck_contains(deck_t *d, card_t c); +void shuffle(deck_t *d); +void assert_full_deck(deck_t *d); +// The below functions will be done in course 4. +deck_t *make_deck_exclude(deck_t *excluded_cards); +void add_card_to(deck_t *deck, card_t c); +card_t *add_empty_card(deck_t *deck); +void free_deck(deck_t *deck); +deck_t *build_remaining_deck(deck_t **hands, size_t n_hands); +#endif +// diff --git a/c3prj1_deck/grade.txt b/c3prj1_deck/grade.txt new file mode 100644 index 0000000..c5a7eda --- /dev/null +++ b/c3prj1_deck/grade.txt @@ -0,0 +1,14 @@ +Grading at Sat 11 Dec 2021 09:48:04 PM UTC +Compiling deck.c +Compiling cards.c +Linking cards.o deck.o deck-c4.o and the grader's .o file +Checking the output of all the functions other than shuffle +Your file matched the expected output + - Those functions seem to work! +Checking your shuffle results with a 6 card hand... + Least common hand: 0.131350% + Most common hand: 0.147450% + Perfectly even is: 0.138888% + Excellent! + +Overall Grade: A diff --git a/c3prj1_deck/test-deck.o b/c3prj1_deck/test-deck.o Binary files differnew file mode 100644 index 0000000..53a80bf --- /dev/null +++ b/c3prj1_deck/test-deck.o diff --git a/c3prj2_eval/.gitignore b/c3prj2_eval/.gitignore new file mode 100644 index 0000000..15d0dfb --- /dev/null +++ b/c3prj2_eval/.gitignore @@ -0,0 +1,4 @@ +deck.o +eval.o +cards.o +test-eval diff --git a/c3prj2_eval/Makefile b/c3prj2_eval/Makefile new file mode 100644 index 0000000..d297bdb --- /dev/null +++ b/c3prj2_eval/Makefile @@ -0,0 +1,10 @@ +CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99 +GIVEN_OBJS=deck-c4.o eval-c4.o future.o input.o main.o +MY_OBJS=cards.o deck.o eval.o + +test-eval: deck.o eval.o eval-c4.o test-eval.o deck-c4.o cards.o input.o future.o + gcc -o test-eval -ggdb3 deck.o deck-c4.o eval-c4.o eval.o test-eval.o cards.o input.o future.o +poker: $(GIVEN_OBJS) $(MY_OBJS) + gcc -o poker -ggdb3 $(MY_OBJS) $(GIVEN_OBJS) +clean: + rm -f test poker cards.o my-test-main.o *~ diff --git a/c3prj2_eval/README b/c3prj2_eval/README new file mode 100644 index 0000000..ce5530e --- /dev/null +++ b/c3prj2_eval/README @@ -0,0 +1,332 @@ +Hand Evaluation +--------------- +The other part of the project that you will do in this +course is write some of the code to evaluate and compare hands. +Remember that in Course 2 you already wrote test cases +for this code. That means you have already thought +about various corner cases that might come up +and will have a nice suite of tests ready to go +when you finish your code. + +Your ultimate goal in this step is to write a function, +which when passed two hands of cards, determines +which one won (or if they tied). We'll use the +deck_t type that you worked with in the previous +part to represent a hand of cards as well (a hand +of cards is just a much smaller deck of cards---they +are both just sets of cards). + +There are three major steps to determining who won: + (1) Figuring out what ranking each hand has (straight, flush, etc) + If you look in cards.h, you will see enum hand_ranking_t, + which you worked with in Course 2. + (2) Figuring out which 5 cards make up the hand (picking out + the 5 cards that made the flush, or the two pairs and tiebreaker) + (3) Comparing the rankings, and if they are the same, breaking + ties by comparing the values in the hands. + +At this point, you might be thinking that there is going to +be a lot of code to write with all the different possible +arrangements of cards and different possible hand rankings. +However, there are a few important things that will make +this managable: + +(1) You will start by sorting the cards into descending order + by value. This makes it much easier to find straights (cards + in order), and you will have "N of a kind"s grouped together. +(2) The code to find "N of a kind" is basically the same + for 4, 3, and 2 (so we can abstract it out into a function...) +(3) Full house and two pair are just three of a kind and a pair + (so we already have that code...) with another pair + (so we can just write a function to find a secondary pair) +(4) We are going to make two simplifying assumptions: + - if there is a flush, it will occur in at most one suit. + (i.e., you won't have As Ah Kh Qs 8s 7h 4s 3s 3h 2h, + which has two different flushes). + - if there is an ace-high straight, there is not also + an ace-low straight. + (These both hold for all major poker variants) + +If you open up eval.c, you will find the following functions +that you will need to write: + + - int card_ptr_comp(const void * vp1, const void * vp2) + You want to sort the hand by value, so you need + a comparison function to pass to quicksort. + Quicksort sorts into ascending order, but you + want descending order, so you will want to + return + something < 0 if card1 > card2 + 0 if card1 == card2 + something > 0 if card1 < card2 + If two cards have the same value, compare them by + suit in the same order as the enum suit_t: + club < diamond < heart < spade + Note that vp1 and vp2 are passed as const void * + because that is the type that qsort demands. + They will should each be assigned to variables + of type + const card_t * const * cp1 + before using them (this is much like sorting + an array of strings from your readings). + To learn more about using the C library function qsort, + we suggest reviewing the course reading + "Sorting Functions" in the "Function Pointers" + lesson and consulting "man qsort" + to read about the comparison function. + + - suit_t flush_suit(deck_t * hand); + This function looks at the hand and determines + if a flush (at least 5 cards of one suit) exists. + If so, it returns the suit of the cards comprising + the flush. If not, it returns NUM_SUITS. + For example: + Given Ks Qs 0s 9h 8s 7s, it would return SPADES. + Given Kd Qd 0s 9h 8c 7c, it would return NUM_SUITS. + + - unsigned get_largest_element(unsigned * arr, size_t n); + This function returns the largest element in an array + of unsigned integers. This should be familiar + from the videos you watched. + + In course 4 (after you learn to dynamically allocate + memory), you will write get_match_counts, + which will construct an array with one element + per card in the hand. That array will + tell you how many cards in the hand + have the same value as the corresponding + card. You will then use get_largest_element + to figure out which is the best "N of a kind". + + + - size_t get_match_index(unsigned * match_counts, size_t n,unsigned n_of_akind); + This function returns the index in the array (match_counts) whose + value is n_of_akind. The array has n elements. The array match_counts + may have multiple values equal to n_of_akind. You should return + the LOWEST index whose value is n_of_akind [which also guarantees + it corresponds to the largest valued cards, since they will be sorted]. + (Once you figure out the best n_of_akind above, + you will use this to locate that group of cards + in the hand). + Note that it is guaranteed that n_of_akind is in match_counts. + If not, you should abort as this is evidence of an error. + + + - ssize_t find_secondary_pair(deck_t * hand, + unsigned * match_counts, + size_t match_idx) ; + When you have a hand with 3 of a kind or a pair, + you will want to look and see if there is another + pair to make the hand into a full house or + or two pairs. This function takes in + the hand, the match counts from before, and + the index where the original match (3 of a kind + or pair) was found. It should find + the index of a card meeting the following conditions: + - Its match count is > 1 [so there is at least a pair of them] + - The card's value is not the same as the value of the + card at match_idx (so it is not part of the original + three of a kind/pair) + - It is the lowest index meeting the first two conditions + (which will be the start of that pair, and the highest + value pair other than the original match). + If no such index can be found, this function should + return -1. + + - int is_straight_at(deck_t * hand, size_t index, suit_t fs) + This function should determine if there is a straight + starting at index (and only starting at index) in the + given hand. If fs is NUM_SUITS, then it should look + for any straight. If fs is some other value, then + it should look for a straight flush in the specified suit. + This function should return: + -1 if an Ace-low straight was found at that index (and that index is the Ace) + 0 if no straight was found at that index + 1 if any other straight was found at that index + + When writing this function, you can assume + that the hand is sorted by value: the + values of cards will appear in descending order. + (A K Q ... 4 3 2). + + There are two things that make this function + tricky (probably the trickiest function in + this assignment): + (1) Ace low straights. An Ace low straight + will appear in the hand with the Ace + first, then possibly some other cards, + then the 5 4 3 2. For example, you + might have + As Ks Qc 5s 4c 3d 2c + (2) You may have multiple cards with the + same value, but still have a straight: + As Ac Ks Kc Qh Jh 0d + has a straight even though A K Q + do not appear next to each other in + our sorted order. + Hint: I made this easier on myself, by writing + two helper functions: + int is_n_length_straight_at(deck_t * hand, size_t index, suit_t fs, int n) ; + and + int is_ace_low_straight_at(deck_t * hand, size_t index, suit_t fs); + + The second of these lets me pull out the complexities of an ace + low straight. However, in doing so, I realized that there + would be a lot of duplication of code between the ace low straight + helper and the original function (for an ace low, you want to find + a 5, then a straight of length 4: 5, 4, 3, 2). This realization + caused me to pull out much of the code into is_n_length_straight_at, + so that I could call it with n=4 to search for the 5,4,3,2 part + of an ace low straight. + + + - hand_eval_t build_hand_from_match(deck_t * hand, + unsigned n, + hand_ranking_t what, + size_t idx) ; + Now you have written a bunch of functions that + will figure out which ranking a hand has. It + is time to construct a hand_eval_t (see eval.h) which + has the ranking and the 5 cards used for it. + This helper function will handle the + "n of a kind" case. + It should make hand_eval_t and set its + ranking to the passed in "what" value. + Then it should copy "n" cards from + the hand, starting at "idx" into + the first "n" elements of the hand_eval_t's + "cards" array. The cards field in + hand_eval_t is declared as: + card_t * cards[5] + This is an array of pointers, each to a card_t. + Draw a picture to be sure you know how to name + each card_t "box" before you start writing code. + + Your function should then fill the remainder + of the "cards" array with the highest-value + cards from the hand which were not in + the "n of a kind". + + For example, given this hand: + As Kc Kh Kd Qc 8s 5d + The hand has 3 kings, and the As and Qc will break ties. + Note that here n = 3, what= THREE_OF_A_KIND, idx= 1. + So the cards array in the hand_eval_t should have + + Kc Kh Kd As Qc + + Note that what may also be FULL_HOUSE or TWO_PAIR, + since this function will get used for the first + part of preparing those evaluations (then other code + will later fix the rest of the hand with the other pair). + + + - int compare_hands(deck_t * hand1, deck_t * hand2) + + This is the goal of the whole thing: given two hands, + figure out which wins (or if it is a tie). + Everything you wrote goes together to make this work! + + + We're providing you with + hand_eval_t evaluate_hand(deck_t * hand) ; + since it involves some things you won't learn until + Course 4. It's also not super interesting: + it mostly make a bunch of calls to the functions + you wrote above, and has a lot of if-statements + to handle the rules of poker. + + The important part of evaluate_hand is that + (a) assumes the cards in the passed in hand are + sorted and (b) it returns a hand_eval_t for the passed in hand. + + That means that to implement compare_hands, you should + + (a) sort each hand using qsort on the hand's cards + and your card_ptr_comp [from earlier] + (b) Call evaluate_hand on each hand, which gives you a hand_eval_t + for each hand. + (c) Check if the rankings in the hand_eval_t are the same + or different. If they are different, you can just use + the ranking to determine the winner. + (d) If they are the same, then you need to look + at the values in the cards array of each hand_eval_t + to break the tie. The way that we constructed + the hand_eval_t's cards array means that + the cards are already ordered from most significant (at index 0) + to least significant (at index 4). You can just + do a lexicographic comparison on the values in the arrays. + (Its like comparing strings, but you are comparing values + of cards---if element 0 is the different, use that difference + to determine your answer. If element 0 is the same, + look at element 1, and so on). +Note that compare hands should return a positive number +if hand 1 is better, 0 if the hands tie, and a negative number +if hand 2 is better. + +You will also notice some functions at the bottom of eval.c that +we provided. You don't need to do anything to these---we wrote +them for you to keep the amount of code manageable. + +-------------- +That sure was a lot of code! You've been compiling and testing +along the way, right? We sure hope so :) + +However, to help you test things out even more, we've +provided some test infrastructure for you. + +If you do + +make + +You will compile the test-eval program you are +familiar with from Course 2. This program behaves +exactly like it did in Course 2. As a reminder, +it expects input where each line looks like: + +hand1 ; hand2 + +where a hand looks like something that print_hand +would output. So a valid input might be + +Kc Ac Jh 8s 9c 2s ; Ah Kh 0s 7c 7h 3c + +For each line in the input, the test program +will tell you: + - The results of your functions that went into evaluating it + (if there was a straight, if there was a flush, etc). + - What hand_eval_t was returned by evaluate_hand for each hand + - Which hand won (or if it was a tie) according to compare_hands + +Good thing you have all those test cases from Course 2 +to use with it! + +Because you have an object file test-eval.o and not the source +test-eval.c, you may need to use the debugger differently than you're +used to. For this test program, we recommend running gdb in emacs, +then first, specifying the command line argument (in this case, a file +name with your tests) + +set args tests.txt + +Then you will want to set a breakpoint in the code you wrote (since +you can't see test-eval.c, where main is, to step through it). For +example, if you just wrote the function is_straight_at, and it doesn't +behave the way you expect, you can do + +break is_straight_at + +and gdb will pause execution any time the program calls that +function. Then you can use the command "run" instead of "start," since +you don't need to pause execution at the start of main. Also recall +the command "continue," which you can review from the debugging +lesson. + + +As usual, when you are finished, use the "grade" command. +When you pass, this, congratulations! You are done +with Course 3 and ready to move on to Course 4 :) + + + + diff --git a/c3prj2_eval/README~ b/c3prj2_eval/README~ new file mode 100644 index 0000000..1b77db5 --- /dev/null +++ b/c3prj2_eval/README~ @@ -0,0 +1,332 @@ +Hand Evaluation +--------------- +The other part of the project that you will do in this +course is write some of the code to evaluate and compare hands. +Remember that in Course 2 you already wrote test cases +for this code. That means you have already thought +about various corner cases that might come up +and will have a nice suite of tests ready to go +when you finish your code. + +Your ultimate goal in this step is to write a function, +which when passed two hands of cards, determines +which one won (or if they tied). We'll use the +deck_t type that you worked with in the previous +part to represent a hand of cards as well (a hand +of cards is just a much smaller deck of cards---they +are both just sets of cards). + +There are three major steps to determining who won: + (1) Figuring out what ranking each hand has (straight, flush, etc) + If you look in cards.h, you will see enum hand_ranking_t, + which you worked with in Course 2. + (2) Figuring out which 5 cards make up the hand (picking out + the 5 cards that made the flush, or the two pairs and tiebreaker) + (3) Comparing the rankings, and if they are the same, breaking + ties by comparing the values in the hands. + +At this point, you might be thinking that there is going to +be a lot of code to write with all the different possible +arrangements of cards and different possible hand rankings. +However, there are a few important things that will make +this managable: + +(1) You will start by sorting the cards into descending order + by value. This makes it much easier to find straights (cards + in order), and you will have "N of a kind"s grouped together. +(2) The code to find "N of a kind" is basically the same + for 4, 3, and 2 (so we can abstract it out into a function...) +(3) Full house and two pair are just three of a kind and a pair + (so we already have that code...) with another pair + (so we can just write a function to find a secondary pair) +(4) We are going to make two simplifying assumptions: + - if there is a flush, it will occur in at most one suit. + (i.e., you won't have As Ah Kh Qs 8s 7h 4s 3s 3h 2h, + which has two different flushes). + - if there is an ace-high straight, there is not also + an ace-low straight. + (These both hold for all major poker variants) + +If you open up eval.c, you will find the following functions +that you will need to write: + + - int card_ptr_comp(const void * vp1, const void * vp2) + You want to sort the hand by value, so you need + a comparison function to pass to quicksort. + Quicksort sorts into ascending order, but you + want descending order, so you will want to + return + something < 0 if card1 > card2 + 0 if card1 == card2 + something > 0 if card1 < card2 + If two cards have the same value, compare them by + suit in the same order as the enum suit_t: + club < diamond < heart < spade + Note that vp1 and vp2 are passed as const void * + because that is the type that qsort demands. + They will should each be assigned to variables + of type + const card_t * const * cp1 + before using them (this is much like sorting + an array of strings from your readings). + To learn more about using the C library function qsort, + we suggest reviewing the course reading + "Sorting Functions" in the "Function Pointers" + lesson and consulting "man qsort" + to read about the comparison function. + + - suit_t flush_suit(deck_t * hand); + This function looks at the hand and determines + if a flush (at least 5 cards of one suit) exists. + If so, it returns the suit of the cards comprising + the flush. If not, it returns NUM_SUITS. + For example: + Given Ks Qs 0s 9h 8s 7s, it would return SPADES. + Given Kd Qd 0s 9h 8c 7c, it would return NUM_SUITS. + + - unsigned get_largest_element(unsigned * arr, size_t n); + This function returns the largest element in an array + of unsigned integers. This should be familiar + from the videos you watched. + + In course 4 (after you learn to dynamically allocate + memory), you will write get_match_counts, + which will construct an array with one element + per card in the hand. That array will + tell you how many cards in the hand + have the same value as the corresponding + card. You will then use get_largest_element + to figure out which is the best "N of a kind". + + + - size_t get_match_index(unsigned * match_counts, size_t n,unsigned n_of_akind); + This function returns the index in the array (match_counts) whose + value is n_of_akind. The array has n elements. The array match_counts + may have multiple values equal to n_of_akind. You should return + the LOWEST index whose value is n_of_akind [which also guarantees + it corresponds to the largest valued cards, since they will be sorted]. + (Once you figure out the best n_of_akind above, + you will use this to locate that group of cards + in the hand). + Note that it is guaranteed that n_of_akind is in match_counts. + If not, you should abort as this is evidence of an error. + + + - size_t find_secondary_pair(deck_t * hand, + unsigned * match_counts, + size_t match_idx) ; + When you have a hand with 3 of a kind or a pair, + you will want to look and see if there is another + pair to make the hand into a full house or + or two pairs. This function takes in + the hand, the match counts from before, and + the index where the original match (3 of a kind + or pair) was found. It should find + the index of a card meeting the following conditions: + - Its match count is > 1 [so there is at least a pair of them] + - The card's value is not the same as the value of the + card at match_idx (so it is not part of the original + three of a kind/pair) + - It is the lowest index meeting the first two conditions + (which will be the start of that pair, and the highest + value pair other than the original match). + If no such index can be found, this function should + return -1. + + - int is_straight_at(deck_t * hand, size_t index, suit_t fs) + This function should determine if there is a straight + starting at index (and only starting at index) in the + given hand. If fs is NUM_SUITS, then it should look + for any straight. If fs is some other value, then + it should look for a straight flush in the specified suit. + This function should return: + -1 if an Ace-low straight was found at that index (and that index is the Ace) + 0 if no straight was found at that index + 1 if any other straight was found at that index + + When writing this function, you can assume + that the hand is sorted by value: the + values of cards will appear in descending order. + (A K Q ... 4 3 2). + + There are two things that make this function + tricky (probably the trickiest function in + this assignment): + (1) Ace low straights. An Ace low straight + will appear in the hand with the Ace + first, then possibly some other cards, + then the 5 4 3 2. For example, you + might have + As Ks Qc 5s 4c 3d 2c + (2) You may have multiple cards with the + same value, but still have a straight: + As Ac Ks Kc Qh Jh 0d + has a straight even though A K Q + do not appear next to each other in + our sorted order. + Hint: I made this easier on myself, by writing + two helper functions: + int is_n_length_straight_at(deck_t * hand, size_t index, suit_t fs, int n) ; + and + int is_ace_low_straight_at(deck_t * hand, size_t index, suit_t fs); + + The second of these lets me pull out the complexities of an ace + low straight. However, in doing so, I realized that there + would be a lot of duplication of code between the ace low straight + helper and the original function (for an ace low, you want to find + a 5, then a straight of length 4: 5, 4, 3, 2). This realization + caused me to pull out much of the code into is_n_length_straight_at, + so that I could call it with n=4 to search for the 5,4,3,2 part + of an ace low straight. + + + - hand_eval_t build_hand_from_match(deck_t * hand, + unsigned n, + hand_ranking_t what, + size_t idx) ; + Now you have written a bunch of functions that + will figure out which ranking a hand has. It + is time to construct a hand_eval_t (see eval.h) which + has the ranking and the 5 cards used for it. + This helper function will handle the + "n of a kind" case. + It should make hand_eval_t and set its + ranking to the passed in "what" value. + Then it should copy "n" cards from + the hand, starting at "idx" into + the first "n" elements of the hand_eval_t's + "cards" array. The cards field in + hand_eval_t is declared as: + card_t * cards[5] + This is an array of pointers, each to a card_t. + Draw a picture to be sure you know how to name + each card_t "box" before you start writing code. + + Your function should then fill the remainder + of the "cards" array with the highest-value + cards from the hand which were not in + the "n of a kind". + + For example, given this hand: + As Kc Kh Kd Qc 8s 5d + The hand has 3 kings, and the As and Qc will break ties. + Note that here n = 3, what= THREE_OF_A_KIND, idx= 1. + So the cards array in the hand_eval_t should have + + Kc Kh Kd As Qc + + Note that what may also be FULL_HOUSE or TWO_PAIR, + since this function will get used for the first + part of preparing those evaluations (then other code + will later fix the rest of the hand with the other pair). + + + - int compare_hands(deck_t * hand1, deck_t * hand2) + + This is the goal of the whole thing: given two hands, + figure out which wins (or if it is a tie). + Everything you wrote goes together to make this work! + + + We're providing you with + hand_eval_t evaluate_hand(deck_t * hand) ; + since it involves some things you won't learn until + Course 4. It's also not super interesting: + it mostly make a bunch of calls to the functions + you wrote above, and has a lot of if-statements + to handle the rules of poker. + + The important part of evaluate_hand is that + (a) assumes the cards in the passed in hand are + sorted and (b) it returns a hand_eval_t for the passed in hand. + + That means that to implement compare_hands, you should + + (a) sort each hand using qsort on the hand's cards + and your card_ptr_comp [from earlier] + (b) Call evaluate_hand on each hand, which gives you a hand_eval_t + for each hand. + (c) Check if the rankings in the hand_eval_t are the same + or different. If they are different, you can just use + the ranking to determine the winner. + (d) If they are the same, then you need to look + at the values in the cards array of each hand_eval_t + to break the tie. The way that we constructed + the hand_eval_t's cards array means that + the cards are already ordered from most significant (at index 0) + to least significant (at index 4). You can just + do a lexicographic comparison on the values in the arrays. + (Its like comparing strings, but you are comparing values + of cards---if element 0 is the different, use that difference + to determine your answer. If element 0 is the same, + look at element 1, and so on). +Note that compare hands should return a positive number +if hand 1 is better, 0 if the hands tie, and a negative number +if hand 2 is better. + +You will also notice some functions at the bottom of eval.c that +we provided. You don't need to do anything to these---we wrote +them for you to keep the amount of code manageable. + +-------------- +That sure was a lot of code! You've been compiling and testing +along the way, right? We sure hope so :) + +However, to help you test things out even more, we've +provided some test infrastructure for you. + +If you do + +make + +You will compile the test-eval program you are +familiar with from Course 2. This program behaves +exactly like it did in Course 2. As a reminder, +it expects input where each line looks like: + +hand1 ; hand2 + +where a hand looks like something that print_hand +would output. So a valid input might be + +Kc Ac Jh 8s 9c 2s ; Ah Kh 0s 7c 7h 3c + +For each line in the input, the test program +will tell you: + - The results of your functions that went into evaluating it + (if there was a straight, if there was a flush, etc). + - What hand_eval_t was returned by evaluate_hand for each hand + - Which hand won (or if it was a tie) according to compare_hands + +Good thing you have all those test cases from Course 2 +to use with it! + +Because you have an object file test-eval.o and not the source +test-eval.c, you may need to use the debugger differently than you're +used to. For this test program, we recommend running gdb in emacs, +then first, specifying the command line argument (in this case, a file +name with your tests) + +set args tests.txt + +Then you will want to set a breakpoint in the code you wrote (since +you can't see test-eval.c, where main is, to step through it). For +example, if you just wrote the function is_straight_at, and it doesn't +behave the way you expect, you can do + +break is_straight_at + +and gdb will pause execution any time the program calls that +function. Then you can use the command "run" instead of "start," since +you don't need to pause execution at the start of main. Also recall +the command "continue," which you can review from the debugging +lesson. + + +As usual, when you are finished, use the "grade" command. +When you pass, this, congratulations! You are done +with Course 3 and ready to move on to Course 4 :) + + + + diff --git a/c3prj2_eval/cards.c b/c3prj2_eval/cards.c new file mode 100644 index 0000000..8e467ec --- /dev/null +++ b/c3prj2_eval/cards.c @@ -0,0 +1,131 @@ +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> +#include "cards.h" + + +void assert_card_valid(card_t c) { + assert(c.value >= 2 && c.value <= VALUE_ACE); + assert(c.suit >= SPADES && c.suit <= CLUBS); +} + +const char * ranking_to_string(hand_ranking_t r) { + switch (r) { + case STRAIGHT_FLUSH: + return "STRAIGHT_FLUSH"; + case FOUR_OF_A_KIND: + return "FOUR_OF_A_KIND"; + case FULL_HOUSE: + return "FULL_HOUSE"; + case FLUSH: + return "FLUSH"; + case STRAIGHT: + return "STRAIGHT"; + case THREE_OF_A_KIND: + return "THREE_OF_A_KIND"; + case TWO_PAIR: + return "TWO_PAIR"; + case PAIR: + return "PAIR"; + default: + return "NOTHING"; + } +} + +char value_letter(card_t c) { + switch(c.value) { + case VALUE_ACE: + return 'A'; + case VALUE_KING: + return 'K'; + case VALUE_QUEEN: + return 'Q'; + case VALUE_JACK: + return 'J'; + case 10: + return '0'; + default: + return '0' + c.value; + } +} + + +char suit_letter(card_t c) { + switch(c.suit) { + case SPADES: + return 's'; + case HEARTS: + return 'h'; + case DIAMONDS: + return 'd'; + default: + return 'c'; + } + +} + +void print_card(card_t c) { + printf("%c%c", value_letter(c), suit_letter(c)); +} + +card_t card_from_letters(char value_let, char suit_let) { + card_t temp; + switch(value_let) { + case 'A': + temp.value = VALUE_ACE; + break; + case 'K': + temp.value = VALUE_KING; + break; + case 'Q': + temp.value = VALUE_QUEEN; + break; + case 'J': + temp.value = VALUE_JACK; + break; + case '0': + temp.value = 10; + break; + default: + temp.value = value_let - '0'; + break; + } + switch(suit_let) { + case 's': + temp.suit = SPADES; + break; + case 'h': + temp.suit = HEARTS; + break; + case 'd': + temp.suit = DIAMONDS; + break; + case 'c': + temp.suit = CLUBS; + break; + } + assert_card_valid(temp); + return temp; +} + +card_t card_from_num(unsigned c) { + card_t temp; + if (c <= 12) { + temp.value = c + 2; + temp.suit = SPADES; + } + else if (c > 12 && c <= 25) { + temp.value = c % 13 + 2; + temp.suit = HEARTS; + } + else if (c > 25 && c <= 38) { + temp.value = c % 13 + 2; + temp.suit = DIAMONDS; + } + else { + temp.value = c % 13 + 2; + temp.suit = CLUBS; + } + assert_card_valid(temp); + return temp; +} diff --git a/c3prj2_eval/cards.h b/c3prj2_eval/cards.h new file mode 100644 index 0000000..fef0529 --- /dev/null +++ b/c3prj2_eval/cards.h @@ -0,0 +1,38 @@ +#ifndef CARD_H +#define CARD_H +#define VALUE_ACE 14 +#define VALUE_KING 13 +#define VALUE_QUEEN 12 +#define VALUE_JACK 11 +typedef enum { + SPADES, + HEARTS, + DIAMONDS, + CLUBS, + NUM_SUITS +} suit_t; + +struct card_tag { + unsigned value; + suit_t suit; +}; +typedef struct card_tag card_t; +typedef enum { + STRAIGHT_FLUSH, + FOUR_OF_A_KIND, + FULL_HOUSE, + FLUSH, + STRAIGHT, + THREE_OF_A_KIND, + TWO_PAIR, + PAIR, + NOTHING +} hand_ranking_t; +card_t card_from_num(unsigned c); +void assert_card_valid(card_t c); +const char * ranking_to_string(hand_ranking_t r) ; +char value_letter(card_t c); +char suit_letter(card_t c) ; +void print_card(card_t c); +card_t card_from_letters(char value_let, char suit_let); +#endif diff --git a/c3prj2_eval/deck-c4.o b/c3prj2_eval/deck-c4.o Binary files differnew file mode 100644 index 0000000..5fc5541 --- /dev/null +++ b/c3prj2_eval/deck-c4.o diff --git a/c3prj2_eval/deck.c b/c3prj2_eval/deck.c new file mode 100644 index 0000000..c4a3d78 --- /dev/null +++ b/c3prj2_eval/deck.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include "deck.h" + +void print_hand(deck_t * hand){ + for (size_t i = 0; i < hand->n_cards; i++) { + print_card(*hand->cards[i]); + printf(" "); + } +} + +int deck_contains(deck_t * d, card_t c) { + for (size_t i = 0; i < d->n_cards; i++) { + if (d->cards[i]->value == c.value && d->cards[i]->suit == c.suit ) { + return 1; + } + } + return 0; +} + +void shuffle(deck_t * d){ + card_t c; + for (size_t i = d->n_cards; i > 0; i--) { + int r = rand() % i; + c = *d->cards[i-1]; + *d->cards[i-1] = *d->cards[r]; + //d[i-1] = d[r]; + *d->cards[r] = c; + } +} + +void assert_full_deck(deck_t * d) { + card_t temp; + for (int i = 0; i <= 51; i++) { + temp = card_from_num(i); + assert(deck_contains(d, temp) == 1); + } + +} diff --git a/c3prj2_eval/deck.c~ b/c3prj2_eval/deck.c~ new file mode 100644 index 0000000..c4a3d78 --- /dev/null +++ b/c3prj2_eval/deck.c~ @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include "deck.h" + +void print_hand(deck_t * hand){ + for (size_t i = 0; i < hand->n_cards; i++) { + print_card(*hand->cards[i]); + printf(" "); + } +} + +int deck_contains(deck_t * d, card_t c) { + for (size_t i = 0; i < d->n_cards; i++) { + if (d->cards[i]->value == c.value && d->cards[i]->suit == c.suit ) { + return 1; + } + } + return 0; +} + +void shuffle(deck_t * d){ + card_t c; + for (size_t i = d->n_cards; i > 0; i--) { + int r = rand() % i; + c = *d->cards[i-1]; + *d->cards[i-1] = *d->cards[r]; + //d[i-1] = d[r]; + *d->cards[r] = c; + } +} + +void assert_full_deck(deck_t * d) { + card_t temp; + for (int i = 0; i <= 51; i++) { + temp = card_from_num(i); + assert(deck_contains(d, temp) == 1); + } + +} diff --git a/c3prj2_eval/deck.h b/c3prj2_eval/deck.h new file mode 100644 index 0000000..f5f44bf --- /dev/null +++ b/c3prj2_eval/deck.h @@ -0,0 +1,22 @@ +#ifndef DECK_H +#define DECK_H +#include <stdlib.h> +#include "cards.h" +struct deck_tag { + card_t ** cards; + size_t n_cards; +}; +typedef struct deck_tag deck_t; + +void print_hand(deck_t * hand); +int deck_contains(deck_t * d, card_t c) ; +void shuffle(deck_t * d); +void assert_full_deck(deck_t * d) ; +//The below functions will be done in course 4. +deck_t * make_deck_exclude(deck_t * excluded_cards); +void add_card_to(deck_t * deck, card_t c); +card_t * add_empty_card(deck_t * deck); +void free_deck(deck_t * deck) ; +deck_t * build_remaining_deck(deck_t ** hands, size_t n_hands) ; +#endif +// diff --git a/c3prj2_eval/eval-c4.o b/c3prj2_eval/eval-c4.o Binary files differnew file mode 100755 index 0000000..8cca00b --- /dev/null +++ b/c3prj2_eval/eval-c4.o diff --git a/c3prj2_eval/eval.c b/c3prj2_eval/eval.c new file mode 100644 index 0000000..b4bb37a --- /dev/null +++ b/c3prj2_eval/eval.c @@ -0,0 +1,366 @@ +#include "eval.h" +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int card_ptr_comp(const void *vp1, const void *vp2) { + const card_t *const *cp1 = vp1; + const card_t *const *cp2 = vp2; + + if ((*cp1)->value != (*cp2)->value) { + return (*cp2)->value - (*cp1)->value; + } + + return (*cp2)->suit - (*cp1)->suit; +} + +suit_t flush_suit(deck_t *hand) { + int numClub = 0; + int numDiamond = 0; + int numHeart = 0; + int numSpade = 0; + + for (size_t i = 0; i < hand->n_cards; i++) { + switch (hand->cards[i]->suit) { + case SPADES: + numSpade++; + break; + case HEARTS: + numHeart++; + break; + case DIAMONDS: + numDiamond++; + break; + default: + numClub++; + } + } + + if (numSpade >= 5) { + return SPADES; + } + if (numHeart >= 5) { + return HEARTS; + } + if (numDiamond >= 5) { + return DIAMONDS; + } + if (numClub >= 5) { + return CLUBS; + } + return NUM_SUITS; +} + +unsigned get_largest_element(unsigned *arr, size_t n) { + if (n == 0) { + return 0; + } + unsigned ans = arr[0]; + for (size_t i = 1; i < n; i++) { + if (arr[i] > ans) { + ans = arr[i]; + } + } + return ans; +} + +size_t get_match_index(unsigned *match_counts, size_t n, unsigned n_of_akind) { + + for (size_t i = 0; i < n; i++) { + if (match_counts[i] == n_of_akind) { + return i; + } + } + assert(1 == 2); +} + +ssize_t find_secondary_pair(deck_t *hand, unsigned *match_counts, + size_t match_idx) { + + for (size_t i = 0; i < hand->n_cards; i++) { + if (match_counts[i] > 1) { + if (hand->cards[i]->value != hand->cards[match_idx]->value) { + return i; + } + } + } + return -1; +} + +int is_ace_low_straight_at_five(deck_t *hand, size_t index, suit_t fs) { + int straightTally = 2; + int currentCardValue = 5; + for (size_t i = index + 1; i < hand->n_cards; i++) { + if (straightTally == 5) { + return -1; + } + + if (hand->cards[i]->value == currentCardValue) { + continue; + } + + if (hand->cards[i]->value == currentCardValue - 1) { + if (fs == NUM_SUITS || hand->cards[i]->suit == fs) { + straightTally++; + currentCardValue--; + } else { + continue; + } + } else { + break; + } + } + if (straightTally == 5) { + return -1; + } + return 0; +} + +int is_ace_low_straight_at(deck_t *hand, size_t index, suit_t fs) { + int currentCardValue = hand->cards[index]->value; + if (currentCardValue == 5) { + return is_ace_low_straight_at_five(hand, index, fs); + } + + if (currentCardValue == VALUE_ACE) { + for (size_t i = index + 1; i < hand->n_cards; i++) { + + if (hand->cards[i]->value == currentCardValue) { + continue; + } + + if (hand->cards[i]->value == 5) { + return is_ace_low_straight_at_five(hand, i, fs); + } + } + } + + return 0; +} + +int is_straight_at(deck_t *hand, size_t index, suit_t fs) { + if (hand->cards[index]->suit != fs && fs != NUM_SUITS) { + return 0; + } + int currentCardValue = hand->cards[index]->value; + if (currentCardValue < 5) { + return 0; + } + if (currentCardValue == 5) { + if (hand->cards[0]->value != 14) { + return 0; + } else { + return is_ace_low_straight_at(hand, index, fs); + } + } + + int straightTally = 1; + for (size_t i = index + 1; i < hand->n_cards; i++) { + if (straightTally == 5) { + return 1; + } + + if (hand->cards[i]->value == currentCardValue) { + continue; + } + + if (hand->cards[i]->value == currentCardValue - 1) { + if (fs == NUM_SUITS || hand->cards[i]->suit == fs) { + straightTally++; + currentCardValue--; + } else { + continue; + } + } else { + break; + } + } + if (straightTally == 5) { + return 1; + } + + if (hand->cards[index]->value == VALUE_ACE) { + return is_ace_low_straight_at(hand, index, fs); + } else { + return 0; + } +} + +hand_eval_t build_hand_from_match(deck_t *hand, unsigned n, hand_ranking_t what, + size_t idx) { + + hand_eval_t ans; + ans.ranking = what; + for (int i = 0; i < n; i++) { + ans.cards[i] = hand->cards[idx + i]; + } + + if (idx == 0) { + for (int i = n; i < 5; i++) { + ans.cards[i] = hand->cards[i]; + } + } else if (idx >= 5 - n) { + for (int i = 0; i < 5 - n; i++) { + ans.cards[n + i] = hand->cards[i]; + } + } else { + for (int i = 0; i < idx; i++) { + ans.cards[n + i] = hand->cards[i]; + } + for (int i = idx + n; i < 5; i++) { + ans.cards[i] = hand->cards[i]; + } + } + return ans; +} + +int compare_hands(deck_t *hand1, deck_t *hand2) { + + qsort(hand1->cards, hand1->n_cards, sizeof(card_t), card_ptr_comp); + qsort(hand2->cards, hand2->n_cards, sizeof(card_t), card_ptr_comp); + hand_eval_t ht1 = evaluate_hand(hand1); + hand_eval_t ht2 = evaluate_hand(hand2); + + if (ht1.ranking != ht2.ranking) { + return ht2.ranking - ht1.ranking; + } + + for (int i = 0; i < 5; i++) { + if (ht1.cards[i]->value == ht2.cards[i]->value) { + continue; + } else { + return ht1.cards[i]->value - ht2.cards[i]->value; + } + } + return 0; +} + +// You will write this function in Course 4. +// For now, we leave a prototype (and provide our +// implementation in eval-c4.o) so that the +// other functions we have provided can make +// use of get_match_counts. +unsigned *get_match_counts(deck_t *hand); + +// We provide the below functions. You do NOT need to modify them +// In fact, you should not modify them! + +// This function copies a straight starting at index "ind" from deck "from". +// This copies "count" cards (typically 5). +// into the card array "to" +// if "fs" is NUM_SUITS, then suits are ignored. +// if "fs" is any other value, a straight flush (of that suit) is copied. +void copy_straight(card_t **to, deck_t *from, size_t ind, suit_t fs, + size_t count) { + assert(fs == NUM_SUITS || from->cards[ind]->suit == fs); + unsigned nextv = from->cards[ind]->value; + size_t to_ind = 0; + while (count > 0) { + assert(ind < from->n_cards); + assert(nextv >= 2); + assert(to_ind < 5); + if (from->cards[ind]->value == nextv && + (fs == NUM_SUITS || from->cards[ind]->suit == fs)) { + to[to_ind] = from->cards[ind]; + to_ind++; + count--; + nextv--; + } + ind++; + } +} + +// This looks for a straight (or straight flush if "fs" is not NUM_SUITS) +// in "hand". It calls the student's is_straight_at for each possible +// index to do the work of detecting the straight. +// If one is found, copy_straight is used to copy the cards into +// "ans". +int find_straight(deck_t *hand, suit_t fs, hand_eval_t *ans) { + if (hand->n_cards < 5) { + return 0; + } + for (size_t i = 0; i <= hand->n_cards - 5; i++) { + int x = is_straight_at(hand, i, fs); + if (x != 0) { + if (x < 0) { // ace low straight + assert(hand->cards[i]->value == VALUE_ACE && + (fs == NUM_SUITS || hand->cards[i]->suit == fs)); + ans->cards[4] = hand->cards[i]; + size_t cpind = i + 1; + while (hand->cards[cpind]->value != 5 || + !(fs == NUM_SUITS || hand->cards[cpind]->suit == fs)) { + cpind++; + assert(cpind < hand->n_cards); + } + copy_straight(ans->cards, hand, cpind, fs, 4); + } else { + copy_straight(ans->cards, hand, i, fs, 5); + } + return 1; + } + } + return 0; +} + +// This function puts all the hand evaluation logic together. +// This function is longer than we generally like to make functions, +// and is thus not so great for readability :( +hand_eval_t evaluate_hand(deck_t *hand) { + suit_t fs = flush_suit(hand); + hand_eval_t ans; + if (fs != NUM_SUITS) { + if (find_straight(hand, fs, &ans)) { + ans.ranking = STRAIGHT_FLUSH; + return ans; + } + } + unsigned *match_counts = get_match_counts(hand); + unsigned n_of_a_kind = get_largest_element(match_counts, hand->n_cards); + assert(n_of_a_kind <= 4); + size_t match_idx = get_match_index(match_counts, hand->n_cards, n_of_a_kind); + ssize_t other_pair_idx = find_secondary_pair(hand, match_counts, match_idx); + free(match_counts); + if (n_of_a_kind == 4) { // 4 of a kind + return build_hand_from_match(hand, 4, FOUR_OF_A_KIND, match_idx); + } else if (n_of_a_kind == 3 && other_pair_idx >= 0) { // full house + ans = build_hand_from_match(hand, 3, FULL_HOUSE, match_idx); + ans.cards[3] = hand->cards[other_pair_idx]; + ans.cards[4] = hand->cards[other_pair_idx + 1]; + return ans; + } else if (fs != NUM_SUITS) { // flush + ans.ranking = FLUSH; + size_t copy_idx = 0; + for (size_t i = 0; i < hand->n_cards; i++) { + if (hand->cards[i]->suit == fs) { + ans.cards[copy_idx] = hand->cards[i]; + copy_idx++; + if (copy_idx >= 5) { + break; + } + } + } + return ans; + } else if (find_straight(hand, NUM_SUITS, &ans)) { // straight + ans.ranking = STRAIGHT; + return ans; + } else if (n_of_a_kind == 3) { // 3 of a kind + return build_hand_from_match(hand, 3, THREE_OF_A_KIND, match_idx); + } else if (other_pair_idx >= 0) { // two pair + assert(n_of_a_kind == 2); + ans = build_hand_from_match(hand, 2, TWO_PAIR, match_idx); + ans.cards[2] = hand->cards[other_pair_idx]; + ans.cards[3] = hand->cards[other_pair_idx + 1]; + if (match_idx > 0) { + ans.cards[4] = hand->cards[0]; + } else if (other_pair_idx > 2) { // if match_idx is 0, first pair is in 01 + // if other_pair_idx > 2, then, e.g. A A K Q Q + ans.cards[4] = hand->cards[2]; + } else { // e.g., A A K K Q + ans.cards[4] = hand->cards[4]; + } + return ans; + } else if (n_of_a_kind == 2) { + return build_hand_from_match(hand, 2, PAIR, match_idx); + } + return build_hand_from_match(hand, 0, NOTHING, 0); +} diff --git a/c3prj2_eval/eval.c~ b/c3prj2_eval/eval.c~ new file mode 100644 index 0000000..5e880a2 --- /dev/null +++ b/c3prj2_eval/eval.c~ @@ -0,0 +1,366 @@ +#include "eval.h" +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int card_ptr_comp(const void *vp1, const void *vp2) { + const card_t *const *cp1 = vp1; + const card_t *const *cp2 = vp2; + + if ((*cp1)->value != (*cp2)->value) { + return (*cp2)->value - (*cp1)->value; + } + + return (*cp2)->suit - (*cp1)->suit; +} + +suit_t flush_suit(deck_t *hand) { + int numClub = 0; + int numDiamond = 0; + int numHeart = 0; + int numSpade = 0; + + for (size_t i = 0; i < hand->n_cards; i++) { + switch (hand->cards[i]->suit) { + case SPADES: + numSpade++; + break; + case HEARTS: + numHeart++; + break; + case DIAMONDS: + numDiamond++; + break; + default: + numClub++; + } + } + + if (numSpade >= 5) { + return SPADES; + } + if (numHeart >= 5) { + return HEARTS; + } + if (numDiamond >= 5) { + return DIAMONDS; + } + if (numClub >= 5) { + return CLUBS; + } + return NUM_SUITS; +} + +unsigned get_largest_element(unsigned *arr, size_t n) { + if (n == 0) { + return 0; + } + unsigned ans = arr[0]; + for (size_t i = 1; i < n; i++) { + if (arr[i] > ans) { + ans = arr[i]; + } + } + return ans; +} + +size_t get_match_index(unsigned *match_counts, size_t n, unsigned n_of_akind) { + + for (size_t i = 0; i < n; i++) { + if (match_counts[i] == n_of_akind) { + return i; + } + } + assert(1 == 2); +} + +ssize_t find_secondary_pair(deck_t *hand, unsigned *match_counts, + size_t match_idx) { + + for (size_t i = 0; i < hand->n_cards; i++) { + if (match_counts[i] > 1) { + if (hand->cards[i]->value != hand->cards[match_idx]->value) { + return i; + } + } + } + return -1; +} + +int is_ace_low_straight_at_five(deck_t *hand, size_t index, suit_t fs) { + int straightTally = 2; + int currentCardValue = 5; + for (size_t i = index + 1; i < hand->n_cards; i++) { + if (straightTally == 5) { + return -1; + } + + if (hand->cards[i]->value == currentCardValue) { + continue; + } + + if (hand->cards[i]->value == currentCardValue - 1) { + if (fs == NUM_SUITS || hand->cards[i]->suit == fs) { + straightTally++; + currentCardValue--; + } else { + continue; + } + } else { + break; + } + } + if (straightTally == 5) { + return -1; + } + return 0; +} + +int is_ace_low_straight_at(deck_t *hand, size_t index, suit_t fs) { + int currentCardValue = hand->cards[index]->value; + if (currentCardValue == 5) { + return is_ace_low_straight_at_five(hand, index, fs); + } + + if (currentCardValue == VALUE_ACE) { + for (size_t i = index + 1; i < hand->n_cards; i++) { + + if (hand->cards[i]->value == currentCardValue) { + continue; + } + + if (hand->cards[i]->value == 5) { + return is_ace_low_straight_at_five(hand, i, fs); + } + } + } + + return 0; +} + +int is_straight_at(deck_t *hand, size_t index, suit_t fs) { + if (hand->cards[index]->suit != fs && fs != NUM_SUITS) { + return 0; + } + int currentCardValue = hand->cards[index]->value; + if (currentCardValue < 5) { + return 0; + } + if (currentCardValue == 5) { + if (hand->cards[0]->value != 14) { + return 0; + } else { + return is_ace_low_straight_at(hand, index, fs); + } + } + + int straightTally = 1; + for (size_t i = index + 1; i < hand->n_cards; i++) { + if (straightTally == 5) { + return 1; + } + + if (hand->cards[i]->value == currentCardValue) { + continue; + } + + if (hand->cards[i]->value == currentCardValue - 1) { + if (fs == NUM_SUITS || hand->cards[i]->suit == fs) { + straightTally++; + currentCardValue--; + } else { + continue; + } + } else { + break; + } + } + if (straightTally == 5) { + return 1; + } + + if (hand->cards[index]->value == VALUE_ACE) { + return is_ace_low_straight_at(hand, index, fs); + } else { + return 0; + } +} + +hand_eval_t build_hand_from_match(deck_t *hand, unsigned n, hand_ranking_t what, + size_t idx) { + + hand_eval_t ans; + ans.ranking = what; + for (int i = 0; i < n; i++) { + ans.cards[i] = hand->cards[idx + i]; + } + + if (idx == 0) { + for (int i = n; i < 5; i++) { + ans.cards[i] = hand->cards[i]; + } + } else if (idx >= 5 - n) { + for (int i = 0; i < 5 - n; i++) { + ans.cards[n + i] = hand->cards[i]; + } + } else { + for (int i = 0; i < idx; i++) { + ans.cards[n + i] = hand->cards[i]; + } + for (int i = idx + n; i < 5; i++) { + ans.cards[i] = hand->cards[i]; + } + } + return ans; +} + +int compare_hands(deck_t *hand1, deck_t *hand2) { + + qsort(hand1->cards, hand1->n_cards, sizeof(card_t), card_ptr_comp); + qsort(hand2->cards, hand2->n_cards, sizeof(card_t), card_ptr_comp); + hand_eval_t ht1 = evaluate_hand(hand1); + hand_eval_t ht2 = evaluate_hand(hand2); + + if (ht1.ranking != ht2.ranking) { + return ht1.ranking - ht2.ranking; + } + + for (int i = 0; i < 5; i++) { + if (ht1.cards[i]->value == ht2.cards[i]->value) { + continue; + } else { + return ht1.cards[i]->value - ht2.cards[i]->value; + } + } + return 0; +} + +// You will write this function in Course 4. +// For now, we leave a prototype (and provide our +// implementation in eval-c4.o) so that the +// other functions we have provided can make +// use of get_match_counts. +unsigned *get_match_counts(deck_t *hand); + +// We provide the below functions. You do NOT need to modify them +// In fact, you should not modify them! + +// This function copies a straight starting at index "ind" from deck "from". +// This copies "count" cards (typically 5). +// into the card array "to" +// if "fs" is NUM_SUITS, then suits are ignored. +// if "fs" is any other value, a straight flush (of that suit) is copied. +void copy_straight(card_t **to, deck_t *from, size_t ind, suit_t fs, + size_t count) { + assert(fs == NUM_SUITS || from->cards[ind]->suit == fs); + unsigned nextv = from->cards[ind]->value; + size_t to_ind = 0; + while (count > 0) { + assert(ind < from->n_cards); + assert(nextv >= 2); + assert(to_ind < 5); + if (from->cards[ind]->value == nextv && + (fs == NUM_SUITS || from->cards[ind]->suit == fs)) { + to[to_ind] = from->cards[ind]; + to_ind++; + count--; + nextv--; + } + ind++; + } +} + +// This looks for a straight (or straight flush if "fs" is not NUM_SUITS) +// in "hand". It calls the student's is_straight_at for each possible +// index to do the work of detecting the straight. +// If one is found, copy_straight is used to copy the cards into +// "ans". +int find_straight(deck_t *hand, suit_t fs, hand_eval_t *ans) { + if (hand->n_cards < 5) { + return 0; + } + for (size_t i = 0; i <= hand->n_cards - 5; i++) { + int x = is_straight_at(hand, i, fs); + if (x != 0) { + if (x < 0) { // ace low straight + assert(hand->cards[i]->value == VALUE_ACE && + (fs == NUM_SUITS || hand->cards[i]->suit == fs)); + ans->cards[4] = hand->cards[i]; + size_t cpind = i + 1; + while (hand->cards[cpind]->value != 5 || + !(fs == NUM_SUITS || hand->cards[cpind]->suit == fs)) { + cpind++; + assert(cpind < hand->n_cards); + } + copy_straight(ans->cards, hand, cpind, fs, 4); + } else { + copy_straight(ans->cards, hand, i, fs, 5); + } + return 1; + } + } + return 0; +} + +// This function puts all the hand evaluation logic together. +// This function is longer than we generally like to make functions, +// and is thus not so great for readability :( +hand_eval_t evaluate_hand(deck_t *hand) { + suit_t fs = flush_suit(hand); + hand_eval_t ans; + if (fs != NUM_SUITS) { + if (find_straight(hand, fs, &ans)) { + ans.ranking = STRAIGHT_FLUSH; + return ans; + } + } + unsigned *match_counts = get_match_counts(hand); + unsigned n_of_a_kind = get_largest_element(match_counts, hand->n_cards); + assert(n_of_a_kind <= 4); + size_t match_idx = get_match_index(match_counts, hand->n_cards, n_of_a_kind); + ssize_t other_pair_idx = find_secondary_pair(hand, match_counts, match_idx); + free(match_counts); + if (n_of_a_kind == 4) { // 4 of a kind + return build_hand_from_match(hand, 4, FOUR_OF_A_KIND, match_idx); + } else if (n_of_a_kind == 3 && other_pair_idx >= 0) { // full house + ans = build_hand_from_match(hand, 3, FULL_HOUSE, match_idx); + ans.cards[3] = hand->cards[other_pair_idx]; + ans.cards[4] = hand->cards[other_pair_idx + 1]; + return ans; + } else if (fs != NUM_SUITS) { // flush + ans.ranking = FLUSH; + size_t copy_idx = 0; + for (size_t i = 0; i < hand->n_cards; i++) { + if (hand->cards[i]->suit == fs) { + ans.cards[copy_idx] = hand->cards[i]; + copy_idx++; + if (copy_idx >= 5) { + break; + } + } + } + return ans; + } else if (find_straight(hand, NUM_SUITS, &ans)) { // straight + ans.ranking = STRAIGHT; + return ans; + } else if (n_of_a_kind == 3) { // 3 of a kind + return build_hand_from_match(hand, 3, THREE_OF_A_KIND, match_idx); + } else if (other_pair_idx >= 0) { // two pair + assert(n_of_a_kind == 2); + ans = build_hand_from_match(hand, 2, TWO_PAIR, match_idx); + ans.cards[2] = hand->cards[other_pair_idx]; + ans.cards[3] = hand->cards[other_pair_idx + 1]; + if (match_idx > 0) { + ans.cards[4] = hand->cards[0]; + } else if (other_pair_idx > 2) { // if match_idx is 0, first pair is in 01 + // if other_pair_idx > 2, then, e.g. A A K Q Q + ans.cards[4] = hand->cards[2]; + } else { // e.g., A A K K Q + ans.cards[4] = hand->cards[4]; + } + return ans; + } else if (n_of_a_kind == 2) { + return build_hand_from_match(hand, 2, PAIR, match_idx); + } + return build_hand_from_match(hand, 0, NOTHING, 0); +} diff --git a/c3prj2_eval/eval.h b/c3prj2_eval/eval.h new file mode 100644 index 0000000..1967917 --- /dev/null +++ b/c3prj2_eval/eval.h @@ -0,0 +1,13 @@ +#ifndef EVAL_H +#define EVAL_H +#include "deck.h" +struct hand_eval_tag { + hand_ranking_t ranking; + card_t *cards[5]; +}; +typedef struct hand_eval_tag hand_eval_t; + +hand_eval_t evaluate_hand(deck_t * hand) ; +int compare_hands(deck_t * hand1, deck_t * hand2) ; + +#endif diff --git a/c3prj2_eval/future.o b/c3prj2_eval/future.o Binary files differnew file mode 100755 index 0000000..a770c6a --- /dev/null +++ b/c3prj2_eval/future.o diff --git a/c3prj2_eval/grade.txt b/c3prj2_eval/grade.txt new file mode 100644 index 0000000..b751b74 --- /dev/null +++ b/c3prj2_eval/grade.txt @@ -0,0 +1,49 @@ +Grading at Sat 11 Dec 2021 09:52:46 PM UTC +Compiling your code +rm -f test poker cards.o my-test-main.o *~ +cc -ggdb3 -Wall -Werror -pedantic -std=gnu99 -c -o deck.o deck.c +cc -ggdb3 -Wall -Werror -pedantic -std=gnu99 -c -o eval.o eval.c +cc -ggdb3 -Wall -Werror -pedantic -std=gnu99 -c -o cards.o cards.c +gcc -o test-eval -ggdb3 deck.o deck-c4.o eval-c4.o eval.o test-eval.o cards.o input.o future.o +Testcase 1: Trying hands with nothing + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 2: Trying hands with pairs + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 3: Trying hands with 2 pairs + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 4: Trying hands with 3 of a kind + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 5: Trying hands with straights + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 6: Trying hands with flushes + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 7: Trying hands with full houses + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 8: Trying hands with 4 of a kind + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 9: Trying hands with straight flushes + Checking the output +Your file matched the expected output + - Testcase passed +Testcase 10: Trying each type of hand ranking + Checking the output +Your file matched the expected output + - Testcase passed + +Overall Grade: A diff --git a/c3prj2_eval/input.o b/c3prj2_eval/input.o Binary files differnew file mode 100755 index 0000000..65cc44b --- /dev/null +++ b/c3prj2_eval/input.o diff --git a/c3prj2_eval/t1.txt b/c3prj2_eval/t1.txt new file mode 100644 index 0000000..cc33372 --- /dev/null +++ b/c3prj2_eval/t1.txt @@ -0,0 +1,2 @@ +7c 3d 9h Qd As 2s; Kc 2h Js 6c 4d 7h + diff --git a/c3prj2_eval/t2.txt b/c3prj2_eval/t2.txt new file mode 100644 index 0000000..efc6951 --- /dev/null +++ b/c3prj2_eval/t2.txt @@ -0,0 +1,2 @@ +0s 9s 8c 7h 6d; Js 0c 9s 8d 7c + diff --git a/c3prj2_eval/t3.txt b/c3prj2_eval/t3.txt new file mode 100644 index 0000000..6620302 --- /dev/null +++ b/c3prj2_eval/t3.txt @@ -0,0 +1,2 @@ +As 5c 4h 3s 2c; 6c 5h 4s 3s 2d + diff --git a/c3prj2_eval/t4.txt b/c3prj2_eval/t4.txt new file mode 100644 index 0000000..3d961ef --- /dev/null +++ b/c3prj2_eval/t4.txt @@ -0,0 +1,2 @@ +Ac As Kc Ks Qs Js 0s; Ad Kh Qh Jh Js 0h 9h + diff --git a/c3prj2_eval/t5.txt b/c3prj2_eval/t5.txt new file mode 100644 index 0000000..d42cde9 --- /dev/null +++ b/c3prj2_eval/t5.txt @@ -0,0 +1,2 @@ +As Kc Qs Js 0s 2s; Kc Kd Kh Ks 8c 6d + diff --git a/c3prj2_eval/test-eval.o b/c3prj2_eval/test-eval.o Binary files differnew file mode 100644 index 0000000..92f6913 --- /dev/null +++ b/c3prj2_eval/test-eval.o diff --git a/c3prj2_eval/tests.txt b/c3prj2_eval/tests.txt new file mode 100755 index 0000000..63059d5 --- /dev/null +++ b/c3prj2_eval/tests.txt @@ -0,0 +1,30 @@ +Kc Qs Jd 9h 8c 7s 6d; Ac Qs Jd 9h 8c 7s 6d +Kh Ac Kc 8c 7h 3d 6s; Kh As 7h 3s 5d 6h Ks +As Ah Ks Kd 2h 3d 6s; Ac Ad Kh Kc Jd 3d 6s +Kh Kc Kd Ac 3s 6h 2s; Kh Kc Kd Ac 7h 6s 3d +Ks Qd Js 0h 6h 9d 2s; 0h 5d 8s 4s 3c 2h Ah +Ah Qh 5s 6d 9h 7h 2h; 4s 6s 5s 7d 0s Qs As +Kc Ks 3d 0c 0s Kh 8d; 9h Jd 9s Js 9d 3d 0c +0c 0s 0h 2d 7c 0d 2h; Kc Kd Kh Ks 3c 4h 5d +As 2d 3c Ks Qs Js 0s; 5s 4s 3s 2d Jc 2s As +As Ks 4d 5d Jd 0d Qd; Kd Qd Js 0s 9s 4s 5s +Qd Jd 0d 9s 9h 8h 8c; Jd 0d 9d 8s 8h 7h 7c +0c 0s 8s 7d 6d 6s 5c; Js 0s 8s 7d 6s 5c 4c +2d 3d 6d 8d 7c As Js; 2d 3d 6d 8d 7c Ah Ac +Ac 2d 3c 0s 4d 5s 0h; Ac 2d 3c 0s 4d 8h Jh +6c 3c 6d 4h Qs As 2d; 6c 3c 6d 4h Qs 2h Jh +6c 3c 6d 4h Qs 6h 2d; 6c 3c 6d 4h Qs 2h Jh +6c 3c 6d 4h 6h Qs 2d; 6c 3c 6d 4h Qs 6s Jh +6c 3c 6d 4h Qs 6h 2d; 6c 3c 6d 4h Qs 6s Ac +2d 3c 3d Jh Qs Js 3h; 2d 3c 3d Jh Qs Jd 3c +2d 3c 3d Jh Qs Js 2s; 2d 3c 3d Jh Qs Jd 3c +7d 2c 8h Ah 2h 9h 0h; 7d 2c 8h Ah 2h Jh Qh +6h 7h 8d 9d Jd 0d Qh; 6h 7h 8d 9d Jd 2c 9s +2c 5d 9h 8h 7h 3d As; 2c 5d 9h 8h 7h 0h Jh +Ah 2c 3c 7h 4s 5s 0d; Ah 2c 3c 7h 4s 0s 0h +4s 3s 8h 2s 9d As 5s; 4s 3s 8h 2s 9d 9h 9s +9d 9h 9s 8c 9c 0h Ah; 9d 9h 9s 8c 9c 0c As +9d 9h 8h 9c 7h 6h 5h; 9d 9h 8h 9c 7h 6c 5c +2s 3s 4s 6s 5h 8s 9h; As 2s 3s 4s 5s 8h 9h +2s 3s 4h 5s 6s 4s 0h; 2s 3s 4h 5s 6s 8d Kh +Kc Ac 2c 3c 2s Qc 7c; Kc Ac 2c As 2s 8c 5c diff --git a/c4prj1_deck/README b/c4prj1_deck/README new file mode 100644 index 0000000..efbcae7 --- /dev/null +++ b/c4prj1_deck/README @@ -0,0 +1,100 @@ +Poker: Almost There! +-------------------- +Now it is time to wrap up your poker project! + +You have four major things to do: + (1) Write a few deck/evaluation functions that need + malloc/realloc/free (which you were not ready for in + Course 3). + (2) Write the code to handle unknown cards (which + we'll call "future cards" because they will be + known in the future). + (3) Read the input. + (4) Write a main function, which puts this all together + and does the Monte Carlo simulation loop + (repeatedly drawing different random cards + for the future cards). + +We're going to split this into 3 parts. In this assignment, +you will do (1) above. In the next assignment, you will do (2) and (3), +which will work together to process the input. In the final assignment, +you will do (4), completing this project! + + +Finish deck/evaluation +---------------------- +Add these functions to deck.c: + - void add_card_to(deck_t * deck, card_t c); + Add the particular card to the given deck (which will + involve reallocing the array of cards in that deck). + - card_t * add_empty_card(deck_t * deck); + Add a card whose value and suit are both 0, and return a pointer + to it in the deck. + This will add an invalid card to use as a placeholder + for an unknown card. + - deck_t * make_deck_exclude(deck_t * excluded_cards); + Create a deck that is full EXCEPT for all the cards + that appear in excluded_cards. For example, + if excluded_cards has Kh and Qs, you would create + a deck with 50 cards---all of them except Kh and Qs. + You will need to use malloc to allocate this deck. + (You will want this for the next function). + Don't forget you wrote card_t card_from_num(unsigned c) + in Course 2 and int deck_contains(deck_t * d, card_t c) + in Course 3! They might be useful here. + - deck_t * build_remaining_deck(deck_t ** hands, size_t n_hands) ; + This function takes an array of hands (remember + that we use deck_t to represent a hand). It then builds + the deck of cards that remain after those cards have + been removed from a full deck. For example, if we have + two hands: + Kh Qs ?0 ?1 ?2 ?3 ?4 + As Ac ?0 ?1 ?2 ?3 ?4 + then this function should build a deck with 48 + cards (all but As Ac Kh Qs). You can just build + one deck with all the cards from all the hands + (remember you just wrote add_card_to), + and then pass it to make_deck_exclude. + - void free_deck(deck_t * deck) ; + Free the memory allocated to a deck of cards. + For example, if you do + deck_t * d = make_excluded_deck(something); + free_deck(d); + it should free all the memory allocated by make_excluded_deck. + Once you have written it, add calls to free_deck anywhere you + need to to avoid memory leaks. + +Next, go back to eval.c, and implement: + - unsigned * get_match_counts(deck_t * hand) ; + You will find its prototype after the code you wrote + in Course 3, and before the functions we + provided for you. Replace the prototype with + your implementation. + + Given a hand (deck_t) of cards, this function + allocates an array of unsigned ints with as + many elements as there are cards in the hand. + It then fills in this array with + the "match counts" of the corresponding cards. + That is, for each card in the original hand, + the value in the match count array + is how many times a card of the same + value appears in the hand. For example, + given + Ks Kh Qs Qh 0s 9d 9c 9h + This function would return + 2 2 2 2 1 3 3 3 + because there are 2 kings, 2 queens, + 1 ten, and 3 nines. + +We recommend you write your own testing code in a separate +C file (e.g., test-c4deck.c) and run your own test cases +before you submit. When you are satisfied with the correctness +of your code, you should grade this assignment. + +As a final note, we remind you that since previously released files +have been symlinked into other directories you may need to add the +original versions (as this is where your changes are reflected). For +example, in this assignment we have you modify deck.c which is symlinked +to ../c3prj1_deck/deck.c. This means when you submit the assignment you +need to add and commit the actual file, not the symlink itself. diff --git a/c4prj1_deck/cards.c b/c4prj1_deck/cards.c new file mode 120000 index 0000000..1b5fce4 --- /dev/null +++ b/c4prj1_deck/cards.c @@ -0,0 +1 @@ +../c2prj1_cards/cards.c
\ No newline at end of file diff --git a/c4prj1_deck/cards.h b/c4prj1_deck/cards.h new file mode 120000 index 0000000..7a280fd --- /dev/null +++ b/c4prj1_deck/cards.h @@ -0,0 +1 @@ +../c2prj1_cards/cards.h
\ No newline at end of file diff --git a/c4prj1_deck/deck.c b/c4prj1_deck/deck.c new file mode 120000 index 0000000..382208f --- /dev/null +++ b/c4prj1_deck/deck.c @@ -0,0 +1 @@ +../c3prj1_deck/deck.c
\ No newline at end of file diff --git a/c4prj1_deck/deck.h b/c4prj1_deck/deck.h new file mode 120000 index 0000000..705003d --- /dev/null +++ b/c4prj1_deck/deck.h @@ -0,0 +1 @@ +../c3prj1_deck/deck.h
\ No newline at end of file diff --git a/c4prj1_deck/eval.c b/c4prj1_deck/eval.c new file mode 120000 index 0000000..c1f5d89 --- /dev/null +++ b/c4prj1_deck/eval.c @@ -0,0 +1 @@ +../c3prj2_eval/eval.c
\ No newline at end of file diff --git a/c4prj1_deck/eval.h b/c4prj1_deck/eval.h new file mode 120000 index 0000000..7fb381b --- /dev/null +++ b/c4prj1_deck/eval.h @@ -0,0 +1 @@ +../c3prj2_eval/eval.h
\ No newline at end of file |