diff options
| author | Paulo Custodio <pauloscustodio@gmail.com> | 2023-04-03 20:35:14 +0100 |
|---|---|---|
| committer | Paulo Custodio <pauloscustodio@gmail.com> | 2023-04-03 20:35:14 +0100 |
| commit | 0611f359262fc95a57321fda21748c9986bcd5e1 (patch) | |
| tree | ebf6c3061e9e4e8e9091c135562bc75abbf72a31 /challenge-014 | |
| parent | ed17a0bef83e3276a3949814dab37a8a51871041 (diff) | |
| download | perlweeklychallenge-club-0611f359262fc95a57321fda21748c9986bcd5e1.tar.gz perlweeklychallenge-club-0611f359262fc95a57321fda21748c9986bcd5e1.tar.bz2 perlweeklychallenge-club-0611f359262fc95a57321fda21748c9986bcd5e1.zip | |
Add C solution
Diffstat (limited to 'challenge-014')
| -rw-r--r-- | challenge-014/paulo-custodio/c/ch-1.c | 56 | ||||
| -rw-r--r-- | challenge-014/paulo-custodio/c/ch-2.c | 195 | ||||
| -rw-r--r-- | challenge-014/paulo-custodio/perl/ch-1.pl | 4 | ||||
| -rw-r--r-- | challenge-014/paulo-custodio/perl/ch-2.pl | 5 | ||||
| -rw-r--r-- | challenge-014/paulo-custodio/python/ch-1.py | 2 | ||||
| -rw-r--r-- | challenge-014/paulo-custodio/python/ch-2.py | 2 | ||||
| -rw-r--r-- | challenge-014/paulo-custodio/t/test-1.yaml | 4 | ||||
| -rw-r--r-- | challenge-014/paulo-custodio/t/test-2.yaml | 21 |
8 files changed, 266 insertions, 23 deletions
diff --git a/challenge-014/paulo-custodio/c/ch-1.c b/challenge-014/paulo-custodio/c/ch-1.c new file mode 100644 index 0000000000..32796436e3 --- /dev/null +++ b/challenge-014/paulo-custodio/c/ch-1.c @@ -0,0 +1,56 @@ +/* +Challenge 014 + +Challenge #1 +Write a script to generate Van Eck’s sequence starts with 0. For more +information, please check out wikipedia page. This challenge was proposed by +team member Andrezgz. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +int* van_eck_seq(int N) { + int* nums = check_mem(malloc(N * sizeof(int))); + nums[0] = nums[1] = 0; + for (int i = 2; i < N; i++) { + bool found = false; + for (int m = i-2; !found && m >= 0; m--) { + if (nums[m] == nums[i-1]) { + nums[i] = i-1-m; + found = true; + } + } + if (!found) + nums[i] = 0; + } + return nums; +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + fputs("usage: ch-1 N\n", stderr); + return EXIT_FAILURE; + } + + int N = atoi(argv[1]); + int* nums = van_eck_seq(N); + + const char* sep = ""; + for (int i = 0; i < N; i++) { + printf("%s%d", sep, nums[i]); + sep = ", "; + } + printf("\n"); + + free(nums); +} diff --git a/challenge-014/paulo-custodio/c/ch-2.c b/challenge-014/paulo-custodio/c/ch-2.c new file mode 100644 index 0000000000..ed96667a1e --- /dev/null +++ b/challenge-014/paulo-custodio/c/ch-2.c @@ -0,0 +1,195 @@ +/* +Challenge 014 + +Challenge #2 +Using only the official postal (2-letter) abbreviations for the 50 U.S. +states, write a script to find the longest English word you can spell? Here +is the list of U.S. states abbreviations as per wikipedia page. This challenge +was proposed by team member Neil Bowers. + +For example, +Pennsylvania + Connecticut = PACT +Wisconsin + North Dakota = WIND +Maine + Alabama = MEAL +California + Louisiana + Massachusetts + Rhode Island = Calamari +*/ + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define LU_IDX(a,b) (((a)-'A')*26 + ((b)-'A')) + +struct us_states { + const char* key; + const char* name; +}; + +struct us_states lut_us_states[] = { + {"AL", "Alabama"}, + {"AK", "Alaska"}, + {"AZ", "Arizona"}, + {"AR", "Arkansas"}, + {"CA", "California"}, + {"CO", "Colorado"}, + {"CT", "Connecticut"}, + {"DE", "Delaware"}, + {"FL", "Florida"}, + {"GA", "Georgia"}, + {"HI", "Hawaii"}, + {"ID", "Idaho"}, + {"IL", "Illinois"}, + {"IN", "Indiana"}, + {"IA", "Iowa"}, + {"KS", "Kansas"}, + {"KY", "Kentucky"}, + {"LA", "Louisiana"}, + {"ME", "Maine"}, + {"MD", "Maryland"}, + {"MA", "Massachusetts"}, + {"MI", "Michigan"}, + {"MN", "Minnesota"}, + {"MS", "Mississippi"}, + {"MO", "Missouri"}, + {"MT", "Montana"}, + { "NE", "Nebraska" }, + { "NV", "Nevada" }, + { "NH", "New Hampshire" }, + { "NJ", "New Jersey" }, + { "NM", "New Mexico" }, + { "NY", "New York" }, + { "NC", "North Carolina" }, + { "ND", "North Dakota" }, + { "OH", "Ohio" }, + { "OK", "Oklahoma" }, + { "OR", "Oregon" }, + { "PA", "Pennsylvania" }, + { "RI", "Rhode Island" }, + { "SC", "South Carolina" }, + { "SD", "South Dakota" }, + { "TN", "Tennessee" }, + { "TX", "Texas" }, + { "UT", "Utah" }, + { "VT", "Vermont" }, + { "VA", "Virginia" }, + { "WA", "Washington" }, + { "WV", "West Virginia" }, + { "WI", "Wisconsin" }, + { "WY", "Wyoming" }, + { NULL, NULL }, +}; + +const char* lut_states[LU_IDX('Z', 'Z') + 1]; + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +void build_lookup_table() { + for (struct us_states* p = lut_us_states; p->key != NULL; p++) { + int idx = LU_IDX(toupper(p->key[0]), toupper(p->key[1])); + assert(lut_states[idx] == NULL); + lut_states[idx] = p->name; + } +} + +const char* lookup_state(const char* str) { + if (!isalpha(str[0]) || !isalpha(str[1])) + return NULL; + else { + int idx = LU_IDX(toupper(str[0]), toupper(str[1])); + return lut_states[idx]; + } +} + +char* state_words(const char* word) { + char text[BUFSIZ]; + + if (strlen(word) % 2 != 0) // odd number of chars + return NULL; + + text[0] = '\0'; + const char* sep = ""; + for (int i = 0; i < strlen(word); i += 2) { + const char* state = lookup_state(word + i); + if (state == NULL) + return NULL; // no state found + sprintf(text + strlen(text), "%s%s", sep, state); + sep = " + "; + } + + return check_mem(strdup(text)); +} + +char* chomp(char* str) { + char* p = str + strlen(str) - 1; + while (p >= str && isspace(*p)) + *p = '\0'; + return str; +} + +char** search_words(const char* dictionary) { + FILE* fp = fopen(dictionary, "r"); + if (fp == NULL) { + perror(dictionary); + exit(EXIT_FAILURE); + } + + // array to return list + int N = 0; + char** words = check_mem(malloc((N + 1) * sizeof(char*))); + words[0] = NULL; + int curlen = 0; + + char word[BUFSIZ]; + while (fgets(word, sizeof(word), fp)) { + chomp(word); + char* text = state_words(word); + if (text != NULL) { + if (strlen(word) > curlen) { + for (int i = 0; i < N; i++) + free(words[i]); + N = 1; + words = check_mem(realloc(words, (N + 1) * sizeof(char*))); + words[0] = check_mem(strdup(word)); + words[1] = NULL; + curlen = strlen(word); + } + else if (strlen(word) == curlen) { + N++; + words = check_mem(realloc(words, (N + 1) * sizeof(char*))); + words[N - 1] = check_mem(strdup(word)); + words[N] = NULL; + } + free(text); + } + } + + fclose(fp); + + return words; +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + fputs("usage: ch-2 dictionary.txt\n", stderr); + return EXIT_FAILURE; + } + + build_lookup_table(); + + char** words = search_words(argv[1]); + for (char** p = words; *p != NULL; p++) { + char* text = state_words(*p); + printf("%s = %s\n", *p, text); + free(text); + } + + free(words); +} diff --git a/challenge-014/paulo-custodio/perl/ch-1.pl b/challenge-014/paulo-custodio/perl/ch-1.pl index ff7c2ea8d0..38c78011dc 100644 --- a/challenge-014/paulo-custodio/perl/ch-1.pl +++ b/challenge-014/paulo-custodio/perl/ch-1.pl @@ -30,9 +30,11 @@ sub van_eck_iter { }; } +@ARGV==1 or die "usage: ch-1.pl N\n"; +my $N = shift; my $iter = van_eck_iter(); my $sep = ""; -for (0..96) { +for (1..$N) { print $sep, $iter->(); $sep = ", "; } diff --git a/challenge-014/paulo-custodio/perl/ch-2.pl b/challenge-014/paulo-custodio/perl/ch-2.pl index 6549b608a1..3e5b8b16f8 100644 --- a/challenge-014/paulo-custodio/perl/ch-2.pl +++ b/challenge-014/paulo-custodio/perl/ch-2.pl @@ -74,8 +74,11 @@ my $codes = join("|", @codes); # regex to match any codes my $regex = qr/^($codes)+$/i; # regex to match word composed of codes # find all words that match, save longest ones +@ARGV==1 or die "usage: ch-2.pl dictionary.txt\n"; +my $words = shift; + my @longest; -open(my $fh, "<", "words.txt") or die "open words.txt: $!\n"; +open(my $fh, "<", $words) or die "open $words: $!\n"; while (<$fh>) { chomp; next unless /$regex/; # filter words that match state codes diff --git a/challenge-014/paulo-custodio/python/ch-1.py b/challenge-014/paulo-custodio/python/ch-1.py index 6852909991..727c5b1529 100644 --- a/challenge-014/paulo-custodio/python/ch-1.py +++ b/challenge-014/paulo-custodio/python/ch-1.py @@ -35,6 +35,6 @@ for n in van_eck_iter(): output += sep + str(n) sep = ", " count += 1 - if count > 96: + if count >= 96: break print(output) diff --git a/challenge-014/paulo-custodio/python/ch-2.py b/challenge-014/paulo-custodio/python/ch-2.py index fd1890993e..03b7edc5f0 100644 --- a/challenge-014/paulo-custodio/python/ch-2.py +++ b/challenge-014/paulo-custodio/python/ch-2.py @@ -114,6 +114,6 @@ def word_to_states(word): states.append(us_states[cc]) return " + ".join(states) -words = longest_words(words_like_states(read_words(read_file("words.txt")))) +words = longest_words(words_like_states(read_words(read_file(sys.argv[1])))) for word in words: print(word+" = "+word_to_states(word)) diff --git a/challenge-014/paulo-custodio/t/test-1.yaml b/challenge-014/paulo-custodio/t/test-1.yaml index ebf698340d..7c15f5075f 100644 --- a/challenge-014/paulo-custodio/t/test-1.yaml +++ b/challenge-014/paulo-custodio/t/test-1.yaml @@ -1,5 +1,5 @@ - setup: cleanup: - args: 2019 + args: 96 input: - output: 0, 0, 1, 0, 2, 0, 2, 2, 1, 6, 0, 5, 0, 2, 6, 5, 4, 0, 5, 3, 0, 3, 2, 9, 0, 4, 9, 3, 6, 14, 0, 6, 3, 5, 15, 0, 5, 3, 5, 2, 17, 0, 6, 11, 0, 3, 8, 0, 3, 3, 1, 42, 0, 5, 15, 20, 0, 4, 32, 0, 3, 11, 18, 0, 4, 7, 0, 3, 7, 3, 2, 31, 0, 6, 31, 3, 6, 3, 2, 8, 33, 0, 9, 56, 0, 3, 8, 7, 19, 0, 5, 37, 0, 3, 8, 8, 1 + output: 0, 0, 1, 0, 2, 0, 2, 2, 1, 6, 0, 5, 0, 2, 6, 5, 4, 0, 5, 3, 0, 3, 2, 9, 0, 4, 9, 3, 6, 14, 0, 6, 3, 5, 15, 0, 5, 3, 5, 2, 17, 0, 6, 11, 0, 3, 8, 0, 3, 3, 1, 42, 0, 5, 15, 20, 0, 4, 32, 0, 3, 11, 18, 0, 4, 7, 0, 3, 7, 3, 2, 31, 0, 6, 31, 3, 6, 3, 2, 8, 33, 0, 9, 56, 0, 3, 8, 7, 19, 0, 5, 37, 0, 3, 8, 8 diff --git a/challenge-014/paulo-custodio/t/test-2.yaml b/challenge-014/paulo-custodio/t/test-2.yaml index c89ea9f41a..1b6246e24b 100644 --- a/challenge-014/paulo-custodio/t/test-2.yaml +++ b/challenge-014/paulo-custodio/t/test-2.yaml @@ -1,20 +1,7 @@ -- setup: 0==system("aspell -d en dump master | aspell -l en expand > words.txt") - cleanup: unlink("words.txt") - args: +- setup: + cleanup: + args: ../../data/dictionary.txt input: output: | - armorial = Arkansas + Missouri + Rhode Island + Alabama - calamine = California + Louisiana + Michigan + Nebraska - coalmine = Colorado + Alabama + Michigan + Nebraska - calamari = California + Louisiana + Massachusetts + Rhode Island - Concorde = Colorado + North Carolina + Oregon + Delaware - Ganymede = Georgia + New York + Maine + Delaware - landmine = Louisiana + North Dakota + Michigan + Nebraska - melamine = Maine + Louisiana + Michigan + Nebraska - moorland = Missouri + Oregon + Louisiana + North Dakota - malarial = Massachusetts + Louisiana + Rhode Island + Alabama - memorial = Maine + Missouri + Rhode Island + Alabama mainland = Massachusetts + Indiana + Louisiana + North Dakota - Mandarin = Massachusetts + North Dakota + Arkansas + Indiana - mandarin = Massachusetts + North Dakota + Arkansas + Indiana - mescalin = Maine + South Carolina + Alabama + Indiana + memorial = Maine + Missouri + Rhode Island + Alabama |
