-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
232 additions
and
71 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,59 @@ | ||
#include "high_scores.h" | ||
|
||
int32_t latest(const int32_t *scores, size_t scores_len) { | ||
if (scores_len == 0) { | ||
return 0; | ||
} | ||
|
||
return scores[scores_len - 1]; | ||
} | ||
|
||
int32_t personal_best(const int32_t *scores, size_t scores_len) { | ||
if (scores_len == 0) { | ||
return 0; | ||
} | ||
|
||
int32_t best = scores[0]; | ||
for (size_t i = 1; i < scores_len; i++) { | ||
if (best < scores[i]) { | ||
best = scores[i]; | ||
} | ||
} | ||
|
||
return best; | ||
} | ||
|
||
size_t personal_top_three(const int32_t *scores, size_t scores_len, | ||
int32_t *output) { | ||
if (scores_len == 0) { | ||
return 0; | ||
} | ||
|
||
int32_t sorted[scores_len]; | ||
size_t sorted_len = 0; | ||
|
||
memcpy(sorted, scores, sizeof(int) * scores_len); | ||
|
||
qsort(sorted, scores_len, sizeof(scores[0]), comparator); | ||
|
||
if (scores_len >= 3) { | ||
output[2] = sorted[scores_len - 3]; | ||
sorted_len++; | ||
} | ||
|
||
if (scores_len >= 2) { | ||
output[1] = sorted[scores_len - 2]; | ||
sorted_len++; | ||
} | ||
|
||
if (scores_len >= 1) { | ||
output[0] = sorted[scores_len - 1]; | ||
sorted_len++; | ||
} | ||
|
||
return sorted_len; | ||
} | ||
|
||
int32_t comparator(const void *value1, const void *value2) { | ||
return (*(int32_t *)value1 - *(int32_t *)value2); | ||
} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
Running automated test file(s): | ||
|
||
|
||
=============================================================================== | ||
|
||
Running: make clean | ||
rm -rf *.o *.out *.out.dSYM | ||
|
||
real 0m0.007s | ||
user 0m0.001s | ||
sys 0m0.006s | ||
|
||
=============================================================================== | ||
|
||
Running: make test | ansifilter | ||
Compiling tests.out | ||
test_high_scores.c:81:test_latest_score:PASS | ||
test_high_scores.c:82:test_personal_best:PASS | ||
test_high_scores.c:83:test_personal_top_three_from_a_list_of_scores:PASS | ||
test_high_scores.c:84:test_personal_top_highest_to_lowest:PASS | ||
test_high_scores.c:85:test_personal_top_when_there_is_a_tie:PASS | ||
test_high_scores.c:86:test_personal_top_when_there_are_less_than_3:PASS | ||
test_high_scores.c:87:test_personal_top_when_there_is_only_one:PASS | ||
|
||
----------------------- | ||
7 Tests 0 Failures 0 Ignored | ||
OK | ||
|
||
real 0m0.132s | ||
user 0m0.088s | ||
sys 0m0.041s | ||
|
||
=============================================================================== | ||
|
||
Running: make memcheck | ansifilter | ||
Compiling memcheck | ||
test_high_scores.c:81:test_latest_score:PASS | ||
test_high_scores.c:82:test_personal_best:PASS | ||
test_high_scores.c:83:test_personal_top_three_from_a_list_of_scores:PASS | ||
test_high_scores.c:84:test_personal_top_highest_to_lowest:PASS | ||
test_high_scores.c:85:test_personal_top_when_there_is_a_tie:PASS | ||
test_high_scores.c:86:test_personal_top_when_there_are_less_than_3:PASS | ||
test_high_scores.c:87:test_personal_top_when_there_is_only_one:PASS | ||
|
||
----------------------- | ||
7 Tests 0 Failures 0 Ignored | ||
OK | ||
Memory check passed | ||
|
||
real 0m0.135s | ||
user 0m0.098s | ||
sys 0m0.037s | ||
|
||
=============================================================================== | ||
|
||
Running: clang-check-16 ./high_scores.c ./test_high_scores.c ./high_scores.h -- | ||
|
||
real 0m0.043s | ||
user 0m0.027s | ||
sys 0m0.016s | ||
|
||
=============================================================================== | ||
|
||
Running: clang-tidy-16 ./high_scores.c ./test_high_scores.c ./high_scores.h -checks=*,-llvm-header-guard,-llvmlibc-restrict-system-libc-headers -- | head -n 100 | ||
2579 warnings generated. | ||
6383 warnings generated. | ||
8958 warnings generated. | ||
Suppressed 8953 warnings (8953 in non-user code). | ||
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. | ||
/home/vpayno/git_vpayno/exercism-workspace/c/high-scores/high_scores.c:17:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops] | ||
for (size_t i = 1; i < scores_len; i++) { | ||
^ | ||
/home/vpayno/git_vpayno/exercism-workspace/c/high-scores/high_scores.c:35:5: warning: Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] | ||
memcpy(sorted, scores, sizeof(int) * scores_len); | ||
^~~~~~ | ||
/home/vpayno/git_vpayno/exercism-workspace/c/high-scores/high_scores.c:35:5: note: Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 | ||
memcpy(sorted, scores, sizeof(int) * scores_len); | ||
^~~~~~ | ||
/home/vpayno/git_vpayno/exercism-workspace/c/high-scores/test_high_scores.c:5:47: warning: macro argument should be enclosed in parentheses [bugprone-macro-parentheses] | ||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | ||
^ | ||
( ) | ||
/home/vpayno/git_vpayno/exercism-workspace/c/high-scores/test_high_scores.c:7:1: warning: replace macro with enum [modernize-macro-to-enum] | ||
#define TOP_SCORES_ARRAY_SIZE (3) | ||
^~~~~~~~ | ||
= | ||
/home/vpayno/git_vpayno/exercism-workspace/c/high-scores/test_high_scores.c:7:9: warning: macro 'TOP_SCORES_ARRAY_SIZE' defines an integral constant; prefer an enum instead [modernize-macro-to-enum] | ||
#define TOP_SCORES_ARRAY_SIZE (3) | ||
^ | ||
|
||
real 0m0.250s | ||
user 0m0.224s | ||
sys 0m0.026s | ||
|
||
=============================================================================== | ||
|
||
Running: clang-format-16 -style=file -i ./high_scores.c ./test_high_scores.c ./high_scores.h | ||
|
||
real 0m0.021s | ||
user 0m0.012s | ||
sys 0m0.009s | ||
|
||
=============================================================================== | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,90 @@ | ||
#include "test-framework/unity.h" | ||
#include "high_scores.h" | ||
#include "test-framework/unity.h" | ||
#include <string.h> | ||
|
||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | ||
|
||
#define TOP_SCORES_ARRAY_SIZE (3) | ||
|
||
void setUp(void) | ||
{ | ||
} | ||
void setUp(void) {} | ||
|
||
void tearDown(void) | ||
{ | ||
} | ||
void tearDown(void) {} | ||
|
||
static void check_personal_top_three(const int32_t *scores, size_t scores_len, | ||
const int32_t *expected, | ||
size_t expected_len) | ||
{ | ||
int32_t top_scores[TOP_SCORES_ARRAY_SIZE] = { 0 }; | ||
size_t expected_len) { | ||
int32_t top_scores[TOP_SCORES_ARRAY_SIZE] = {0}; | ||
|
||
size_t actual_len = personal_top_three(scores, scores_len, top_scores); | ||
size_t actual_len = personal_top_three(scores, scores_len, top_scores); | ||
|
||
TEST_ASSERT_EQUAL_INT32(expected_len, actual_len); | ||
TEST_ASSERT_EQUAL_INT32(expected_len, actual_len); | ||
|
||
if (expected_len > 0) { | ||
TEST_ASSERT_EQUAL_INT32_ARRAY(expected, top_scores, expected_len); | ||
} | ||
if (expected_len > 0) { | ||
TEST_ASSERT_EQUAL_INT32_ARRAY(expected, top_scores, expected_len); | ||
} | ||
} | ||
|
||
static void test_latest_score(void) | ||
{ | ||
const int scores[] = { 100, 0, 90, 30 }; | ||
TEST_ASSERT_EQUAL_INT(latest(scores, ARRAY_SIZE(scores)), 30); | ||
static void test_latest_score(void) { | ||
const int scores[] = {100, 0, 90, 30}; | ||
TEST_ASSERT_EQUAL_INT(latest(scores, ARRAY_SIZE(scores)), 30); | ||
} | ||
|
||
static void test_personal_best(void) | ||
{ | ||
TEST_IGNORE(); // delete this line to run test | ||
const int scores[] = { 40, 100, 70 }; | ||
TEST_ASSERT_EQUAL_INT(personal_best(scores, ARRAY_SIZE(scores)), 100); | ||
static void test_personal_best(void) { | ||
// TEST_IGNORE(); // delete this line to run test | ||
const int scores[] = {40, 100, 70}; | ||
TEST_ASSERT_EQUAL_INT(personal_best(scores, ARRAY_SIZE(scores)), 100); | ||
} | ||
|
||
static void test_personal_top_three_from_a_list_of_scores(void) | ||
{ | ||
TEST_IGNORE(); | ||
const int scores[] = { 10, 30, 90, 30, 100, 20, 10, 0, 30, 40, 40, 70, 70 }; | ||
const int expected[] = { 100, 90, 70 }; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
static void test_personal_top_three_from_a_list_of_scores(void) { | ||
// TEST_IGNORE(); | ||
const int scores[] = {10, 30, 90, 30, 100, 20, 10, 0, 30, 40, 40, 70, 70}; | ||
const int expected[] = {100, 90, 70}; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
} | ||
|
||
static void test_personal_top_highest_to_lowest(void) | ||
{ | ||
TEST_IGNORE(); | ||
const int scores[] = { 20, 10, 30 }; | ||
const int expected[] = { 30, 20, 10 }; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
static void test_personal_top_highest_to_lowest(void) { | ||
// TEST_IGNORE(); | ||
const int scores[] = {20, 10, 30}; | ||
const int expected[] = {30, 20, 10}; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
} | ||
|
||
static void test_personal_top_when_there_is_a_tie(void) | ||
{ | ||
TEST_IGNORE(); | ||
const int scores[] = { 40, 20, 40, 30 }; | ||
const int expected[] = { 40, 40, 30 }; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
static void test_personal_top_when_there_is_a_tie(void) { | ||
// TEST_IGNORE(); | ||
const int scores[] = {40, 20, 40, 30}; | ||
const int expected[] = {40, 40, 30}; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
} | ||
|
||
static void test_personal_top_when_there_are_less_than_3(void) | ||
{ | ||
TEST_IGNORE(); | ||
const int scores[] = { 30, 70 }; | ||
const int expected[] = { 70, 30 }; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
static void test_personal_top_when_there_are_less_than_3(void) { | ||
// TEST_IGNORE(); | ||
const int scores[] = {30, 70}; | ||
const int expected[] = {70, 30}; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
} | ||
|
||
static void test_personal_top_when_there_is_only_one(void) | ||
{ | ||
TEST_IGNORE(); | ||
const int scores[] = { 40 }; | ||
const int expected[] = { 40 }; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
static void test_personal_top_when_there_is_only_one(void) { | ||
// TEST_IGNORE(); | ||
const int scores[] = {40}; | ||
const int expected[] = {40}; | ||
check_personal_top_three(scores, ARRAY_SIZE(scores), expected, | ||
ARRAY_SIZE(expected)); | ||
} | ||
|
||
int main(void) | ||
{ | ||
UnityBegin("test_high_scores.c"); | ||
int main(void) { | ||
UnityBegin("test_high_scores.c"); | ||
|
||
RUN_TEST(test_latest_score); | ||
RUN_TEST(test_personal_best); | ||
RUN_TEST(test_personal_top_three_from_a_list_of_scores); | ||
RUN_TEST(test_personal_top_highest_to_lowest); | ||
RUN_TEST(test_personal_top_when_there_is_a_tie); | ||
RUN_TEST(test_personal_top_when_there_are_less_than_3); | ||
RUN_TEST(test_personal_top_when_there_is_only_one); | ||
RUN_TEST(test_latest_score); | ||
RUN_TEST(test_personal_best); | ||
RUN_TEST(test_personal_top_three_from_a_list_of_scores); | ||
RUN_TEST(test_personal_top_highest_to_lowest); | ||
RUN_TEST(test_personal_top_when_there_is_a_tie); | ||
RUN_TEST(test_personal_top_when_there_are_less_than_3); | ||
RUN_TEST(test_personal_top_when_there_is_only_one); | ||
|
||
return UnityEnd(); | ||
return UnityEnd(); | ||
} |