aboutsummaryrefslogtreecommitdiff
path: root/challenge-014
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2023-04-03 20:35:14 +0100
committerPaulo Custodio <pauloscustodio@gmail.com>2023-04-03 20:35:14 +0100
commit0611f359262fc95a57321fda21748c9986bcd5e1 (patch)
treeebf6c3061e9e4e8e9091c135562bc75abbf72a31 /challenge-014
parented17a0bef83e3276a3949814dab37a8a51871041 (diff)
downloadperlweeklychallenge-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.c56
-rw-r--r--challenge-014/paulo-custodio/c/ch-2.c195
-rw-r--r--challenge-014/paulo-custodio/perl/ch-1.pl4
-rw-r--r--challenge-014/paulo-custodio/perl/ch-2.pl5
-rw-r--r--challenge-014/paulo-custodio/python/ch-1.py2
-rw-r--r--challenge-014/paulo-custodio/python/ch-2.py2
-rw-r--r--challenge-014/paulo-custodio/t/test-1.yaml4
-rw-r--r--challenge-014/paulo-custodio/t/test-2.yaml21
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