From 94147b887b26453576d722e2b96d33571809e67d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Sommer?= Date: Wed, 29 Mar 2017 13:15:45 +0200 Subject: [PATCH 1/3] =?UTF-8?q?J=C3=B6rgs=20L=C3=B6sung=20f=C3=BCr=20Euler?= =?UTF-8?q?=2087=20in=20C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2017-03-28/Makefile | 11 ++++ 2017-03-28/jo-so_euler87.c | 108 +++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 2017-03-28/Makefile create mode 100644 2017-03-28/jo-so_euler87.c diff --git a/2017-03-28/Makefile b/2017-03-28/Makefile new file mode 100644 index 0000000..26afcda --- /dev/null +++ b/2017-03-28/Makefile @@ -0,0 +1,11 @@ +#!/usr/bin/make -f + +CFLAGS=-g -O2 -fPIC -fPIE -Wall -Wextra -Wformat=2 -Wunused -Wlogical-op -Wundef \ + -Wswitch-enum -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings \ + -Wconversion -D_FORTIFY_SOURCE=2 -fstack-protector -Wshadow -Wnested-externs + +LDFLAGS=-lm + +.PHONY: all + +all: jo-so_euler87 diff --git a/2017-03-28/jo-so_euler87.c b/2017-03-28/jo-so_euler87.c new file mode 100644 index 0000000..b0245ec --- /dev/null +++ b/2017-03-28/jo-so_euler87.c @@ -0,0 +1,108 @@ +#include +#include +#include + +static int cmp_uint(const void* p1, const void* p2) +{ + const uint a = *(const uint*)p1; + const uint b = *(const uint*)p2; + if (a < b) + return -1; + if (a == b) + return 0; + return 1; +} + +int main(void) +{ + const uint LIMIT = 50000000; + uint* const prime_numbers = malloc(4096); + if (prime_numbers == NULL) + { + perror("Failed to allocate memory for prime numbers"); + return EXIT_FAILURE; + } + uint* const prime_numbers_end = prime_numbers + 4096 / sizeof(*prime_numbers); + + uint max_pn = (uint)sqrt(LIMIT); + prime_numbers[0] = 2u; + prime_numbers[1] = 3u; + uint* next_pn = &prime_numbers[2]; + + for (uint num = *(next_pn - 1) + 2; num <= max_pn; num += 2) + { + for (uint i = (uint)sqrt(num); i >= 3; --i) + { + if (num % i == 0) + goto next; + } + if (next_pn >= prime_numbers_end) + { + fprintf(stderr, "Memory for prime numbers exceeded, but more needed.\n"); + return EXIT_FAILURE; + } + + *next_pn++ = num; + next: + ; + } + + printf("There are %ld numbers below sqrt(50.000.000)\n", next_pn - prime_numbers); + + uint* nums = NULL; + uint* nums_end = nums; + uint* next_num = nums; + + for (uint* pn2 = prime_numbers; pn2 < next_pn; ++pn2) + { + uint pow2 = *pn2 * *pn2; + + for (uint* pn3 = prime_numbers; pn3 < next_pn; ++pn3) + { + uint pow3 = *pn3 * *pn3 * *pn3; + + uint sum = pow2 + pow3; + if (sum >= LIMIT) + break; + + for (uint* pn4 = prime_numbers; pn4 < next_pn; ++pn4) + { + uint pow4 = *pn4 * *pn4; + pow4 *= pow4; + + uint sum2 = sum + pow4; + if (sum2 >= LIMIT) + break; + + if (next_num >= nums_end) + { + long next_num_idx = next_num - nums; + size_t new_size = (uint)(nums_end - nums) * sizeof(*nums) + (1 << 20); + nums = realloc(nums, new_size); + if (nums == NULL) + { + perror("Failed to increase memory for result numbers"); + return EXIT_FAILURE; + } + + nums_end = nums + new_size / sizeof(*nums); + next_num = &nums[next_num_idx]; + } + + *next_num++ = sum2; + } + } + } + nums_end = next_num; + + qsort(nums, (size_t)(nums_end - nums), sizeof(*nums), cmp_uint); + + uint count = 1; + for (const uint* n = nums + 1; n < nums_end; ++n) + if (*(n - 1) != *n) + ++count; + + printf("Answer: %d\n", count); + + return EXIT_SUCCESS; +} From 044412298bd66247559c14ecd43b617a136ef24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Sommer?= Date: Thu, 30 Mar 2017 20:31:24 +0200 Subject: [PATCH 2/3] =?UTF-8?q?jo-so=5Feuler87.c:=20=C3=9Cberarbeiten=20un?= =?UTF-8?q?d=20lesbarer=20gestalten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bei der Übertragung in Rust habe ich gemerkt, dass man den Code noch etwas schöner aufteilen kann, damit er etwas verständlicher und übersichtlicher wird. --- 2017-03-28/Makefile | 2 + 2017-03-28/jo-so_euler87.c | 133 ++++++++++++++++++++++++------------- 2 files changed, 87 insertions(+), 48 deletions(-) diff --git a/2017-03-28/Makefile b/2017-03-28/Makefile index 26afcda..968aae5 100644 --- a/2017-03-28/Makefile +++ b/2017-03-28/Makefile @@ -9,3 +9,5 @@ LDFLAGS=-lm .PHONY: all all: jo-so_euler87 + +jo-so_euler87: diff --git a/2017-03-28/jo-so_euler87.c b/2017-03-28/jo-so_euler87.c index b0245ec..ef461f9 100644 --- a/2017-03-28/jo-so_euler87.c +++ b/2017-03-28/jo-so_euler87.c @@ -1,8 +1,56 @@ +/* + Copyright © 2017 Jörg Sommer + + License: MIT https://opensource.org/licenses/MIT + */ + +////// +// +// Solution of Euler 87 https://projecteuler.net/problem=87 +// #include #include #include -static int cmp_uint(const void* p1, const void* p2) +int gen_prime_numbers(uint limit, uint* pn, uint** pn_end) +{ + pn[0] = 2u; + pn[1] = 3u; + uint* next_pn = &pn[2]; + + for (uint num = *(next_pn - 1) + 2; num <= limit; num += 2) + { + for (uint i = (uint)sqrt(num); i >= 3; --i) + { + if (num % i == 0) + goto next; + } + if (next_pn >= *pn_end) + return -1; + + *next_pn++ = num; + next: + ; + } + + *pn_end = next_pn; + return 0; +} + +typedef struct { + uint* begin; + uint* end; + uint* mem_end; +} vector_uint; + +void vector_init(vector_uint* vec) +{ + vec->begin = NULL; + vec->end = NULL; + vec->mem_end = NULL; +} + +int cmp_uint(const void* p1, const void* p2) { const uint a = *(const uint*)p1; const uint b = *(const uint*)p2; @@ -13,59 +61,60 @@ static int cmp_uint(const void* p1, const void* p2) return 1; } +int vector_add(vector_uint* vec, uint el) +{ + if (vec->end >= vec->mem_end) + { + uint old_size = (uint)(vec->mem_end - vec->begin); + size_t new_size = old_size * sizeof(*vec->begin) + (1 << 20); + vec->begin = realloc(vec->begin, new_size); + if (vec->begin == NULL) + return -1; + + vec->mem_end = vec->begin + new_size / sizeof(*vec->begin); + vec->end = &vec->begin[old_size]; + } + + *vec->end++ = el; + return 0; +} + int main(void) { const uint LIMIT = 50000000; + uint* const prime_numbers = malloc(4096); if (prime_numbers == NULL) { perror("Failed to allocate memory for prime numbers"); return EXIT_FAILURE; } - uint* const prime_numbers_end = prime_numbers + 4096 / sizeof(*prime_numbers); - uint max_pn = (uint)sqrt(LIMIT); - prime_numbers[0] = 2u; - prime_numbers[1] = 3u; - uint* next_pn = &prime_numbers[2]; + uint* prime_numbers_end = prime_numbers + 4096 / sizeof(*prime_numbers); - for (uint num = *(next_pn - 1) + 2; num <= max_pn; num += 2) + if (gen_prime_numbers((uint)sqrt(LIMIT), prime_numbers, &prime_numbers_end) != 0) { - for (uint i = (uint)sqrt(num); i >= 3; --i) - { - if (num % i == 0) - goto next; - } - if (next_pn >= prime_numbers_end) - { - fprintf(stderr, "Memory for prime numbers exceeded, but more needed.\n"); - return EXIT_FAILURE; - } - - *next_pn++ = num; - next: - ; + fprintf(stderr, "Memory for prime numbers exceeded, but more needed.\n"); + return EXIT_FAILURE; } - printf("There are %ld numbers below sqrt(50.000.000)\n", next_pn - prime_numbers); + printf("There are %ld numbers below sqrt(50.000.000)\n", + prime_numbers_end - prime_numbers); - uint* nums = NULL; - uint* nums_end = nums; - uint* next_num = nums; + vector_uint nums; + vector_init(&nums); - for (uint* pn2 = prime_numbers; pn2 < next_pn; ++pn2) + for (uint* pn2 = prime_numbers; pn2 < prime_numbers_end; ++pn2) { uint pow2 = *pn2 * *pn2; - for (uint* pn3 = prime_numbers; pn3 < next_pn; ++pn3) + for (uint* pn3 = prime_numbers; pn3 < prime_numbers_end; ++pn3) { - uint pow3 = *pn3 * *pn3 * *pn3; - - uint sum = pow2 + pow3; + uint sum = pow2 + *pn3 * *pn3 * *pn3; if (sum >= LIMIT) break; - for (uint* pn4 = prime_numbers; pn4 < next_pn; ++pn4) + for (uint* pn4 = prime_numbers; pn4 < prime_numbers_end; ++pn4) { uint pow4 = *pn4 * *pn4; pow4 *= pow4; @@ -74,31 +123,19 @@ int main(void) if (sum2 >= LIMIT) break; - if (next_num >= nums_end) + if (vector_add(&nums, sum2) != 0) { - long next_num_idx = next_num - nums; - size_t new_size = (uint)(nums_end - nums) * sizeof(*nums) + (1 << 20); - nums = realloc(nums, new_size); - if (nums == NULL) - { - perror("Failed to increase memory for result numbers"); - return EXIT_FAILURE; - } - - nums_end = nums + new_size / sizeof(*nums); - next_num = &nums[next_num_idx]; + perror("Failed to increase memory for result numbers"); + return EXIT_FAILURE; } - - *next_num++ = sum2; } } } - nums_end = next_num; - qsort(nums, (size_t)(nums_end - nums), sizeof(*nums), cmp_uint); + qsort(nums.begin, (size_t)(nums.end - nums.begin), sizeof(*nums.begin), cmp_uint); uint count = 1; - for (const uint* n = nums + 1; n < nums_end; ++n) + for (const uint* n = nums.begin + 1; n < nums.end; ++n) if (*(n - 1) != *n) ++count; From b8040027c95b094e94b768adcbd271acea622139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Sommer?= Date: Thu, 30 Mar 2017 20:33:16 +0200 Subject: [PATCH 3/3] =?UTF-8?q?J=C3=B6rgs=20L=C3=B6sung=20f=C3=BCr=20Euler?= =?UTF-8?q?=2087=20in=20Rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2017-03-28/Makefile | 5 ++- 2017-03-28/jo-so_euler87.rs | 62 +++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 2017-03-28/jo-so_euler87.rs diff --git a/2017-03-28/Makefile b/2017-03-28/Makefile index 968aae5..db17310 100644 --- a/2017-03-28/Makefile +++ b/2017-03-28/Makefile @@ -8,6 +8,9 @@ LDFLAGS=-lm .PHONY: all -all: jo-so_euler87 +all: jo-so_euler87 jo-so_euler87_rust jo-so_euler87: + +jo-so_euler87_rust: jo-so_euler87.rs + rustc -O -g -o $@ $< diff --git a/2017-03-28/jo-so_euler87.rs b/2017-03-28/jo-so_euler87.rs new file mode 100644 index 0000000..c5611e1 --- /dev/null +++ b/2017-03-28/jo-so_euler87.rs @@ -0,0 +1,62 @@ +/* + Copyright © 2017 Jörg Sommer + + License: MIT https://opensource.org/licenses/MIT + */ + +////// +// +// Solution of Euler 87 https://projecteuler.net/problem=87 +// +fn gen_prime_numbers(limit: u32) -> Vec { + let mut ret = vec![2, 3]; + + let mut num = *ret.last().unwrap(); + 'num: while num + 2 <= limit { + num += 2; + for i in 3..((num as f32).sqrt() as u32 + 1) { + if num % i == 0 { + continue 'num; + } + } + ret.push(num); + } + + ret +} + +fn main() { + const LIMIT: u32 = 50_000_000; + + // println!("pn {:?}", gen_prime_numbers(500)); + let pn = gen_prime_numbers((LIMIT as f32).sqrt() as u32); + + println!("There are {} numbers below sqrt(50.000.000)", pn.len()); + + let mut nums = Vec::new(); + + for pn2 in pn.iter() { + let pow2 = pn2.pow(2); + + for pn3 in pn.iter() { + let sum = pow2 + pn3.pow(3); + if sum >= LIMIT { + break; + } + + for pn4 in pn.iter() { + let sum2 = sum + pn4.pow(4); + if sum2 >= LIMIT { + break; + } + + nums.push(sum2); + } + } + } + + nums.sort(); + nums.dedup(); + + println!("Answer {}", nums.len()); +}