Impl limited C solution to problem
This commit is contained in:
parent
91c0654dec
commit
7e3fc05cf1
5 changed files with 128 additions and 3 deletions
2
c_impl/.gitignore
vendored
2
c_impl/.gitignore
vendored
|
@ -1,2 +1,4 @@
|
||||||
src/*.o
|
src/*.o
|
||||||
ReciprocalOfPalindromes
|
ReciprocalOfPalindromes
|
||||||
|
.cache
|
||||||
|
compile_commands.json
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
ifdef DEBUG
|
||||||
|
EXTRA_CFLAGS = -g -O0
|
||||||
|
else
|
||||||
|
EXTRA_CFLAGS = -DNDEBUG -O3
|
||||||
|
endif
|
||||||
|
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS ?= -Wall -Wextra -Wpedantic
|
CFLAGS ?= -Wall -Wextra -Wpedantic ${EXTRA_CFLAGS}
|
||||||
|
|
||||||
all: ReciprocalOfPalindromes
|
all: ReciprocalOfPalindromes
|
||||||
|
|
||||||
ReciprocalOfPalindromes: src/main.o
|
ReciprocalOfPalindromes: src/main.o src/palindrome_generator.o
|
||||||
$(CC) $(CFLAGS) -o ReciprocalOfPalindromes $^
|
$(CC) $(CFLAGS) -o ReciprocalOfPalindromes $^
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
|
@ -1,3 +1,45 @@
|
||||||
int main() {
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "palindrome_generator.h"
|
||||||
|
|
||||||
|
#define LIMIT 128
|
||||||
|
|
||||||
|
// expects a const char* for "msg"
|
||||||
|
#define LOG(msg) do { \
|
||||||
|
printf("%s:%u %s\n", __FILE__, __LINE__, msg); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
unsigned long long limit = LIMIT;
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
// do nothing
|
||||||
|
} else if (argc == 2) {
|
||||||
|
limit = strtoull(argv[1], NULL, 10);
|
||||||
|
if (limit == 0) {
|
||||||
|
LOG("ERROR: Failed to parse arg into unsigned long long");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG("ERROR: Program requires one integer as its only argument, or no "
|
||||||
|
"args");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Generating sum of reciprocals of palindromes with \"limit\" of "
|
||||||
|
"%llu\n",
|
||||||
|
limit);
|
||||||
|
|
||||||
|
double sum = 0.0;
|
||||||
|
PGeneratorState state = PGenerator_Init();
|
||||||
|
|
||||||
|
while(limit > 0) {
|
||||||
|
--limit;
|
||||||
|
sum += 1.0 / (double)(PGenerator_Next(&state));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Resulting sum == %lf, last state is %llu\n", sum, state.current);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
64
c_impl/src/palindrome_generator.c
Normal file
64
c_impl/src/palindrome_generator.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#include "palindrome_generator.h"
|
||||||
|
|
||||||
|
PGeneratorState PGenerator_Init() {
|
||||||
|
return (PGeneratorState){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO needs testing
|
||||||
|
int PGeneratorInternal_IsPalindrome(unsigned long long n) {
|
||||||
|
unsigned int digits = 0;
|
||||||
|
|
||||||
|
for (unsigned long long i = n; i > 0; i /= 10) {
|
||||||
|
++digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digits == 0) {
|
||||||
|
// invalid state
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// end as in "least signifciant digit end"
|
||||||
|
unsigned int end = 0;
|
||||||
|
// start as in "most significant digit start"
|
||||||
|
unsigned int start = digits - 1;
|
||||||
|
unsigned long long temp, temp2, temp3;
|
||||||
|
while (end < start) {
|
||||||
|
// get end value
|
||||||
|
temp = n;
|
||||||
|
temp2 = 0;
|
||||||
|
while (temp2 < end) {
|
||||||
|
++temp2;
|
||||||
|
temp /= 10;
|
||||||
|
}
|
||||||
|
temp %= 10;
|
||||||
|
|
||||||
|
// get start value
|
||||||
|
temp2 = n;
|
||||||
|
temp3 = 0;
|
||||||
|
while (temp3 < start) {
|
||||||
|
++temp3;
|
||||||
|
temp2 /= 10;
|
||||||
|
}
|
||||||
|
temp2 %= 10;
|
||||||
|
|
||||||
|
// compare
|
||||||
|
if (temp != temp2) {
|
||||||
|
// mismatch, we now know it's not a palindrome
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// matches, cannot yet prove it is a palindrome until convergence
|
||||||
|
++end;
|
||||||
|
--start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no mismatches, at this point it has to be a palindrome
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long PGenerator_Next(PGeneratorState *state) {
|
||||||
|
do {
|
||||||
|
++state->current;
|
||||||
|
} while(!PGeneratorInternal_IsPalindrome(state->current));
|
||||||
|
return state->current;
|
||||||
|
}
|
11
c_impl/src/palindrome_generator.h
Normal file
11
c_impl/src/palindrome_generator.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef SUM_OF_RECIPROCALS_OF_PALINDROMES_PALINDROME_GENERATOR_H_
|
||||||
|
#define SUM_OF_RECIPROCALS_OF_PALINDROMES_PALINDROME_GENERATOR_H_
|
||||||
|
|
||||||
|
typedef struct PGeneratorState {
|
||||||
|
unsigned long long current;
|
||||||
|
} PGeneratorState;
|
||||||
|
|
||||||
|
PGeneratorState PGenerator_Init();
|
||||||
|
unsigned long long PGenerator_Next(PGeneratorState *state);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue