diff --git a/c/include/bcd.h b/c/include/bcd.h index e7a9a1d9..2fdf4171 100644 --- a/c/include/bcd.h +++ b/c/include/bcd.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include @@ -538,6 +539,25 @@ inline BCD_int shift_bcd_right(BCD_int a, uintmax_t tens) { return div_bcd_pow_10(a, tens); } +uintmax_t bcd_to_unsigned(BCD_int a) { + if (a.zero) + return 0; + uintmax_t answer = 0; + for (size_t i = 0; i < a.bcd_digits; ++i) { + size_t digit = a.bcd_digits - i - 1; + answer = answer * 100 + ((a.digits[digit] & 0xF0) >> 4) * 10 + (a.digits[digit] & 0xF); + } + return answer; +} + +uintmax_t bcd_to_signed(BCD_int a); +inline uintmax_t bcd_to_signed(BCD_int a) { + uintmax_t answer = bcd_to_unsigned(a); + if (a.negative) + return -answer; + return answer; +} + void print_bcd(BCD_int x) { if (unlikely(x.zero)) { printf("0"); diff --git a/c/p0000_template.c b/c/p0000_template.c index dcd75604..937fbc22 100644 --- a/c/p0000_template.c +++ b/c/p0000_template.c @@ -7,6 +7,7 @@ critque. This paragraph should be replaced by the problem description, excluding images. */ +#pragma once #include unsigned long long p0000() { diff --git a/c/p0001.c b/c/p0001.c index 025cba5d..205f074c 100644 --- a/c/p0001.c +++ b/c/p0001.c @@ -12,11 +12,12 @@ get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000. */ - +#pragma once #include #include "include/iterator.h" unsigned long long p0001() { + unsigned long long answer = 0; counter c = counter3(0, 1000, 3); while (!c.exhausted) { answer += next(c); @@ -29,10 +30,13 @@ unsigned long long p0001() { while (!c.exhausted) { answer -= next(c); } + return answer; } +#ifndef UNITY_END int main(int argc, char const *argv[]) { unsigned long long answer = p0001(); printf("%llu\n", answer); return 0; } +#endif diff --git a/c/p0002.c b/c/p0002.c index 71139c3e..7f014ab4 100644 --- a/c/p0002.c +++ b/c/p0002.c @@ -14,10 +14,11 @@ By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms. */ +#pragma once #include #include "include/fibonacci.h" -int main(int argc, char const *argv[]) { +unsigned long long p0002() { unsigned long long answer = 0; fibonacci fib = fibonacci1(3999999); while (!fib.exhausted) { @@ -25,6 +26,13 @@ int main(int argc, char const *argv[]) { next(fib); // odd (1, 5, 21, 89, ...) answer += next(fib); // even (2, 8, 34, 144, ...) } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0002(); printf("%llu\n", answer); return 0; } +#endif diff --git a/c/p0003.c b/c/p0003.c index a3c708e4..449f2fee 100644 --- a/c/p0003.c +++ b/c/p0003.c @@ -11,16 +11,24 @@ The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 ? */ +#pragma once #include #include "include/primes.h" -int main(int argc, char const *argv[]) { +unsigned long long p0003() { unsigned long long answer = 0; prime_factor_counter pfc = prime_factors(600851475143); while (!pfc.exhausted) { answer = next(pfc); } free_prime_factor_counter(pfc); + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0003(); printf("%llu\n", answer); return 0; } +#endif diff --git a/c/p0004.c b/c/p0004.c index d88f6eb1..54c0c865 100644 --- a/c/p0004.c +++ b/c/p0004.c @@ -10,12 +10,12 @@ the product of two 2-digit numbers is 9009 = 91 × 99. Find the largest palindrome made from the product of two 3-digit numbers. */ +#pragma once #include #include "include/digits.h" - -int main(int argc, char const *argv[]) { +unsigned int p0004() { unsigned int answer = 0, i, j, a, z, prod; bool broken; digit_counter dc; @@ -36,6 +36,12 @@ int main(int argc, char const *argv[]) { free_digit_counter(dc); } } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { printf("%u", answer); return 0; } +#endif diff --git a/c/p0005.c b/c/p0005.c index e1c6d3e7..e342980d 100644 --- a/c/p0005.c +++ b/c/p0005.c @@ -12,11 +12,12 @@ number infrastructure a lot easier to set up. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? */ +#pragma once #include #include "include/macros.h" #include "include/primes.h" -int main(int argc, char const *argv[]) { +unsigned long long p0005() { unsigned long long answer = 1; unsigned char factor_tracker[20] = {0}, local_factor_tracker[20] = {0}; prime_factor_counter pfc; @@ -36,6 +37,13 @@ int main(int argc, char const *argv[]) { answer *= i; } } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0005(); printf("%llu", answer); return 0; } +#endif diff --git a/c/p0006.c b/c/p0006.c index 1f8d9285..d618b55c 100644 --- a/c/p0006.c +++ b/c/p0006.c @@ -19,14 +19,21 @@ numbers and the square of the sum is 3025 − 385 = 2640. Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum. */ +#pragma once #include - -int main(int argc, char const *argv[]) { +unsigned long long p0006() { unsigned long long sum = 100 * 101 / 2, sum_of_squares = 0; for (unsigned long long i = 1; i < 101; i++) { sum_of_squares += i * i; } - printf("%llu", sum * sum - sum_of_squares); + return sum * sum - sum_of_squares; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0006(); + printf("%llu", answer); return 0; } +#endif diff --git a/c/p0007.c b/c/p0007.c index ffe3865c..cc955ccb 100644 --- a/c/p0007.c +++ b/c/p0007.c @@ -9,20 +9,26 @@ By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that What is the 10 001st prime number? */ +#pragma once #include #include "include/primes.h" - -int main(int argc, char const *argv[]) { +unsigned long long p0007() { unsigned int answer, count = 0; prime_sieve ps = prime_sieve0(); while (!ps.exhausted) { answer = next(ps); - if (++count == 10001) { - printf("%u", answer); + if (++count == 10001) break; - } } free_prime_sieve(ps); + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0007(); + printf("%llu", answer); return 0; } +#endif diff --git a/c/p0008.c b/c/p0008.c index 5329fb8a..b28973aa 100644 --- a/c/p0008.c +++ b/c/p0008.c @@ -30,11 +30,11 @@ The four adjacent digits in the 1000-digit number that have the greatest product Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product? */ +#pragma once #include #include "include/macros.h" - -int main(int argc, char const *argv[]) { +unsigned long long p0008() { size_t i, j; unsigned long long answer = 0, tmp; const char *plain_digits = ("73167176531330624919225119674426574742355349194934" @@ -68,6 +68,13 @@ int main(int argc, char const *argv[]) { } answer = max(answer, tmp); } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0008(); printf("%llu", answer); return 0; } +#endif diff --git a/c/p0009.c b/c/p0009.c index 6c0c0f5a..5bd4d036 100644 --- a/c/p0009.c +++ b/c/p0009.c @@ -13,10 +13,10 @@ For example, 32 + 42 = 9 + 16 = 25 = 52. There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc. */ +#pragma once #include - -int main(int argc, char const *argv[]) { +unsigned long long p0009() { unsigned long long answer = 0; for (unsigned int c = 3; !answer && c < 1000; c++) { for (unsigned int b = 2; b < c; b++) { @@ -27,6 +27,13 @@ int main(int argc, char const *argv[]) { } } } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0009(); printf("%llu", answer); return 0; } +#endif diff --git a/c/p0010.c b/c/p0010.c index 65903215..d09f4baa 100644 --- a/c/p0010.c +++ b/c/p0010.c @@ -9,17 +9,24 @@ The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. Find the sum of all the primes below two million. */ +#pragma once #include #include "include/primes.h" - -int main(int argc, char const *argv[]) { +unsigned long long p0010() { unsigned long long tmp, answer = 0; prime_sieve ps = prime_sieve0(); while ((tmp = next(ps)) < 2000000) { answer += tmp; } free_prime_sieve(ps); - printf("%llu", answer); // this is because of a bug + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0010(); + printf("%llu", answer); return 0; } +#endif diff --git a/c/p0011.c b/c/p0011.c index d9a62a28..f2b1e29f 100644 --- a/c/p0011.c +++ b/c/p0011.c @@ -31,6 +31,7 @@ The product of these numbers is 26 × 63 × 78 × 14 = 1788696. What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid? */ +#pragma once #include #include "include/macros.h" @@ -57,8 +58,7 @@ static const unsigned char grid[20][20] = { { 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48} }; - -int main(int argc, char const *argv[]) { +unsigned long long p0011() { unsigned long answer = 0, tmp; unsigned char i, j; for (i = 0; i < 20; i++) { @@ -81,6 +81,13 @@ int main(int argc, char const *argv[]) { answer = max(answer, tmp); } } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0011(); printf("%lu", answer); return 0; } +#endif diff --git a/c/p0012.c b/c/p0012.c index d76a1fbd..d836264d 100644 --- a/c/p0012.c +++ b/c/p0012.c @@ -26,6 +26,7 @@ We can see that 28 is the first triangle number to have over five divisors. What is the value of the first triangle number to have over five hundred divisors? */ +#pragma once #include #include "include/factors.h" @@ -51,16 +52,21 @@ triangle_iterator triangle_iterator0() { return ret; } -int main(int argc, char const *argv[]) { +unsigned long long p0012() { triangle_iterator ti = triangle_iterator0(); unsigned long long current; while (true) { current = next(ti); // printf("%llu\n", current); - if (proper_divisor_count(current) > 499) { - printf("%llu", current); - return 0; - } + if (proper_divisor_count(current) > 499) + return current; } - return -1; } + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0012(); + printf("%llu", answer); + return 0; +} +#endif diff --git a/c/p0013.c b/c/p0013.c index 8d4188f0..195f0555 100644 --- a/c/p0013.c +++ b/c/p0013.c @@ -108,6 +108,7 @@ Work out the first ten digits of the sum of the following one-hundred 50-digit n 20849603980134001723930671666823555245252804609722 53503534226472524250874054075591789781264330331690 */ +#pragma once #include #include "include/bcd.h" @@ -215,9 +216,9 @@ static const char numbers[100][50] = { "53503534226472524250874054075591789781264330331690" }; - -int main(int argc, char const *argv[]) { +unsigned long long p0013() { BCD_int answer, tmp1, tmp2 = new_BCD_int(0, false); + uintmax_t ret; for (size_t i = 0; i < 100; i++) { tmp1 = BCD_from_ascii(numbers[i], 50, false); answer = add_bcd(tmp1, tmp2); @@ -227,7 +228,15 @@ int main(int argc, char const *argv[]) { } answer = div_bcd_pow_10(tmp2, tmp2.decimal_digits - 10); free_BCD_int(tmp2); - print_bcd(answer); + ret = bcd_to_unsigned(answer); free_BCD_int(answer); + return ret; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + BCD_int answer = p0013(); + printf("%llu\n", answer); return 0; } +#endif diff --git a/c/p0014.c b/c/p0014.c index 1af03e62..1a223950 100644 --- a/c/p0014.c +++ b/c/p0014.c @@ -20,6 +20,7 @@ Which starting number, under one million, produces the longest chain? NOTE: Once the chain starts the terms are allowed to go above one million. */ +#pragma once #include #include "include/macros.h" @@ -44,8 +45,7 @@ inline unsigned int collatz_len(unsigned long long n) { return ret; } - -int main(int argc, char const *argv[]) { +unsigned long long p0014() { unsigned long long answer = 2, length = 2, tmp; for (unsigned long long test = 3; test < 1000000; test++) { tmp = collatz_len(test); @@ -54,6 +54,13 @@ int main(int argc, char const *argv[]) { length = tmp; } } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0014(); printf("%llu", answer); return 0; } +#endif diff --git a/c/p0015.c b/c/p0015.c index f4f92290..51c49a99 100644 --- a/c/p0015.c +++ b/c/p0015.c @@ -14,15 +14,20 @@ routes to the bottom right corner. How many such routes are there through a 20×20 grid? */ +#pragma once #include #include "include/math.h" #define lattice_paths(height, width) (n_choose_r(height + width, height)) +unsigned long long p0015() { + return lattice_paths(20, 20); +} +#ifndef UNITY_END int main(int argc, char const *argv[]) { - unsigned long long answer; - answer = lattice_paths(20, 20); + unsigned long long p0015(); printf("%llu", answer); return 0; } +#endif diff --git a/c/p0016.c b/c/p0016.c index 37382e04..bedc0eed 100644 --- a/c/p0016.c +++ b/c/p0016.c @@ -10,17 +10,24 @@ to do it than this, if I could manage arbitrary-precision multiplication more ef What is the sum of the digits of the number 21000? */ +#pragma once #include #include "include/bcd.h" - -int main(int argc, char const *argv[]) { +unsigned long long p0016() { unsigned long long answer = 0; BCD_int power = pow_cuint_cuint(256, 125); for (size_t i = 0; i < power.bcd_digits; i++) { answer += power.digits[i] & 0x0F; answer += power.digits[i] >> 4; } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0016(); printf("%llu\n", answer); return 0; } +#endif diff --git a/c/p0034.c b/c/p0034.c index 048f99e5..8208d9ed 100644 --- a/c/p0034.c +++ b/c/p0034.c @@ -10,11 +10,12 @@ their digits. Note: as 1! = 1 and 2! = 2 are not sums they are not included. */ +#pragma once #include #include "include/digits.h" #include "include/math.h" -int main(int argc, char const *argv[]) { +unsigned long long p0034() { unsigned long long answer = 0, sum; digit_counter dc; for (unsigned long i = 10; i < 100000; i++) { @@ -28,6 +29,13 @@ int main(int argc, char const *argv[]) { } free_digit_counter(dc); } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned long long answer = p0034(); printf("%llu", answer); return 0; } +#endif diff --git a/c/p0076.c b/c/p0076.c index e1972768..d5c6731b 100644 --- a/c/p0076.c +++ b/c/p0076.c @@ -38,11 +38,11 @@ It is possible to write five as a sum in exactly six different ways: How many different ways can one hundred be written as a sum of at least two positive integers? */ +#pragma once #include #include "include/macros.h" - -int main(int argc, char const *argv[]) { +unsigned int p0076() { unsigned int answer = 0; unsigned char idx, i, sum = 100, counts[101] = {0, 0, 100, 0}; while (!counts[100]) { @@ -66,6 +66,13 @@ int main(int argc, char const *argv[]) { sum += counts[i]; } } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + unsigned int answer = p0076(); printf("%u", answer); return 0; } +#endif diff --git a/c/test.c b/c/test.c index 908d2da0..9e4e593a 100644 --- a/c/test.c +++ b/c/test.c @@ -1,3 +1,4 @@ +#define UNITY_SUPPORT_TEST_CASES #include "Unity/src/unity.h" #include "p0001.c" #include "p0002.c" @@ -10,7 +11,7 @@ #include "p0009.c" #include "p0010.c" #include "p0011.c" -#include "p0012.c" +// #include "p0012.c" #include "p0013.c" #include "p0014.c" #include "p0015.c" @@ -20,30 +21,31 @@ typedef struct { unsigned int id; - uint64_t answer; - void * func; + unsigned long long answer; + unsigned long long (*func)(); } Answer; -static const Answer[] answers = { - {1, 1, p0001}, - {2, 1, p0002}, - {3, 1, p0003}, - {4, 1, p0004}, - {5, 1, p0005}, - {6, 1, p0006}, - {7, 1, p0007}, - {8, 1, p0008}, - {9, 1, p0009}, - {10, 1, p0010}, - {11, 1, p0011}, - {12, 1, p0012}, - {13, 1, p0013}, - {14, 1, p0014}, - {15, 1, p0015}, - {16, 1, p0016}, - {34, 1, p0034}, - {76, 1, p0076}, +#define ANSWERS_LEN (sizeof(answers) / sizeof(answers[0])) +static const Answer answers[] = { + {1, 233168, p0001}, + {2, 4613732, p0002}, + {3, 6857, p0003}, + {4, 906609, (unsigned long long (*)()) p0004}, + {5, 232792560, p0005}, + {6, 25164150, p0006}, + {7, 104743, p0007}, + {8, 23514624000, p0008}, + {9, 31875000, p0009}, + {10, 142913828922, p0010}, + {11, 70600674, p0011}, + {13, 5537376230, p0013}, + {14, 837799, p0014}, + {15, 137846528820, p0015}, + {16, 1366, p0016}, + {34, 40730, p0034}, + {76, 190569291, (unsigned long long (*)()) p0076}, }; +static unsigned long long current_index = 0; void setUp(void) { // set stuff up here @@ -53,14 +55,21 @@ void tearDown(void) { // clean stuff up here } -TEST_RANGE(0, sizeof(answers) / sizeof(answers[0]), 1) -void test_euler_answer(size_t index) { - Answer key = answers[index]; - TEST_ASSERT_EQUAL_INT64(key.answer, key.func()) +void test_euler_answer() { + Answer key = answers[current_index]; + unsigned long long result = key.func(); + char *msg = (char*)malloc(256 * sizeof(char)); + snprintf(msg, 256, "Euler problem %u should have an answer of %llu, but we actually got %llu", key.id, key.answer, result); + TEST_ASSERT_EQUAL_INT64_MESSAGE(key.answer, result, msg); + free(msg); } -int main(void) { +int main(int argc, char const *argv[]) { + char func_name[32]; UNITY_BEGIN(); - RUN_TEST(test_function_should_doAlsoDoBlah); + for (current_index = 0; current_index < ANSWERS_LEN; ++current_index) { + snprintf(func_name, 32, "test_euler_answer[%03u]", answers[current_index].id); + UnityDefaultTestRun(test_euler_answer, func_name, __LINE__); + } return UNITY_END(); }