Skip to content

Instantly share code, notes, and snippets.

@jcreigh
Created May 29, 2020 01:47
Show Gist options
  • Save jcreigh/3b4702c1605825959f7eb12a6321b289 to your computer and use it in GitHub Desktop.
Save jcreigh/3b4702c1605825959f7eb12a6321b289 to your computer and use it in GitHub Desktop.
/*
* lab0_tests.c - Tests for lab 0 programming puzzles
*
* Created on: Apr 19, 2018
* Author: deemer
* Updated 17 May 2018
*/
#include <msp430.h>
#include <puzzle_tests.h>
#include <puzzles.h>
#include <string.h>
// Prototypes
void test_linear(void);
void test_gt20(void);
void test_setBit(void);
void test_clearBit(void);
void test_bitCount(void);
void test_divpwr2(void);
void test_negate(void);
void test_isPositive(void);
void test_swapBytes(void);
void test_myMax(void);
void test_clamp(void);
void test_isLetter(void);
void test_average(void);
void test_over21(void);
void test_strLength(void);
void test_letterShift(void);
void test_caesar(void);
void test_i2f(void);
void test_bang(void);
void test_float_neg(void);
void test_ilog2(void);
unsigned long fake_f2i(float f);
float fake_i2f(unsigned long i);
void test_getByte(void);
/*
* ***** Run all tests ******
* To implement each puzzle, write your implementation
* in the corresponding function in puzzles.c.
*
* As you start each puzzle,
* BE SURE TO UNCOMMENT the corresponding
* tests here to check your work!
*/
void test_all_puzzles(void)
{
test_linear();
// test_gt20();
//
// test_myMax();
// test_clamp();
// test_isLetter();
// test_letterShift();
// test_setBit();
// test_clearBit();
// test_bitCount();
// test_divpwr2();
// test_getByte();
// test_swapBytes();
//
// test_isPositive();
// test_negate();
//
// test_average();
// test_over21();
// test_strLength();
// test_caesar();
//
// test_bang();
// test_float_neg();
// test_i2f();
// test_ilog2();
}
/* ************* TESTS *************** */
void test_linear(void)
{
TEST_ASSERT2(linear(0), 4);
TEST_ASSERT2(linear(1), 6);
TEST_ASSERT2(linear(-10), -16);
TEST_ASSERT2(linear(20), 44);
}
void test_gt20(void)
{
TEST_ASSERT2(gt20(0, 1), 0);
TEST_ASSERT2(gt20(20, 21), 0);
TEST_ASSERT2(gt20(42, 145), 1);
}
void test_setBit(void)
{
TEST_ASSERT2(setBit(0, 0), 0x01);
TEST_ASSERT2(setBit(0x4444, 15), 0xC444);
TEST_ASSERT2(setBit(0xFFFF, 2), 0xFFFF);
TEST_ASSERT2(setBit(0x52, 2), 0x56);
}
void test_clearBit(void)
{
TEST_ASSERT2(clearBit(0, 0), 0);
TEST_ASSERT2(clearBit(0xFFFF, 0), 0xFFFE);
TEST_ASSERT2(clearBit(0x2255, 4), 0x2245);
TEST_ASSERT2(clearBit(0x5555, 7), 0x5555);
}
void test_bitCount(void)
{
TEST_ASSERT2(bitCount(0), 0);
TEST_ASSERT2(bitCount(1), 1);
TEST_ASSERT2(bitCount(0xff), 8);
TEST_ASSERT2(bitCount(0xA5), 4);
}
void test_divpwr2(void)
{
TEST_ASSERT2(divpwr2(0, 4), 0);
TEST_ASSERT2(divpwr2(16, 2), 4);
TEST_ASSERT2(divpwr2(-1024, 10), -1);
}
void test_negate(void)
{
TEST_ASSERT2(negate(0), 0);
TEST_ASSERT2(negate(1), -1);
TEST_ASSERT2(negate(-1), 1);
TEST_ASSERT2(negate(-31224), 31224);
}
void test_isPositive(void)
{
TEST_ASSERT(isPositive(0));
TEST_ASSERT(isPositive(1));
TEST_ASSERT(isPositive(32111));
TEST_ASSERT(!isPositive(-1));
TEST_ASSERT(!isPositive(-32111));
}
void test_getByte(void)
{
TEST_ASSERT2(getByte(0xAABBCCDD, 0), 0xDD);
TEST_ASSERT2(getByte(0xAABBCCDD, 1), 0xCC);
TEST_ASSERT2(getByte(0xAABBCCDD, 2), 0xBB);
TEST_ASSERT2(getByte(0xAABBCCDD, 3), 0xAA);
}
void test_swapBytes(void)
{
TEST_ASSERT2(swapBytes(0xDEADBEEF), 0xEFBEADDE);
TEST_ASSERT2(swapBytes(0xAABBCCDD), 0xDDCCBBAA);
}
void test_myMax(void)
{
TEST_ASSERT2(myMax(0, 1), 1);
TEST_ASSERT2(myMax(5, 5), 5);
TEST_ASSERT2(myMax(-1, 1), 1);
TEST_ASSERT2(myMax(-10, -1), -1);
}
void test_clamp(void)
{
TEST_ASSERT2(clamp(5, 0, 10), 5);
TEST_ASSERT2(clamp(-10, 0, 10), 0);
TEST_ASSERT2(clamp(150, 0, 100), 100);
TEST_ASSERT2(clamp(12, -10, 10), 10);
}
void test_isLetter(void)
{
TEST_ASSERT(isLetter('A'));
TEST_ASSERT(isLetter('g'));
TEST_ASSERT(isLetter('z'));
TEST_ASSERT(isLetter('Z'));
TEST_ASSERT(!isLetter('0'));
TEST_ASSERT(!isLetter(';'));
TEST_ASSERT(!isLetter(0x00));
}
void test_average(void)
{
char v1[2] = {0, 10};
TEST_ASSERT2(average(v1, 2), 5);
char v2[6] = {100, 90, 90, 76, 85, 90};
TEST_ASSERT2(average(v2, 6), 88);
}
void test_over21(void)
{
char v1[4] = {5, 10, 20, 19};
TEST_ASSERT2(over21(v1, 4), 0);
char v2[4] = {5, 10, 20, 24};
TEST_ASSERT2(over21(v2, 4), 0);
char v3[6] = {25, 40, 30, 21, 32, 54};
TEST_ASSERT2(over21(v3, 6), 1);
}
void test_strLength(void)
{
TEST_ASSERT2(strLength(""), 0);
TEST_ASSERT2(strLength("a"), 1);
TEST_ASSERT2(strLength("abcd"), 4);
TEST_ASSERT2(strLength("Hello world!"), 12);
}
void test_letterShift(void)
{
TEST_ASSERT2(letterShift('A', 0), 'A');
TEST_ASSERT2(letterShift('D', 3), 'G');
TEST_ASSERT2(letterShift('W', 7), 'D');
TEST_ASSERT2(letterShift('A', 26), 'A');
}
#define STR_MAX 30 // None of the test strings are longer than 30
// bytes. Important to compare up to a maximum
// value in case the function being tested does
// not null-terminate its output
void test_caesar(void)
{
char s1[5] = "ABCD"; // 4 chars + 1 for null terminator
caesar(s1);
TEST_ASSERT(!strncmp(s1, "DEFG", STR_MAX));
char s2[5] = "WXYZ";
caesar(s2);
TEST_ASSERT(!strncmp(s2, "ZABC", STR_MAX));
char s3[6] = "APPLE";
caesar(s3);
TEST_ASSERT(!strncmp(s3, "DSSOH", STR_MAX));
// This is another way to declare a string, which has
// exactly the same result as above
char s4[3] = {'L', 'V', '\0'};
caesar(s4);
TEST_ASSERT(!strncmp(s4, "OY", STR_MAX));
}
void test_ilog2(void)
{
TEST_ASSERT2(ilog2(1), 0);
TEST_ASSERT2(ilog2(4), 2);
TEST_ASSERT2(ilog2(5), 2);
TEST_ASSERT2(ilog2(16), 4);
TEST_ASSERT2(ilog2(25), 4);
TEST_ASSERT2(ilog2(1025), 10);
TEST_ASSERT2(ilog2(32000), 14);
}
void test_bang(void)
{
TEST_ASSERT2(bang(1), 0);
TEST_ASSERT2(bang(0xffff), 0);
TEST_ASSERT2(bang(0xBEEF), 0);
TEST_ASSERT(bang(0));
}
void test_float_neg(void)
{
TEST_ASSERT2(floatNeg(fake_f2i(3.0)),
fake_f2i(-3.0));
TEST_ASSERT2(floatNeg(fake_f2i(-1142.5124)),
fake_f2i(1142.5124));
TEST_ASSERT2(floatNeg(fake_f2i(1e-5)),
fake_f2i(-1e-5));
}
void test_i2f(void)
{
TEST_ASSERT2(i2f(42), fake_f2i(42.0f));
TEST_ASSERT2(i2f(-42), fake_f2i(-42.0f));
TEST_ASSERT2(i2f(11345), fake_f2i(11345));
TEST_ASSERT2(i2f(-32768), fake_f2i(-32768));
TEST_ASSERT2(i2f(0), fake_f2i(0));
}
/*
* Return a 32-bit value containing
* the floating point representation of f.
*
* The purpose of this function is to allow us
* to manipulate raw floating point values for demonstration
* purposes--this is not a good idea in practice!
*/
unsigned long fake_f2i(float f)
{
unsigned long i = * ((unsigned long *) &f);
return i;
}
/*
* Return a float given by the single-precision
* representation in i.
*
* The purpose of this function is to allow us to
* manipulate raw floating point values for demonstration
* purposes--this is not a good idea in practice!
*/
float fake_i2f(unsigned long i)
{
float f = *((float *) &i);
return f;
}
/*
* lab0.c - Programming puzzles for lab 0
*
* Created on: Apr 10, 2018
* Author: deemer
*/
#include <puzzles.h>
/*
* ****** PUZZLES ********
* This is where you implement your solutions for the puzzles
*
* Each function provides a comment describing how the function
* should be implemented, as well as the C operations you are permitted
* to use.
*
* Currently, each function is a "stub": it does nothing, but contains
* a meaningless dummy statement (like "return 0") that just
* allows it to compile. You should replace the body of the function
* with your own implementation.
*
* If you want to know more about how the function should operate,
* take a look at its tests in puzzle_tests.c. These tests provide
* some sample inputs and outputs for each function.
*
* ***NOTE***: YOU MAY NOT BE REQUIRED TO COMPLETE ALL OF THE
* PUZZLES LISTED HERE. SEE YOUR LAB DOCUMENT FOR DETAILS ON WHICH PUZZLES
* ARE REQUIRED AND WHICH MAY BE EXTRA CREDIT.
*
*/
// ********* WARMUP *********
// linear: Given x, output a value corresponding
// to the linear equation 2*x + 4
//
// ALLOWED OPERATORS: All bitwise and logical operators, if/else statements
// PROHIBITED: loops (for, while), calling functions, or floating point math
int linear(int x)
{
return 2*x + 4;
}
// gt20: Return 1 if both a and b are greater than 20,
// and 0 otherwise
// ALLOWED OPERATORS: All bitwise and logical operators, if/else statements
// PROHIBITED: loops (for, while), calling functions, or floating point math
int gt20(int a, int b)
{
return 0;
}
// ******** LOGICAL OPERATORS **********
// myMax: Given two integers a and b,
// return the larger integer
// ALLOWED OPERATORS: All bitwise and logical operators, if/else statements
// PROHIBITED: loops (for, while), calling functions, or floating point math
int myMax(int a, int b)
{
return 0;
}
// clamp: "Clamp" input x within upper and lower bounds
// lower and upper: if x < lower, return lower, if x > upper
// return upper, otherwise return x.
// ALLOWED OPERATORS: All bitwise and logical operators, if/else statements
// PROHIBITED: loops (for, while), calling functions, or floating point math
int clamp(int x, int lower, int upper)
{
return 0;
}
// Return true if x corresponds to a letter
// in the ASCII table (that is A-Z or a-z)
// To do this, you may NOT write an if statement
// for each character.
// HINT: Look at an ASCII table
//
// ALLOWED OPERATORS: All bitwise and logical operators, if/else statements
// PROHIBITED: loops (for, while), calling functions, or floating point math
int isLetter(char x)
{
return 0;
}
/*
* "Shift" character c in the alphabet by
* the number of places given by variable shift.
* For example, 'A' shifted by 3 -> 'D'
*
* If shifting the letter would go past 'Z', the shifted result
* should wrap around, eg. 'X' shifted by 4 -> 'B'
* See the tests for more examples.
*
* You may NOT solve this problem by writing one
* if statement per letter. Hint: see ASCII table.
*
* You may assume that the input is a CAPITAL ASCII letter.
*
*
* ALLOWED OPERATORS: All bitwise and logical operators, if/else statements
* PROHIBITED: loops (for, while), calling functions, or floating point math
*/
char letterShift(char c, int shift)
{
return 0;
}
// ******** BITWISE MANIPULATION **********
// testBit: Return a value with bit b of x to 1,
// leaving all other bits unchanged
// You may assume b is in the range 0-15.
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
int setBit(int x, int b)
{
return 0;
}
// testBit: Return a value with bit b of x to 0,
// leaving all other bits unchanged
// You may assume b is in the range 0-15.
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
int clearBit(int x, int b)
{
return 0;
}
// Compute x/(2^n) (that is, x divided by the quantity (two to the power n))
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
int divpwr2(int x, int n)
{
return 0;
}
// Count number of 1's in x
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
int bitCount(char x)
{
return 0;
}
// ******** BYTE MANIPULATION **********
// Get *BYTE* n from x
// Assume n is a value from 0-3,
// and byte 0 is the LEAST significant byte
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
char getByte(long x, int n)
{
return 0;
}
// Swap all bytes in x such that the
// most significant byte becomes the least significant
// byte, and the least significant byte becomes
// the most significant byte, and so on
// See the tests for examples.
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
unsigned long swapBytes(unsigned long x)
{
return 0;
}
// ******** TWO'S COMPLEMENT **********
// Compute -x without the - operator
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
int negate(int x)
{
return 0;
}
// Return true if x >= 0,
// but without using any logical operators
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
int isPositive(int x)
{
return 0;
}
// Compute !x without using the ! operator
// You are limited to straight-line code (similar to bitSet/bitTest),
// no loops or conditionals
//
// ALLOWED OPERATORS: ! ~ | & ^ + << >> = and casting
// PROHIBITED: if, for, while, switch, any logical operators like < && ==,
// calling functions, or floating point math
int bang(int x)
{
return 0;
}
// ********* LOOPS AND ARRAYS *********
// Compute the average of the array of values
// "vals", with the size indicated by "num_vals".
//
// ALLOWED OPERATORS: All operators and loops
// PROHIBITED: No library functions
char average(char *vals, char num_vals)
{
return 0;
}
// Given array of values "vals" with size indicated by "num_vals",
// return 1 if all values are >= 21, 0 otherwise
//
// ALLOWED OPERATORS: All operators and loops
// PROHIBITED: No library functions
int over21(char *vals, char num_vals)
{
return 0;
}
/*
* Compute the length of the null-terminated
* string s. The length returned should NOT
* count the null-terminator.
*
* You may assume that all strings tested have
* length less than 255.
*
* ALLOWED OPERATORS: All operators and loops
* PROHIBITED: No library functions (but you can use your own)
*
*/
#define STR_MAX 255 // Feel free to use this definition
int strLength(char *s)
{
return 0;
}
/*
* Implement the "Caesar cipher", which is an ancient
* example of cryptography.
* To encode a message, shift all characters in the null-terminated
* string s by 3 letters. For example "APPLE" becomes "DSSOH"
* To do this, use your letterShift function.
*
* You may assume that the input is a null-terminated, ASCII
* string containing only CAPITAL letters.
*
* ALLOWED OPERATORS: All operators and loops
* PROHIBITED: No library functions (but you can use your own)
*
*/
void caesar(char *s)
{
}
// ********* FLOATING POINT AND MORE *********
// Compute the integer form of the base-2 log of x
// This is equivalent to floor(log2(x))
// See the tests for some examples
// You may use loops and conditionals for this puzzle.
//
// ALLOWED OPERATORS: All operators and loops
// PROHIBITED: No library functions
unsigned int ilog2(unsigned long x)
{
return 0;
}
// Compute -f
// Assume that f is a number in single-precision IEEE754 format
//
// C does not permit bitwise operators on floats,
// so the input and return type of this function is
// unsigned long to allow you to alter its format
//
// You may use conditionals for this puzzle.
//
// ALLOWED OPERATORS: All operators and loops
// PROHIBITED: No library functions (but you can use your own)
unsigned long floatNeg(unsigned long f)
{
return 0;
}
// Return the single-precision IEEE754 representation of integer x
// You may use conditionals, loops, and your ilog2 function
//
// As above, the return type for this function is unsigned long
// to allow you to manipulate its format
//
// ALLOWED OPERATORS: All operators and loops
// PROHIBITED: No library functions (but you can use your own, such as ilog2)
unsigned long i2f(int x)
{
return 0;
}
/*
* lab0.h
*
* Created on: Apr 10, 2018
* Author: deemer
*/
#ifndef PUZZLES_H_
#define PUZZLES_H_
// Warmup
int linear(int x);
int gt20(int a, int b);
// Bit-twiddling
int setBit(int x, int b);
int clearBit(int x, int b);
int divpwr2(int x, int n);
int bitCount(char x);
// Byte manipulation
char getByte(long x, int n);
unsigned long swapBytes(unsigned long x);
// Two's complement
int negate(int x);
int isPositive(int x);
// ASCII and Logical operators
int myMax(int a, int b);
int clamp(int x, int lower, int upper);
int isLetter(char x);
char letterShift(char c, int shift);
// Loops, Characters and Arrays
char average(char *vals, char num_vals);
int over21(char *vals, char num_vals);
int strLength(char *s);
void caesar(char *s);
// Extra puzzles
int bang(int x);
unsigned int ilog2(unsigned long x);
unsigned long floatNeg(unsigned long f);
unsigned long i2f(int x);
#endif /* PUZZLES_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment