Last active
August 29, 2015 14:06
-
-
Save jadudm/227105e0c3dbf2488b70 to your computer and use it in GitHub Desktop.
A Square Encoder Reading and Coding Exercise
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(I recommend you turn on line wrap by going to View->Line Wrap.) | |
# The Challenge: Square Code | |
One classic method for composing secret messages is called a square code. The spaces are removed from the english text and the characters are written into a square (or rectangle). For example, the sentence "If man was meant to stay on the ground god would have given us roots" is 54 characters long, so it is written into a rectangle with 7 rows and 8 columns. | |
ifmanwas | |
meanttos | |
tayonthe | |
groundgo | |
dwouldha | |
vegivenu | |
sroots | |
The coded message is obtained by reading down the columns going left to right. For example, the message above is coded as: | |
imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau | |
################# | |
# The Code | |
You've been given a starter template to work with. | |
##### | |
## square.c | |
This is where the majority of your code will go. You may introduce new functions, but you may not change the names of anything there, because this will break the test suite. | |
##### | |
## square_test.c | |
This file contains the test suite that will be run against your code. | |
To run it, type | |
make test | |
on the command line, and then execute the program square_test as follows: | |
./square_test | |
This will tell you if your C code is correct according to the tests your Evil Professor has provided you. | |
##### | |
## square.h | |
If you add any new functions to square.c, you will need to add headers for them here as well. I don't expect you to need to add new functions for this assignment, however. | |
##### | |
## Makefile | |
This is a good thing to look at; it takes care of defining how your programs should be compileted. We'll talk more about Makefiles as the term progresses. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "square.h" | |
int main () { | |
char *msg; | |
int length; | |
for (int i = 0 ; i < get_number_of_messages(); i++) { | |
msg = read_message(i); | |
length = get_message_length(i); | |
for (int i = 0; i < length; i++) { | |
printf("%c", msg[i]); | |
} | |
printf("\n"); | |
} | |
return 0; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# QUESTIONS FOR CONSIDERATION | |
# | |
CFLAGS=-std=c99 -Wall -g | |
test: square | |
gcc ${CFLAGS} -o square_test square.o square_test.c | |
encoder: square | |
gcc ${CFLAGS} -o encoder square.o encoder.c | |
square: | |
gcc ${CFLAGS} -c square.c | |
clean: | |
rm -f square square_test encoder square.o | |
all: clean square test encoder |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
God has made of one blood all peoples of the earth | |
There is dignity in all labor | |
Imagination is more important than knowledge | |
Do not dwell in the past, do not dream of the future, concentrate the mind on the present moment | |
The best place to find a helping hand is at the end of your own arm | |
If your strength is small, don't carry heavy burdens. If your words are worthless, don't give advice | |
If you are patient in one moment of anger, you will escape a hundred days of sorrow | |
If you must play, decide upon three things at the start: the rules of the game, the stakes, and the quitting time | |
Learning is a treasure that will follow its owner everywhere | |
A change is as good as a rest | |
A known mistake is better than an unknown truth | |
Arrogance is a weed that grows mostly on a dunghill | |
A cutting word is worse than a bowstring, a cut may heal, but the cut of the tongue does not | |
A fool looks for dung where the cow never browsed | |
If you don't stand for something, you will fall for something | |
Adversity is the foundation of virtue | |
An excess of courtesy is discourtesy | |
Opinions founded on prejudice are always sustained with the greatest violence | |
In a country well governed, poverty is something to be ashamed of. In a country badly governed, wealth is something to be ashamed of | |
The cautious seldom err |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include "square.h" | |
char IGNORE[] = {'.', ' ', ',', 0x27, ':'}; | |
FILE *open_message_file () { | |
return fopen("SEKRETS.txt", "r"); | |
} | |
void close_message_file(FILE *fp) { | |
if (fp != NULL) { | |
fclose(fp); | |
} | |
} | |
int get_number_of_messages () { | |
FILE *fp; | |
int line_count; | |
fp = open_message_file(); | |
line_count = 0; | |
while (!feof(fp)) { | |
int c = getc(fp); | |
if (c == '\n') { | |
line_count++; | |
} | |
} | |
close_message_file(fp); | |
return line_count; | |
} | |
FILE *advance_to_msg (int msg_ndx) { | |
FILE *fp; | |
int line_count; | |
fp = open_message_file(); | |
line_count = 0; | |
while (!feof(fp) && line_count < msg_ndx) { | |
int c = getc(fp); | |
if (c == '\n') { | |
line_count++; | |
} | |
} | |
return fp; | |
} | |
int get_message_length (int msg_ndx) { | |
FILE *fp; | |
int length = 0; | |
char c; | |
fp = advance_to_msg (msg_ndx); | |
while((c = getc(fp)) != '\n') { | |
int OK = 1; | |
for (int i = 0; i < sizeof(IGNORE); i++) { | |
if (c == IGNORE[i]) { | |
OK = 0; | |
} | |
} | |
if (OK) { | |
length++; | |
} | |
} | |
close_message_file(fp); | |
return length; | |
} | |
char *read_message (int msg_ndx) { | |
FILE *fp; | |
char *msg; | |
int ndx; | |
int length; | |
char c; | |
ndx = 0; | |
length = get_message_length(msg_ndx); | |
fp = advance_to_msg(msg_ndx); | |
msg = (char*) malloc(length * sizeof(char)); | |
while((c = getc(fp)) != '\n') { | |
int OK = 1; | |
for (int i = 0; i < sizeof(IGNORE); i++) { | |
/* printf("CHECKING %c vs %c\n", c, IGNORE[i]); */ | |
if (c == IGNORE[i]) { | |
OK = 0; | |
} | |
} | |
if (OK) { | |
msg[ndx] = c; | |
ndx += 1; | |
} | |
} | |
close_message_file(fp); | |
return msg; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SQUARE_H | |
/* MinUnit Source Code */ | |
/* http://www.jera.com/techinfo/jtns/jtn002.html */ | |
/* BEGIN NO STUDENT COMMENTS */ | |
#define mu_assert(message, test) do { if (!(test)) return message; } while (0) | |
#define mu_run_test(test) do { char *message = test(); tests_run++; \ | |
if (message) return message; } while (0) | |
extern int tests_run; | |
/* END NO STUDENT COMMENTS */ | |
int get_number_of_messages(); | |
FILE *open_message_file(); | |
void close_message_file(FILE *fp); | |
int get_message_length (int msg_ndx); | |
char *read_message (int msg_ndx); | |
FILE *advance_to_msg (int msg_ndx); | |
#endif /* SQUARE_H */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include "square.h" | |
/* BEGIN NO STUDENT COMMENTS */ | |
int tests_run = 0; | |
/* END NO STUDENT COMMENTS */ | |
static char * test_get_number_of_messages() { | |
int msgs; | |
msgs = get_number_of_messages(); | |
mu_assert("There should be more than zero messages!", msgs > 0); | |
return 0; | |
} | |
static char * test_open_message_file() { | |
FILE *fp; | |
fp = open_message_file(); | |
mu_assert("The message file pointer should not be NULL!", fp != NULL); | |
if (fp != NULL) { | |
fclose(fp); | |
} | |
return 0; | |
} | |
static char * test_advance_to_message () { | |
FILE *fp; | |
char correct[] = {'G', 'T', 'I', 'D', 'T'}; | |
for (int i = 0 ; i < 5; i++) { | |
fp = advance_to_msg(i); | |
printf("\t... Checking ability to advance to message %d\n", i); | |
mu_assert("Found wrong message in first five.", getc(fp) == correct[i]); | |
close_message_file(fp); | |
} | |
return 0; | |
} | |
static char * test_get_message_length () { | |
int lengths[] = {40, 24, 39, 76, 52, 79, 66, 88, 51, 22, 39, 42, 71, 40, 49, 32, 31, 67, 106, 20}; | |
/* | |
for (int i = 0 ; i < get_number_of_messages() ; i++) { | |
int length; | |
length = get_message_length(i); | |
printf("%d, ", length); | |
} | |
*/ | |
for (int i = 0 ; i < get_number_of_messages() ; i++) { | |
int length; | |
length = get_message_length(i); | |
printf("\t... Checking length of message index %d (%d)\n", i, length); | |
mu_assert("Found wrong message length.", length == lengths[i]); | |
} | |
return 0; | |
} | |
static char * test_read_message () { | |
char * messages[] = {"Godhasmadeofonebloodallpeoplesoftheearth", \ | |
"Thereisdignityinalllabor", \ | |
"Imaginationismoreimportantthanknowledge", \ | |
"Donotdwellinthepastdonotdreamofthefutureconcentratethemindonthepresentmoment", \ | |
"Thebestplacetofindahelpinghandisattheendofyourownarm", \ | |
"IfyourstrengthissmalldontcarryheavyburdensIfyourwordsareworthlessdontgiveadvice", \ | |
"Ifyouarepatientinonemomentofangeryouwillescapeahundreddaysofsorrow", \ | |
"Ifyoumustplaydecideuponthreethingsatthestarttherulesofthegamethestakesandthequittingtime", \ | |
"Learningisatreasurethatwillfollowitsownereverywhere", \ | |
"Achangeisasgoodasarest", \ | |
"Aknownmistakeisbetterthananunknowntruth", \ | |
"Arroganceisaweedthatgrowsmostlyonadunghill", \ | |
"Acuttingwordisworsethanabowstringacutmayhealbutthecutofthetonguedoesnot", \ | |
"Afoollooksfordungwherethecowneverbrowsed", \ | |
"Ifyoudontstandforsomethingyouwillfallforsomething", \ | |
"Adversityisthefoundationofvirtue", \ | |
"Anexcessofcourtesyisdiscourtesy", \ | |
"Opinionsfoundedonprejudicearealwayssustainedwiththegreatestviolence", \ | |
"InacountrywellgovernedpovertyissomethingtobeashamedofInacountrybadlygovernedwealthissomethingtobeashamedof", \ | |
"Thecautiousseldomerr" \ | |
}; | |
for (int i = 0 ; i < get_number_of_messages() ; i++) { | |
int message_length = get_message_length(i); | |
char *msg = read_message(i); | |
printf("\t... Checking correctness of message %d\n", i); | |
for (int pos = 0 ; pos < message_length ; pos++) { | |
/* printf("POS[%d] msg[%c] messages[%c]\n", pos, msg[pos], messages[i][pos]); */ | |
mu_assert("Found wrong character in message.", msg[pos] = messages[i][pos]); | |
} | |
free(msg); | |
} | |
return 0; | |
} | |
static char * all_tests() { | |
mu_run_test(test_get_number_of_messages); | |
mu_run_test(test_open_message_file); | |
mu_run_test(test_advance_to_message); | |
mu_run_test(test_get_message_length); | |
mu_run_test(test_read_message); | |
return 0; | |
} | |
/* Standard main() for running all tests. */ | |
int main(int argc, char **argv) { | |
char *result = all_tests(); | |
if (result != 0) { | |
printf("%s\n", result); | |
} | |
else { | |
printf("ALL TESTS PASSED\n"); | |
} | |
printf("Tests run: %d\n", tests_run); | |
return result != 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment