diff --git a/2017-03-28/Makefile b/2017-03-28/Makefile new file mode 100644 index 0000000..db17310 --- /dev/null +++ b/2017-03-28/Makefile @@ -0,0 +1,16 @@ +#!/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 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.c b/2017-03-28/jo-so_euler87.c new file mode 100644 index 0000000..ef461f9 --- /dev/null +++ b/2017-03-28/jo-so_euler87.c @@ -0,0 +1,145 @@ +/* + Copyright © 2017 Jörg Sommer + + License: MIT https://opensource.org/licenses/MIT + */ + +////// +// +// Solution of Euler 87 https://projecteuler.net/problem=87 +// +#include +#include +#include + +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; + if (a < b) + return -1; + if (a == b) + return 0; + 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* prime_numbers_end = prime_numbers + 4096 / sizeof(*prime_numbers); + + if (gen_prime_numbers((uint)sqrt(LIMIT), prime_numbers, &prime_numbers_end) != 0) + { + 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", + prime_numbers_end - prime_numbers); + + vector_uint nums; + vector_init(&nums); + + for (uint* pn2 = prime_numbers; pn2 < prime_numbers_end; ++pn2) + { + uint pow2 = *pn2 * *pn2; + + for (uint* pn3 = prime_numbers; pn3 < prime_numbers_end; ++pn3) + { + uint sum = pow2 + *pn3 * *pn3 * *pn3; + if (sum >= LIMIT) + break; + + for (uint* pn4 = prime_numbers; pn4 < prime_numbers_end; ++pn4) + { + uint pow4 = *pn4 * *pn4; + pow4 *= pow4; + + uint sum2 = sum + pow4; + if (sum2 >= LIMIT) + break; + + if (vector_add(&nums, sum2) != 0) + { + perror("Failed to increase memory for result numbers"); + return EXIT_FAILURE; + } + } + } + } + + qsort(nums.begin, (size_t)(nums.end - nums.begin), sizeof(*nums.begin), cmp_uint); + + uint count = 1; + for (const uint* n = nums.begin + 1; n < nums.end; ++n) + if (*(n - 1) != *n) + ++count; + + printf("Answer: %d\n", count); + + return EXIT_SUCCESS; +} 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()); +}