Skip to content

Commit

Permalink
Improve id0021 and id0023 using new libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
ishanpranav committed Jan 26, 2024
1 parent f570ce3 commit 3d3d015
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 119 deletions.
24 changes: 11 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ miller_rabin_primality_test.o: \
lib/primality_tests/miller_rabin_primality_test.h
$(CC) $(CFLAGS) -c $< -o $@

sieve_primality_test.o: \
lib/primality_tests/sieve_primality_test.c \
lib/primality_tests/sieve_primality_test.h
$(CC) $(CFLAGS) -c $< -o $@

boolean_set.o: lib/boolean_set.c lib/boolean_set.h
$(CC) $(CFLAGS) -c $< -o $@

Expand All @@ -42,6 +37,9 @@ divisor_iterator.o: lib/divisor_iterator.c lib/divisor_iterator.h
euler.o: lib/euler.c lib/euler.h
$(CC) $(CFLAGS) -c $< -o $@

factor_iterator.o: lib/factor_iterator.c lib/factor_iterator.h
$(CC) $(CFLAGS) -c $< -o $@

list.o: lib/list.c lib/list.h
$(CC) $(CFLAGS) -c $< -o $@

Expand Down Expand Up @@ -72,8 +70,8 @@ id0001.o: src/id0001.c euler.o
id0002.o: src/id0002.c euler.o
$(CC) $(CFLAGS) $< -o $@ euler.o

id0003.o: src/id0003.c euler.o $(SIEVE_O)
$(CC) $(CFLAGS) $< -o $@ euler.o $(SIEVE_O) -lm
id0003.o: src/id0003.c euler.o factor_iterator.o $(SIEVE_O)
$(CC) $(CFLAGS) $< -o $@ euler.o factor_iterator.o $(SIEVE_O) -lm

id0004.o: src/id0004.c euler.o
$(CC) $(CFLAGS) $< -o $@ euler.o
Expand All @@ -99,8 +97,8 @@ id0010.o: src/id0010.c euler.o $(SIEVE_O)
id0011.o: src/id0011.c euler.o
$(CC) $(CFLAGS) $< -o $@ euler.o

id0012.o: src/id0012.c divisor_iterator.o euler.o $(SIEVE_O)
$(CC) $(CFLAGS) $< -o $@ divisor_iterator.o euler.o $(SIEVE_O) -lm
id0012.o: src/id0012.c euler.o factor_iterator.o $(SIEVE_O)
$(CC) $(CFLAGS) $< -o $@ euler.o factor_iterator.o $(SIEVE_O) -lm

id0013.o: src/id0013.c euler.o
$(CC) $(CFLAGS) $< -o $@ euler.o
Expand All @@ -126,14 +124,14 @@ id0019.o: src/id0019.c euler.o
id0020.o: src/id0020.c euler.o lp_string.o series.o
$(CC) $(CFLAGS) $< -o $@ euler.o lp_string.o series.o -lgmp

id0021.o: src/id0021.c divisor_iterator.o euler.o
$(CC) $(CFLAGS) $< -o $@ divisor_iterator.o euler.o -lm
id0021.o: src/id0021.c euler.o factor_iterator.o $(SIEVE_O)
$(CC) $(CFLAGS) $< -o $@ euler.o factor_iterator.o $(SIEVE_O) -lm

id0022.o: src/id0022.c euler.o $(LP_STRING_COLLECTION_O)
$(CC) $(CFLAGS) $< -o $@ euler.o $(LP_STRING_COLLECTION_O)

id0023.o: src/id0023.c boolean_set.o divisor_iterator.o euler.o list.o
$(CC) $(CFLAGS) $< -o $@ boolean_set.o divisor_iterator.o euler.o list.o -lm
id0023.o: src/id0023.c euler.o factor_iterator.o $(SIEVE_O)
$(CC) $(CFLAGS) $< -o $@ euler.o factor_iterator.o $(SIEVE_O) -lm

id0024.o: src/id0024.c euler.o list.o permutation_iterator.o
$(CC) $(CFLAGS) $< -o $@ euler.o list.o permutation_iterator.o
Expand Down
13 changes: 0 additions & 13 deletions lib/divisor_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,3 @@ void divisor_next(DivisorIterator iterator)
iterator->state = DIVISOR_ITERATOR_STATE_INITIAL;
}
}

long long divisor_sum(long long n)
{
int result = 0;
struct DivisorIterator it;

for (divisor_begin(&it, n); !divisor_end(&it); divisor_next(&it))
{
result += it.current;
}

return result;
}
18 changes: 5 additions & 13 deletions lib/divisor_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,26 @@ struct DivisorIterator
typedef struct DivisorIterator* DivisorIterator;

/**
* Provides an iterator over the divisors of `n`.
* Provides an iterator over the proper divisors of `n`.
*
* @param iterator the iterator.
* @param n the number whose proper divisors to enumerate.
* @param n the number whose divisors to enumerate.
*/
void divisor_begin(DivisorIterator iterator, long long n);

/**
* Returns a value indicating whether the iterator can advance to the next
* divisor.
* proper divisor.
*
* @param iterator
* @param iterator the iterator.
* @return `true` if the iterator can successfully advance to the next divisor;
* `false` if there are no more divisors.
*/
bool divisor_end(DivisorIterator iterator);

/**
* Advances the iterator to the next divisor.
* Advances the iterator to the next proper divisor.
*
* @param iterator the iterator.
*/
void divisor_next(DivisorIterator iterator);

/**
* Computes the sum of the proper divisors of a natural number.
*
* @param n the number whose proper divisors to sum.
* @return The sum of the proper divisors of `n`.
*/
long long divisor_sum(long long n);
70 changes: 70 additions & 0 deletions lib/factor_iterator.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Licensed under the MIT License.

#include <math.h>
#include "factor_iterator.h"

void factor_begin(FactorIterator iterator, long long n, Sieve primes)
{
iterator->remainder = n;

sieve_begin(&iterator->iterator, primes);
factor_next(iterator);
}

bool factor_end(FactorIterator iterator)
{
return !iterator->remainder;
}

void factor_next(FactorIterator iterator)
{
if (iterator->remainder == 1)
{
iterator->current = *iterator->iterator.current;
iterator->remainder = 0;
iterator->currentCount = 1;

return;
}

while (iterator->remainder % *iterator->iterator.current != 0)
{
sieve_next(&iterator->iterator);
}

iterator->current = *iterator->iterator.current;
iterator->remainder /= iterator->current;
iterator->currentCount = 1;

while (iterator->remainder % iterator->current == 0)
{
iterator->remainder /= iterator->current;
iterator->currentCount++;
}
}

int factor_divisor_count(long long n, Sieve primes)
{
int result = 1;
struct FactorIterator it;

for (factor_begin(&it, n, primes); !factor_end(&it); factor_next(&it))
{
result *= it.currentCount + 1;
}

return result;
}

int factor_divisor_sum(long long n, Sieve primes)
{
int result = 1;
struct FactorIterator it;

for (factor_begin(&it, n, primes); !factor_end(&it); factor_next(&it))
{
result *= (pow(it.current, it.currentCount + 1) - 1) / (it.current - 1);
}

return result;
}
59 changes: 59 additions & 0 deletions lib/factor_iterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Licensed under the MIT License.

#include "sieve_iterator.h"

/** Iterates over the prime factors of a positive integer. */
struct FactorIterator
{
struct SieveIterator iterator;
long long current;
long long remainder;
int currentCount;
};

/** Iterates over the prime factors of a positive integer. */
typedef struct FactorIterator* FactorIterator;

/**
* Provides an iterator over the prime factors of `n`.
*
* @param iterator the iterator.
* @param n the number whose factors to enumerate.
* @param primes the prime sequence.
*/
void factor_begin(FactorIterator iterator, long long n, Sieve primes);

/**
* Returns a value indicating whether the iterator can advance to the next prime
* factor.
*
* @param iterator the iterator.
* @return `true` if the iterator can successfully advance to the next factor;
* `false` if there are no more factors.
*/
bool factor_end(FactorIterator iterator);

/**
* Advances the iterator to the next prime factor.
*
* @param iterator the iterator.
*/
void factor_next(FactorIterator iterator);

/**
* Returns the number of divisors of a positive integer.
*
* @param n the number whose divisors to count.
* @param primes the prime sequence.
* @return The number of divisors of `n`.
*/
int factor_divisor_count(long long n, Sieve primes);

/**
* Computes the sum of the divisors of a positive integer.
*
* @param n the number whose divisors to sum.
* @param primes the prime sequence.
* @return The sum of the divisors of `n`.
*/
int factor_divisor_sum(long long n, Sieve primes);
18 changes: 9 additions & 9 deletions lib/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,6 @@ static int long_long_compare(Object left, Object right)
return 0;
}

void list_sort(List instance)
{
qsort(
instance->begin,
instance->end - instance->begin,
sizeof * instance->begin,
long_long_compare);
}

void list_reverse(List instance)
{
if (instance->begin == instance->end)
Expand All @@ -124,6 +115,15 @@ void list_reverse(List instance)
}
}

void list_sort(List instance)
{
qsort(
instance->begin,
instance->end - instance->begin,
sizeof * instance->begin,
long_long_compare);
}

bool list_equals(List left, List right)
{
size_t length = left->end - left->begin;
Expand Down
8 changes: 4 additions & 4 deletions lib/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,18 @@ bool list_contains(List instance, long long item);
void list_clear(List instance);

/**
* Sorts the elements in the list.
* Reverses the order of the elements in the list.
*
* @param instance the `List` instance.
*/
void list_sort(List instance);
void list_reverse(List instance);

/**
* Reverses the order of the elements in the list.
* Sorts the elements in the list.
*
* @param instance the `List` instance.
*/
void list_reverse(List instance);
void list_sort(List instance);

/**
* Determines whether two lists are equal.
Expand Down
10 changes: 1 addition & 9 deletions lib/sieve.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,7 @@ static Exception sieve_extend(Sieve instance, long long max)

long long end = sqrt(max);

for (long long* p = instance->primes.begin; p < instance->primes.end; p++)
{
for (long long n = *p * *p; n < max; n += *p)
{
instance->composites.begin[n - 2] = true;
}
}

for (long long m = instance->max; m <= end; m++)
for (long long m = 2; m <= end; m++)
{
if (instance->composites.begin[m - 2])
{
Expand Down
32 changes: 12 additions & 20 deletions src/id0003.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,7 @@

#include <math.h>
#include "../lib/euler.h"
#include "../lib/sieve_iterator.h"

static long long math_max_prime_factor(Sieve primes, long long n)
{
long long result = -1;
struct SieveIterator it;

for (sieve_begin(&it, primes); n != 1; sieve_next(&it))
{
while (n % *it.current == 0)
{
result = *it.current;
n /= *it.current;
}
}

return result;
}
#include "../lib/factor_iterator.h"

int main(void)
{
Expand All @@ -31,7 +14,16 @@ int main(void)

euler_ok();

long long max = math_max_prime_factor(&primes, 600851475143ll);
struct FactorIterator it;

factor_begin(&it, 600851475143ll, &primes);

while (!factor_end(&it))
{
factor_next(&it);
}

return euler_submit(3, max, start);
finalize_sieve(&primes);

return euler_submit(3, it.current, start);
}
Loading

0 comments on commit 3d3d015

Please sign in to comment.