diff --git a/exercises/hamming/.exercism/config.json b/exercises/hamming/.exercism/config.json new file mode 100644 index 0000000000000000000000000000000000000000..2c002775a9cccc2bf5e36b7607fa5a412d2a5b0b --- /dev/null +++ b/exercises/hamming/.exercism/config.json @@ -0,0 +1,38 @@ +{ + "authors": [ + "sunzenshen" + ], + "contributors": [ + "bcc32", + "Gamecock", + "gea-migration", + "h-3-0", + "hintjens", + "JacobMikkelsen", + "kytrinyx", + "lpil", + "patricksjackson", + "QLaille", + "RealBarrettBrown", + "ryanplusplus", + "siebenschlaefer", + "sjwarner", + "wolf99" + ], + "files": { + "solution": [ + "hamming.c", + "hamming.h" + ], + "test": [ + "test_hamming.c" + ], + "example": [ + ".meta/example.c", + ".meta/example.h" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "http://rosalind.info/problems/hamm/" +} diff --git a/exercises/hamming/.exercism/metadata.json b/exercises/hamming/.exercism/metadata.json new file mode 100644 index 0000000000000000000000000000000000000000..d1c2bd0e4d9ac79d7177b25ae7acb0184549d9e4 --- /dev/null +++ b/exercises/hamming/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"c","exercise":"hamming","id":"355be382464849cea1bb20968f94c910","url":"https://exercism.org/tracks/c/exercises/hamming","handle":"mactavishz","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/exercises/hamming/HELP.md b/exercises/hamming/HELP.md new file mode 100644 index 0000000000000000000000000000000000000000..3686d1b2ea80d8b92b58cb07efe69e7aacbd06d8 --- /dev/null +++ b/exercises/hamming/HELP.md @@ -0,0 +1,63 @@ +# Help + +## Running the tests + +Get the first test compiling, linking and passing by following the [three rules of test-driven development][3-tdd-rules]. + +The included makefile can be used to create and run the tests using the `test` task. + +```console +$ make test +``` + +Create just the functions you need to satisfy any compiler errors and get the test to fail. +Then write just enough code to get the test to pass. +Once you've done that, move onto the next test. + +As you progress through the tests, take the time to refactor your implementation for readability and expressiveness and then go on to the next test. + +Try to use standard C99 facilities in preference to writing your own low-level algorithms or facilities by hand. + +[3-tdd-rules]: https://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html + +## Submitting your solution + +You can submit your solution using the `exercism submit hamming.c hamming.h` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [C track's documentation](https://exercism.org/docs/tracks/c) +- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +Make sure you have read the [C track-specific documentation][c-track] on the Exercism site. +This covers the basic information on setting up the development environment expected by the exercises. + +## Submitting Incomplete Solutions + +If you are struggling with a particular exercise, it is possible to submit an incomplete solution so you can see how others have completed the exercise. + +## Resources + +To get help if having trouble, you can use the following resources: + +- [StackOverflow][] can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. +- [CPPReference][] can be used to look up information on C concepts, operators, types, standard library functions and more. +- [TutorialsPoint][] has similar content as CPPReference in its C programming section. +- [The C Programming][K&R] book by K&R is the original source of the language and is still useful today. + +[c-track]: https://exercism.org/docs/tracks/c +[stackoverflow]: http://stackoverflow.com/questions/tagged/c +[cppreference]: https://en.cppreference.com/w/c +[tutorialspoint]: https://www.tutorialspoint.com/cprogramming/ +[K&R]: https://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628/ \ No newline at end of file diff --git a/exercises/hamming/README.md b/exercises/hamming/README.md new file mode 100644 index 0000000000000000000000000000000000000000..560b2abed4602c9fd15894ada751a362708445b6 --- /dev/null +++ b/exercises/hamming/README.md @@ -0,0 +1,48 @@ +# Hamming + +Here is a small exercise that helps you understand pointer arithmetic and String in C. + +## Instructions + +Calculate the Hamming Distance between two DNA sequences. + +If we compare two sequences of DNA and count the differences between them we can see how many mismatches occurred. + +This is known as the "Hamming Distance". + +We read DNA using the letters C,A,G and T. Two sequences might look like this: + +``` +GAGCCTACTAACGGGAT +CATCGTAATGACGGCCT +^ ^ ^ ^ ^ ^^ +``` + +They have 7 differences, and therefore the Hamming Distance is 7. + +## Implementation notes + +The Hamming distance is only defined for sequences of equal length, so an attempt to calculate it between sequences of different lengths should not work. + +## Tips + +You could use auxiliary functions such as `strlen` to get the length of a given string. These functions are defined in `<string.h>` + +## Testing + +The included makefile can be used to create and run the tests using the following commands: + +```bash +# run unit tests +make test + +# check memory leaks +make memcheck + +# clean all compilation files +make clean +``` + +## Credit + +Adapted from [here](https://github.com/exercism/c/tree/main/exercises/practice/hamming) diff --git a/exercises/hamming/hamming.c b/exercises/hamming/hamming.c new file mode 100644 index 0000000000000000000000000000000000000000..33417d7b034f4098e81603f624d233294c4dd948 --- /dev/null +++ b/exercises/hamming/hamming.c @@ -0,0 +1,5 @@ +#include "hamming.h" + +int compute(const char *lhs, const char *rhs) { + // TODO: implement this fucntion +} diff --git a/exercises/hamming/hamming.h b/exercises/hamming/hamming.h new file mode 100644 index 0000000000000000000000000000000000000000..aa122977350a0034cfbfc176a0885385d0e35388 --- /dev/null +++ b/exercises/hamming/hamming.h @@ -0,0 +1,6 @@ +#ifndef HAMMING_H +#define HAMMING_H + +int compute(const char *lhs, const char *rhs); + +#endif diff --git a/exercises/hamming/makefile b/exercises/hamming/makefile new file mode 100644 index 0000000000000000000000000000000000000000..3fc3afdb8553173df0dbc52eb3df40ed0cbd6b85 --- /dev/null +++ b/exercises/hamming/makefile @@ -0,0 +1,36 @@ +### If you wish to use extra libraries (math.h for instance), +### add their flags here (-lm in our case) in the "LIBS" variable. + +LIBS = -lm + +### +CFLAGS = -std=c99 +CFLAGS += -g +CFLAGS += -Wall +CFLAGS += -Wextra +CFLAGS += -pedantic +CFLAGS += -Wmissing-declarations +CFLAGS += -DUNITY_SUPPORT_64 -DUNITY_OUTPUT_COLOR + +ASANFLAGS = -fsanitize=address +ASANFLAGS += -fno-common +ASANFLAGS += -fno-omit-frame-pointer + +.PHONY: test +test: tests.out + @./tests.out + +.PHONY: memcheck +memcheck: ./*.c ./*.h + @echo Compiling $@ + @$(CC) $(ASANFLAGS) $(CFLAGS) ../unity/unity.c ./*.c -o memcheck.out $(LIBS) + @./memcheck.out + @echo "Memory check passed" + +.PHONY: clean +clean: + rm -rf *.o *.out *.out.dSYM + +tests.out: ./*.c ./*.h + @echo Compiling $@ + @$(CC) $(CFLAGS) ../unity/unity.c ./*.c -o tests.out $(LIBS) diff --git a/exercises/hamming/test_hamming.c b/exercises/hamming/test_hamming.c new file mode 100644 index 0000000000000000000000000000000000000000..f5f7fa9c713708355f9df3de017d3317bedb0f7d --- /dev/null +++ b/exercises/hamming/test_hamming.c @@ -0,0 +1,56 @@ +#include "../unity/unity.h" +#include "hamming.h" + +void setUp(void) {} + +void tearDown(void) {} + +static void test_empty_strands(void) { TEST_ASSERT_EQUAL(0, compute("", "")); } + +static void test_single_identical_strands(void) { + TEST_ASSERT_EQUAL(0, compute("A", "A")); +} + +static void test_single_letter_different_strands(void) { + TEST_ASSERT_EQUAL(1, compute("G", "T")); +} + +static void test_long_identical_strands(void) { + TEST_ASSERT_EQUAL(0, compute("GGACTGAAATCTG", "GGACTGAAATCTG")); +} + +static void test_long_different_strands(void) { + TEST_ASSERT_EQUAL(9, compute("GGACGGATTCTG", "AGGACGGATTCT")); +} + +static void test_disallow_first_strand_when_longer(void) { + TEST_ASSERT_EQUAL(-1, compute("AATG", "AAA")); +} + +static void test_disallow_second_strand_when_longer(void) { + TEST_ASSERT_EQUAL(-1, compute("ATA", "AGTG")); +} + +static void test_disallow_empty_first_strand(void) { + TEST_ASSERT_EQUAL(-1, compute("", "G")); +} + +static void test_disallow_empty_second_strand(void) { + TEST_ASSERT_EQUAL(-1, compute("G", "")); +} + +int main(void) { + UnityBegin("test_hamming.c"); + + RUN_TEST(test_empty_strands); + RUN_TEST(test_single_identical_strands); + RUN_TEST(test_single_letter_different_strands); + RUN_TEST(test_long_identical_strands); + RUN_TEST(test_long_different_strands); + RUN_TEST(test_disallow_first_strand_when_longer); + RUN_TEST(test_disallow_second_strand_when_longer); + RUN_TEST(test_disallow_empty_first_strand); + RUN_TEST(test_disallow_empty_second_strand); + + return UnityEnd(); +}