C: run-length-encoding
This commit is contained in:
56
c/run-length-encoding/GNUmakefile
Normal file
56
c/run-length-encoding/GNUmakefile
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# The original 'makefile' has a flaw:
|
||||||
|
# 1) it overrides CFLAGS
|
||||||
|
# 2) it does not pass extra "FLAGS" to $(CC) that could come from environment
|
||||||
|
#
|
||||||
|
# It means :
|
||||||
|
# - we need to edit 'makefile' for different builds (DEBUG, etc...), which is
|
||||||
|
# not practical at all.
|
||||||
|
# - Also, it does not allow to run all tests without editing the test source
|
||||||
|
# code.
|
||||||
|
#
|
||||||
|
# To use this makefile (GNU make only):
|
||||||
|
# 1) copy it into exercise directory
|
||||||
|
# 2) add ex.h to exercise include file
|
||||||
|
# 3) add ex.c to exercise source code, and create a suitable main function
|
||||||
|
# 4) use make with one of the following targets :
|
||||||
|
# all: compile and run all predefined tests.
|
||||||
|
# nowarn: compile with no -Werror, and run all predefined tests
|
||||||
|
# debug: compile with -DDEBUG and run all predefined tests
|
||||||
|
# mem: perform memcheck with all tests enabled
|
||||||
|
# unit: build standalone (unit) bimary
|
||||||
|
# unitnowarn: build standalone (unit) binary with -Werror disabled
|
||||||
|
# unitdebug: build standalone binary with -DDEBUG
|
||||||
|
#
|
||||||
|
# Original 'makefile' targets can be used (test, memcheck, clean, ...)
|
||||||
|
|
||||||
|
.PHONY: default all nowarn debug mem unit unitnowarn unitdebug standalone
|
||||||
|
|
||||||
|
default: all
|
||||||
|
|
||||||
|
ALLSOURCES:=$(wildcard ./*.c)
|
||||||
|
TESTSOURCES:=$(wildcard ./test_*.c)
|
||||||
|
SRC:=$(filter-out $(TESTSOURCES),$(ALLSOURCES))
|
||||||
|
|
||||||
|
include makefile
|
||||||
|
|
||||||
|
all: CFLAGS+=-DTESTALL
|
||||||
|
all: clean test
|
||||||
|
|
||||||
|
nowarn: CFLAGS:=$(filter-out -Werror,$(CFLAGS))
|
||||||
|
nowarn: clean all
|
||||||
|
|
||||||
|
debug: CFLAGS+=-DDEBUG
|
||||||
|
debug: all
|
||||||
|
|
||||||
|
mem: CFLAGS+=-DTESTALL
|
||||||
|
mem: clean memcheck
|
||||||
|
|
||||||
|
unitnowarn: CFLAGS:=$(filter-out -Werror,$(CFLAGS))
|
||||||
|
unitnowarn: clean unit
|
||||||
|
|
||||||
|
unitdebug: CFLAGS+=-DDEBUG
|
||||||
|
unitdebug: clean unit
|
||||||
|
|
||||||
|
unit: CFLAGS+=-DUNIT_TEST
|
||||||
|
unit: *.c *.h
|
||||||
|
$(CC) $(CFLAGS) $(SRC) -o tests.out $(LIBS)
|
63
c/run-length-encoding/HELP.md
Normal file
63
c/run-length-encoding/HELP.md
Normal file
@@ -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]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
|
||||||
|
|
||||||
|
## Submitting your solution
|
||||||
|
|
||||||
|
You can submit your solution using the `exercism submit run_length_encoding.c run_length_encoding.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 support channel on gitter](https://gitter.im/exercism/support)
|
||||||
|
- 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 "Guides" section of the [C track][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.io/my/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/
|
47
c/run-length-encoding/README.md
Normal file
47
c/run-length-encoding/README.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Run Length Encoding
|
||||||
|
|
||||||
|
Welcome to Run Length Encoding on Exercism's C Track.
|
||||||
|
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
Implement run-length encoding and decoding.
|
||||||
|
|
||||||
|
Run-length encoding (RLE) is a simple form of data compression, where runs
|
||||||
|
(consecutive data elements) are replaced by just one data value and count.
|
||||||
|
|
||||||
|
For example we can represent the original 53 characters with only 13.
|
||||||
|
|
||||||
|
```text
|
||||||
|
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB"
|
||||||
|
```
|
||||||
|
|
||||||
|
RLE allows the original data to be perfectly reconstructed from
|
||||||
|
the compressed data, which makes it a lossless data compression.
|
||||||
|
|
||||||
|
```text
|
||||||
|
"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE"
|
||||||
|
```
|
||||||
|
|
||||||
|
For simplicity, you can assume that the unencoded string will only contain
|
||||||
|
the letters A through Z (either lower or upper case) and whitespace. This way
|
||||||
|
data to be encoded will never contain any numbers and numbers inside data to
|
||||||
|
be decoded always represent the count for the following character.
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
### Created by
|
||||||
|
|
||||||
|
- @vlzware
|
||||||
|
|
||||||
|
### Contributed to by
|
||||||
|
|
||||||
|
- @h-3-0
|
||||||
|
- @patricksjackson
|
||||||
|
- @QLaille
|
||||||
|
- @ryanplusplus
|
||||||
|
- @wolf99
|
||||||
|
|
||||||
|
### Based on
|
||||||
|
|
||||||
|
Wikipedia - https://en.wikipedia.org/wiki/Run-length_encoding
|
45
c/run-length-encoding/br-common.h
Normal file
45
c/run-length-encoding/br-common.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef __BR_COMMON_H
|
||||||
|
#define __BR_COMMON_H
|
||||||
|
|
||||||
|
/* ${LINUX_SRC}/include/linux/compiler_attributes.h, around line 30
|
||||||
|
*
|
||||||
|
* __has_attribute is supported on gcc >= 5, clang >= 2.9 and icc >= 17.
|
||||||
|
* For other compilers, simple implementation (for __falltrough__ only)
|
||||||
|
*/
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) __GCC4_has_attribute_##x
|
||||||
|
# define __GCC4_has_attribute___assume_aligned__ (__GNUC_MINOR__ >= 9)
|
||||||
|
# define __GCC4_has_attribute___copy__ 0
|
||||||
|
# define __GCC4_has_attribute___designated_init__ 0
|
||||||
|
# define __GCC4_has_attribute___externally_visible__ 1
|
||||||
|
# define __GCC4_has_attribute___no_caller_saved_registers__ 0
|
||||||
|
# define __GCC4_has_attribute___noclone__ 1
|
||||||
|
# define __GCC4_has_attribute___nonstring__ 0
|
||||||
|
# define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8)
|
||||||
|
# define __GCC4_has_attribute___no_sanitize_undefined__ (__GNUC_MINOR__ >= 9)
|
||||||
|
# define __GCC4_has_attribute___fallthrough__ 0
|
||||||
|
# define __GCC4_has_attribute___fallthrough__ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ${LINUX_SRC}/include/linux/compiler_attributes.h, around line 200
|
||||||
|
*/
|
||||||
|
#if __has_attribute(__fallthrough__)
|
||||||
|
# define fallthrough __attribute__((__fallthrough__))
|
||||||
|
#else
|
||||||
|
# define fallthrough do {} while (0); /* fallthrough */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* See GNUmakefile below for explanation
|
||||||
|
* https://github.com/braoult/exercism/blob/master/c/templates/GNUmakefile
|
||||||
|
*/
|
||||||
|
#if defined UNIT_TEST || defined DEBUG
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TESTALL
|
||||||
|
# undef TEST_IGNORE
|
||||||
|
# define TEST_IGNORE() {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __BR_COMMON_H */
|
26
c/run-length-encoding/main.c
Normal file
26
c/run-length-encoding/main.c
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#include "run_length_encoding.h"
|
||||||
|
/* See GNUmakefile below for explanation
|
||||||
|
* https://github.com/braoult/exercism/blob/master/c/templates/GNUmakefile
|
||||||
|
*/
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
int arg=1, what;
|
||||||
|
char *res;
|
||||||
|
|
||||||
|
what = *av[arg++]; /* 'e', 'd' */
|
||||||
|
for (; arg<ac; ++arg) {
|
||||||
|
switch (what) {
|
||||||
|
case 'e':
|
||||||
|
printf("enc[%s]=%d [%s]\n", av[arg], encode_len(av[arg]),
|
||||||
|
res=encode(av[arg]));
|
||||||
|
printf("dec[%s]=%d [%s]\n", res, decode_len(res), decode(res));
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
printf("dec[%s]=%d [%s]\n", av[arg], encode_len(av[arg]),
|
||||||
|
res=decode(av[arg]));
|
||||||
|
printf("enc[%s]=%d [%s]\n", res, decode_len(res), decode(res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
37
c/run-length-encoding/makefile
Normal file
37
c/run-length-encoding/makefile
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
### 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 += -Werror
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -DUNITY_SUPPORT_64
|
||||||
|
|
||||||
|
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) test-framework/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) test-framework/unity.c ./*.c -o tests.out $(LIBS)
|
101
c/run-length-encoding/run_length_encoding.c
Normal file
101
c/run-length-encoding/run_length_encoding.c
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#include "run_length_encoding.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* We have 2 choices for encoding : allocate a max length string (i.e. the
|
||||||
|
* size of input string), maybe shrinking with realloc() before returning or
|
||||||
|
* trying to calculate first the the exact output length.
|
||||||
|
*
|
||||||
|
* For decoding, if we want to avoid an arbitrary MAX_LENGTH, or, worse,
|
||||||
|
* a smaller string with multiple realloc() when we need more space, we
|
||||||
|
* also can first calculate the output string size.
|
||||||
|
*
|
||||||
|
* We will go for the second method (calculate exact length first for both
|
||||||
|
* encode() and decode().
|
||||||
|
*
|
||||||
|
* Additional checks: we allow only printable characters (isprint()), and
|
||||||
|
* disallow digits for encode() and ending digits for decode().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int encode_len(const char *str)
|
||||||
|
{
|
||||||
|
int len=0, c;
|
||||||
|
|
||||||
|
if (!str)
|
||||||
|
return -1;
|
||||||
|
for (c=*str; c; c=*str) {
|
||||||
|
int sublen=0, log=1;
|
||||||
|
if (isdigit(c) || !isprint(c))
|
||||||
|
return -1;
|
||||||
|
for (; *str == c; str++, sublen++)
|
||||||
|
;
|
||||||
|
if (sublen > 1)
|
||||||
|
do
|
||||||
|
log++;
|
||||||
|
while (sublen /= 10);
|
||||||
|
len += log;
|
||||||
|
}
|
||||||
|
return len+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *encode(const char *str)
|
||||||
|
{
|
||||||
|
char *res, *p;
|
||||||
|
int c, len;
|
||||||
|
|
||||||
|
if (!(str && (len = encode_len(str)) > 0 && (res = malloc(len))))
|
||||||
|
return NULL;
|
||||||
|
p=res;
|
||||||
|
|
||||||
|
for (c=*str; c; *p++ = c, c=*str) {
|
||||||
|
int sublen = 0;
|
||||||
|
for (; *str == c; str++, sublen++) /* count consecutive chars */
|
||||||
|
;
|
||||||
|
if (sublen > 1)
|
||||||
|
p += sprintf(p, "%d", sublen);
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decode_len(const char *str)
|
||||||
|
{
|
||||||
|
int len=0;
|
||||||
|
|
||||||
|
if (!str)
|
||||||
|
return -1;
|
||||||
|
for (int c = *str; c; c = *++str, len++) {
|
||||||
|
if (isdigit(c)) {
|
||||||
|
int sublen = strtold(str, (char **)&str);
|
||||||
|
if ((c = *str) == 0 || !isprint(c)) /* the char to duplicate */
|
||||||
|
return -1;
|
||||||
|
len += sublen - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *decode(const char *str)
|
||||||
|
{
|
||||||
|
char *res, *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!(str && (len = decode_len(str)) > 0 && (res = malloc(len))))
|
||||||
|
return NULL;
|
||||||
|
p=res;
|
||||||
|
|
||||||
|
for (int c = *str; c; *p++ = c, c = *++str) {
|
||||||
|
if (isdigit(c)) {
|
||||||
|
int sublen = strtold(str, (char **)&str);
|
||||||
|
c = *str; /* the char to duplicate */
|
||||||
|
while (--sublen) /* or (optimized) memset ? */
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
return res;
|
||||||
|
}
|
13
c/run-length-encoding/run_length_encoding.h
Normal file
13
c/run-length-encoding/run_length_encoding.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef RUN_LENGTH_ENCODING_H
|
||||||
|
#define RUN_LENGTH_ENCODING_H
|
||||||
|
|
||||||
|
|
||||||
|
int encode_len(const char *str);
|
||||||
|
char *encode(const char *text);
|
||||||
|
|
||||||
|
int decode_len(const char *str);
|
||||||
|
char *decode(const char *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "br-common.h"
|
156
c/run-length-encoding/test_run_length_encoding.c
Normal file
156
c/run-length-encoding/test_run_length_encoding.c
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
#include "test-framework/unity.h"
|
||||||
|
#include "run_length_encoding.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void setUp(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void tearDown(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_encode_empty_string(void)
|
||||||
|
{
|
||||||
|
char *res = encode("");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_encode_single_characters_only_are_encoded_without_count(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE(); // delete this line to run test
|
||||||
|
char *res = encode("XYZ");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("XYZ", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_encode_string_with_no_single_characters(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = encode("AABBBCCCC");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("2A3B4C", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_encode_single_characters_mixed_with_repeated_characters(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("12WB12W3B24WB", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_encode_multiple_whitespace_mixed_in_string(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = encode(" hsqq qww ");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("2 hs2q q2w2 ", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_encode_lowercase_characters(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = encode("aabbbcccc");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("2a3b4c", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_decode_empty_string(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = decode("");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_decode_single_characters_only(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = decode("XYZ");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("XYZ", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_decode_string_with_no_single_characters(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = decode("2A3B4C");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("AABBBCCCC", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_decode_single_characters_with_repeated_characters(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = decode("12WB12W3B24WB");
|
||||||
|
TEST_ASSERT_EQUAL_STRING
|
||||||
|
("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_decode_multiple_whitespace_mixed_in_string(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = decode("2 hs2q q2w2 ");
|
||||||
|
TEST_ASSERT_EQUAL_STRING(" hsqq qww ", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_decode_lower_case_string(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res = decode("2a3b4c");
|
||||||
|
TEST_ASSERT_EQUAL_STRING("aabbbcccc", res);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_consistency_encode_followed_by_decode_gives_original_string(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res_enc = encode("zzz ZZ zZ");
|
||||||
|
char *res_dec = decode(res_enc);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("zzz ZZ zZ", res_dec);
|
||||||
|
free(res_enc);
|
||||||
|
free(res_dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_encode_invalid_input_contains_digits(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res_enc = encode("AABB1A");
|
||||||
|
TEST_ASSERT_NULL(res_enc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_decode_invalid_input_ends_with_digits(void)
|
||||||
|
{
|
||||||
|
TEST_IGNORE();
|
||||||
|
char *res_dec = decode("AABBA2");
|
||||||
|
TEST_ASSERT_NULL(res_dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
UnityBegin("test_run_length_encoding.c");
|
||||||
|
|
||||||
|
RUN_TEST(test_encode_empty_string);
|
||||||
|
RUN_TEST(test_encode_single_characters_only_are_encoded_without_count);
|
||||||
|
RUN_TEST(test_encode_string_with_no_single_characters);
|
||||||
|
RUN_TEST(test_encode_single_characters_mixed_with_repeated_characters);
|
||||||
|
RUN_TEST(test_encode_multiple_whitespace_mixed_in_string);
|
||||||
|
RUN_TEST(test_encode_lowercase_characters);
|
||||||
|
RUN_TEST(test_decode_empty_string);
|
||||||
|
RUN_TEST(test_decode_single_characters_only);
|
||||||
|
RUN_TEST(test_decode_string_with_no_single_characters);
|
||||||
|
RUN_TEST(test_decode_single_characters_with_repeated_characters);
|
||||||
|
RUN_TEST(test_decode_multiple_whitespace_mixed_in_string);
|
||||||
|
RUN_TEST(test_decode_lower_case_string);
|
||||||
|
RUN_TEST(test_consistency_encode_followed_by_decode_gives_original_string);
|
||||||
|
RUN_TEST(test_encode_invalid_input_contains_digits);
|
||||||
|
RUN_TEST(test_decode_invalid_input_ends_with_digits);
|
||||||
|
|
||||||
|
return UnityEnd();
|
||||||
|
}
|
Reference in New Issue
Block a user