diff options
| -rw-r--r-- | challenge-001/paulo-custodio/test.pl | 4 | ||||
| -rw-r--r-- | challenge-024/paulo-custodio/c/ch-2.c | 294 | ||||
| -rw-r--r-- | challenge-024/paulo-custodio/perl/ch-2.pl | 3 | ||||
| -rw-r--r-- | challenge-024/paulo-custodio/python/ch-2.py | 5 | ||||
| -rw-r--r-- | challenge-024/paulo-custodio/t/test-2.yaml | 28 | ||||
| -rw-r--r-- | challenge-214/paulo-custodio/Makefile | 2 | ||||
| -rw-r--r-- | challenge-214/paulo-custodio/perl/ch-1.pl | 95 | ||||
| -rw-r--r-- | challenge-214/paulo-custodio/perl/ch-2.pl | 74 | ||||
| -rw-r--r-- | challenge-214/paulo-custodio/t/test-1.yaml | 20 | ||||
| -rw-r--r-- | challenge-214/paulo-custodio/t/test-2.yaml | 20 | ||||
| -rw-r--r-- | challenge-215/paulo-custodio/Makefile | 2 | ||||
| -rw-r--r-- | challenge-215/paulo-custodio/perl/ch-1.pl | 47 | ||||
| -rw-r--r-- | challenge-215/paulo-custodio/perl/ch-2.pl | 53 | ||||
| -rw-r--r-- | challenge-215/paulo-custodio/t/test-1.yaml | 15 | ||||
| -rw-r--r-- | challenge-215/paulo-custodio/t/test-2.yaml | 15 |
15 files changed, 659 insertions, 18 deletions
diff --git a/challenge-001/paulo-custodio/test.pl b/challenge-001/paulo-custodio/test.pl index e05049e9fd..132d8f52be 100644 --- a/challenge-001/paulo-custodio/test.pl +++ b/challenge-001/paulo-custodio/test.pl @@ -148,11 +148,11 @@ sub build { return "python3 ../../challenge-001/paulo-custodio/brainfuck.py $prog_wo_ext.bf"; } if (/^c$/) { - run("gcc $prog -o $prog_wo_ext -lm -lmpfr -lgmp") if (!-f $exe || -M $exe > -M $prog); + run("gcc $prog -o $prog_wo_ext -lm -lmpfr -lgmp -lsqlite3") if (!-f $exe || -M $exe > -M $prog); return $exe; } if (/^cpp$/) { - run("g++ $prog -o $prog_wo_ext -lmpfr -lgmpxx -lgmp") if (!-f $exe || -M $exe > -M $prog); + run("g++ $prog -o $prog_wo_ext -lmpfr -lgmpxx -lgmp -lsqlite3") if (!-f $exe || -M $exe > -M $prog); return $exe; } if (/^d$/) { diff --git a/challenge-024/paulo-custodio/c/ch-2.c b/challenge-024/paulo-custodio/c/ch-2.c new file mode 100644 index 0000000000..e3424eec6b --- /dev/null +++ b/challenge-024/paulo-custodio/c/ch-2.c @@ -0,0 +1,294 @@ +/* +Challenge 024 + +Task #2 +Create a script to implement full text search functionality using Inverted +Index. According to wikipedia: + +In computer science, an inverted index (also referred to as a postings file +or inverted file) is a database index storing a mapping from content, such as +words or numbers, to its locations in a table, or in a document or a set of +documents (named in contrast to a forward index, which maps from documents to +content). The purpose of an inverted index is to allow fast full-text +searches, at a cost of increased processing when a document is added to the +database. +*/ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <sys/stat.h> +#include <sqlite3.h> + +#define DATABASE "index.db3" +#define SEPARATORS " \t\r\n\v\f!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~" + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory\n", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +bool file_exists(const char *filename) { + struct stat buffer; + return (stat(filename, &buffer) == 0); +} + +void basename(char* filename) { + char* p = filename + strlen(filename); + while (p > filename && p[-1] != '/' && p[-1] != '\\' && p[-1] != '.') + p--; + if (p > filename && p[-1] == '.') + p[-1] = '\0'; +} + +char* strtolower(char* str) { + for (char* p = str; *p; p++) + *p = tolower(*p); + return str; +} + +void check_error(sqlite3* db, int rc) { + if (rc != SQLITE_OK) { + fprintf(stderr, "Database error: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + exit(EXIT_FAILURE); + } +} + +void check_error_step(sqlite3* db, int step) { + if (step != SQLITE_DONE) { + fprintf(stderr, "Database error: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + exit(EXIT_FAILURE); + } +} + +int callback(void *NotUsed, int argc, char **argv, char **azColName) { + for(int i = 0; i < argc; i++) { + printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); + } + printf("\n"); + return 0; +} + +sqlite3* open_database() { + sqlite3 *db; + int rc = sqlite3_open(DATABASE, &db); + check_error(db, rc); + return db; +} + +void close_database(sqlite3* db) { + sqlite3_close(db); +} + +void create_database() { + if (file_exists(DATABASE)) + return; + + sqlite3 *db = open_database(); + char *zErrMsg = NULL; + + const char* sql = + "CREATE TABLE words (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "word TEXT UNIQUE);" + "CREATE TABLE documents (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "title TEXT UNIQUE); " + "CREATE TABLE found (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "document_id INTEGER, " + "word_id INTEGER); " + "CREATE UNIQUE INDEX found_index ON found(document_id, word_id); "; + + int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); + if (rc != SQLITE_OK) { + fprintf(stderr, "SQL error: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + sqlite3_close(db); + return; + } + + close_database(db); +} + +int get_or_add_document_id(sqlite3* db, const char* title) { + bool found = false; + int id = -1; + + const char* sql = "SELECT id FROM documents WHERE title = ?;"; + sqlite3_stmt* stmt; + int rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + check_error(db, rc); + sqlite3_bind_text(stmt, 1, title, strlen(title), NULL); + int step = sqlite3_step(stmt); + if (step == SQLITE_ROW) { + id = sqlite3_column_int(stmt, 0); + found = true; + } + sqlite3_finalize(stmt); + + if (found) + return id; + + sql = "INSERT INTO documents(title) VALUES(?);"; + rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + check_error(db, rc); + sqlite3_bind_text(stmt, 1, title, strlen(title), NULL); + step = sqlite3_step(stmt); + check_error_step(db, step); + sqlite3_finalize(stmt); + + return sqlite3_last_insert_rowid(db); +} + +int get_or_add_word_id(sqlite3* db, const char* word) { + bool found = false; + int id = -1; + + const char* sql = "SELECT id FROM words WHERE word = ?;"; + sqlite3_stmt* stmt; + int rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + check_error(db, rc); + sqlite3_bind_text(stmt, 1, word, strlen(word), NULL); + int step = sqlite3_step(stmt); + if (step == SQLITE_ROW) { + id = sqlite3_column_int(stmt, 0); + found = true; + } + sqlite3_finalize(stmt); + + if (found) + return id; + + sql = "INSERT INTO words(word) VALUES(?);"; + rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + check_error(db, rc); + sqlite3_bind_text(stmt, 1, word, strlen(word), NULL); + step = sqlite3_step(stmt); + check_error_step(db, step); + sqlite3_finalize(stmt); + + return sqlite3_last_insert_rowid(db); +} + +int add_found(sqlite3* db, int document_id, int word_id) { + bool found = false; + int id = -1; + + const char* sql = "SELECT id FROM found " + "WHERE document_id = ? AND word_id = ?;"; + sqlite3_stmt* stmt; + int rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + check_error(db, rc); + sqlite3_bind_int(stmt, 1, document_id); + sqlite3_bind_int(stmt, 2, word_id); + int step = sqlite3_step(stmt); + if (step == SQLITE_ROW) { + id = sqlite3_column_int(stmt, 0); + found = true; + } + sqlite3_finalize(stmt); + + if (found) + return id; + + sql = "INSERT INTO found(document_id, word_id) VALUES(?, ?);"; + rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + check_error(db, rc); + sqlite3_bind_int(stmt, 1, document_id); + sqlite3_bind_int(stmt, 2, word_id); + step = sqlite3_step(stmt); + check_error_step(db, step); + sqlite3_finalize(stmt); + + return sqlite3_last_insert_rowid(db); +} + +void add_document(const char* filename) { + sqlite3* db = open_database(); + + // title + char* title = check_mem(strdup(filename)); + basename(title); + + // document id + int document_id = get_or_add_document_id(db, title); + + // read document + FILE* fp = fopen(filename, "r"); + if (fp == NULL) { + perror(filename); + close_database(db); + free(title); + exit(EXIT_FAILURE); + } + + char line[BUFSIZ]; + while (fgets(line, sizeof(line), fp) != NULL) { + char* word = strtok(line, SEPARATORS); + while (word != NULL) { + strtolower(word); + int word_id = get_or_add_word_id(db, word); + add_found(db, document_id, word_id); + word = strtok(NULL, SEPARATORS); + } + } + + printf("Indexed %s\n", title); + + fclose(fp); + close_database(db); + free(title); +} + +void search_documents(const char* word) { + sqlite3* db = open_database(); + + char* lcword = strtolower(check_mem(strdup(word))); + + const char* sql = "SELECT word, title " + "FROM documents, words, found " + "WHERE word = ? " + "AND found.document_id = documents.id " + "AND found.word_id = words.id " + "ORDER BY title;"; + sqlite3_stmt* stmt; + int rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + check_error(db, rc); + sqlite3_bind_text(stmt, 1, lcword, strlen(lcword), NULL); + int step; + while ((step = sqlite3_step(stmt)) == SQLITE_ROW) { + printf("%s %s\n", + sqlite3_column_text(stmt, 0), + sqlite3_column_text(stmt, 1)); + } + sqlite3_finalize(stmt); + + close_database(db); + free(lcword); +} + +int usage(void) { + fputs("usage: ch-2 add|search file|word\n", stderr); + return EXIT_FAILURE; +} + +int main(int argc, char* argv[]) { + if (argc != 3) + return usage(); + + create_database(); + if (strcmp(argv[1], "add") == 0) + add_document(argv[2]); + else if (strcmp(argv[1], "search") == 0) + search_documents(argv[2]); + else + return usage(); +} diff --git a/challenge-024/paulo-custodio/perl/ch-2.pl b/challenge-024/paulo-custodio/perl/ch-2.pl index 2d74437c97..bd938b5a74 100644 --- a/challenge-024/paulo-custodio/perl/ch-2.pl +++ b/challenge-024/paulo-custodio/perl/ch-2.pl @@ -41,6 +41,7 @@ CREATE TABLE found ( document_id INTEGER, word_id INTEGER ); +CREATE UNIQUE INDEX found_index ON found(document_id, word_id); END close($p) or die "sqlite3 failed"; } @@ -64,7 +65,7 @@ sub add_doc { my($doc) = @_; # get title - my $title = path($doc)->basename; + (my $title = path($doc)->basename) =~ s/\.\w+$//; # connect to index database my $dbh = DBI->connect("dbi:SQLite:dbname=".DBFILE,"","", diff --git a/challenge-024/paulo-custodio/python/ch-2.py b/challenge-024/paulo-custodio/python/ch-2.py index 7b3aff407a..6f4ab47bb9 100644 --- a/challenge-024/paulo-custodio/python/ch-2.py +++ b/challenge-024/paulo-custodio/python/ch-2.py @@ -47,6 +47,9 @@ def create_database(): word_id INTEGER ); ''') + cur.execute(''' + CREATE UNIQUE INDEX found_index ON found(document_id, word_id); + ''') con.commit() con.close() @@ -94,7 +97,7 @@ def add_found(con, document_id, word_id): def add_doc(file): con = sqlite3.connect(DBFILE) - title = os.path.basename(file) + title = re.sub(r"\.\w+$", "", os.path.basename(file)) document_id = get_document_id(con, title) # read document diff --git a/challenge-024/paulo-custodio/t/test-2.yaml b/challenge-024/paulo-custodio/t/test-2.yaml index 1f15630cb9..7df1a09659 100644 --- a/challenge-024/paulo-custodio/t/test-2.yaml +++ b/challenge-024/paulo-custodio/t/test-2.yaml @@ -1,52 +1,52 @@ -- setup: +- setup: unlink('index.db3');1 cleanup: args: add 'The Cask of Amontillado.txt' input: output: | - Indexed The Cask of Amontillado.txt + Indexed The Cask of Amontillado - setup: cleanup: args: add 'The Fall of the House of Usher.txt' input: output: | - Indexed The Fall of the House of Usher.txt + Indexed The Fall of the House of Usher - setup: cleanup: args: add 'The Masque of the Red Death.txt' input: output: | - Indexed The Masque of the Red Death.txt + Indexed The Masque of the Red Death - setup: cleanup: args: add 'The Raven.txt' input: output: | - Indexed The Raven.txt + Indexed The Raven - setup: cleanup: args: search death input: output: | - death The Fall of the House of Usher.txt - death The Masque of the Red Death.txt - death The Raven.txt + death The Fall of the House of Usher + death The Masque of the Red Death + death The Raven - setup: cleanup: args: search mystery input: output: | - mystery The Fall of the House of Usher.txt - mystery The Raven.txt + mystery The Fall of the House of Usher + mystery The Raven - setup: cleanup: args: search revenge input: output: | - revenge The Cask of Amontillado.txt + revenge The Cask of Amontillado - setup: - cleanup: unlink('index.db3') + cleanup: unlink('index.db3');1 args: search imagination input: output: | - imagination The Fall of the House of Usher.txt - imagination The Raven.txt + imagination The Fall of the House of Usher + imagination The Raven diff --git a/challenge-214/paulo-custodio/Makefile b/challenge-214/paulo-custodio/Makefile new file mode 100644 index 0000000000..c3c762d746 --- /dev/null +++ b/challenge-214/paulo-custodio/Makefile @@ -0,0 +1,2 @@ +all: + perl ../../challenge-001/paulo-custodio/test.pl diff --git a/challenge-214/paulo-custodio/perl/ch-1.pl b/challenge-214/paulo-custodio/perl/ch-1.pl new file mode 100644 index 0000000000..0296e952f1 --- /dev/null +++ b/challenge-214/paulo-custodio/perl/ch-1.pl @@ -0,0 +1,95 @@ +#!/usr/bin/perl + +# Challenge 214 +# +# Task 1: Rank Score +# Submitted by: Mohammad S Anwar +# +# You are given a list of scores (>=1). +# +# Write a script to rank each score in descending order. First three will get +# medals i.e. G (Gold), S (Silver) and B (Bronze). Rest will just get the +# ranking number. +# +# Using the standard model of giving equal scores equal rank, then +# advancing that number of ranks. +# +# +# Example 1 +# +# Input: @scores = (1,2,4,3,5) +# Output: (5,4,S,B,G) +# +# Score 1 is the 5th rank. +# Score 2 is the 4th rank. +# Score 4 is the 2nd rank i.e. Silver (S). +# Score 3 is the 3rd rank i.e. Bronze (B). +# Score 5 is the 1st rank i.e. Gold (G). +# +# Example 2 +# +# Input: @scores = (8,5,6,7,4) +# Output: (G,4,B,S,5) +# +# Score 8 is the 1st rank i.e. Gold (G). +# Score 4 is the 4th rank. +# Score 6 is the 3rd rank i.e. Bronze (B). +# Score 7 is the 2nd rank i.e. Silver (S). +# Score 4 is the 5th rank. +# +# Example 3 +# +# Input: @list = (3,5,4,2) +# Output: (B,G,S,4) +# +# Example 4 +# +# Input: @scores = (2,5,2,1,7,5,1) +# Output: (4,S,4,6,G,S,6) + +use Modern::Perl; + +# in: list of numbers +# out: list of items with the same value reverse-ordered by value +# each item is [index, value] +sub rank_values { + my(@list) = @_; + my @sorted = reverse sort {$a->[1] <=> $b->[1]} + map {[$_, $list[$_]]} 0..$#list; + my @output; + while (@sorted) { + my @head; + my $first_value = $sorted[0][1]; + while (@sorted && $sorted[0][1] == $first_value) { + push @head, shift @sorted; + } + push @output, \@head; + } + return @output; +} + +# in: list of numbers +# out: corresponding list of ranking +sub standard_ranking { + my(@list) = @_; + my @ranked = rank_values(@list); + my @ranks; + my $rank = 1; + while (@ranked) { + my @head = @{shift @ranked}; + for (@head) { + $ranks[$_->[0]] = $rank; + } + $rank += @head; + } + + for (@ranks) { + s/^1$/G/; + s/^2$/S/; + s/^3$/B/; + } + + return @ranks; +} + +say join(" ", standard_ranking(@ARGV)); diff --git a/challenge-214/paulo-custodio/perl/ch-2.pl b/challenge-214/paulo-custodio/perl/ch-2.pl new file mode 100644 index 0000000000..29c12ad197 --- /dev/null +++ b/challenge-214/paulo-custodio/perl/ch-2.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl + +# Challenge 214 +# +# Task 2: Collect Points +# Submitted by: Mohammad S Anwar +# +# You are given a list of numbers. +# +# You will perform a series of removal operations. For each operation, you +# remove from the list N (one or more) equal and consecutive numbers, and +# add to your score N × N. +# +# Determine the maximum possible score. +# Example 1: +# +# Input: @numbers = (2,4,3,3,3,4,5,4,2) +# Output: 23 +# +# We see three 3's next to each other so let us remove that first and +# collect 3 x 3 points. +# So now the list is (2,4,4,5,4,2). +# Let us now remove 5 so that all 4's can be next to each other and +# collect 1 x 1 point. +# So now the list is (2,4,4,4,2). +# Time to remove three 4's and collect 3 x 3 points. +# Now the list is (2,2). +# Finally remove both 2's and collect 2 x 2 points. +# So the total points collected is 9 + 1 + 9 + 4 => 23. +# +# Example 2: +# +# Input: @numbers = (1,2,2,2,2,1) +# Output: 20 +# +# Remove four 2's first and collect 4 x 4 points. +# Now the list is (1,1). +# Finally remove the two 1's and collect 2 x 2 points. +# So the total points collected is 16 + 4 => 20. +# +# Example 3: +# +# Input: @numbers = (1) +# Output: 1 +# +# Example 4: +# +# Input: @numbers = (2,2,2,1,1,2,2,2) +# Output: 40 +# +# Remove two 1's = 2 x 2 points. +# Now the list is (2,2,2,2,2,2). +# Then reomove six 2's = 6 x 6 points. + +use Modern::Perl; + +sub remove_numbers { + my(@in) = @_; + return scalar(@in) if @in < 2; + my $best_score = 0; + for (my $s = 0; $s < @in; $s++) { + my $e = $s; + while ($e < @in && $in[$s]==$in[$e]) { + $e++; + } + my @new_list = (@in[0..$s-1], @in[$e..$#in]); + my $score = ($e-$s)*($e-$s) + remove_numbers(@new_list); + $best_score = $score if $best_score < $score; + $s = $e-1; + } + return $best_score; +} + +say remove_numbers(@ARGV); diff --git a/challenge-214/paulo-custodio/t/test-1.yaml b/challenge-214/paulo-custodio/t/test-1.yaml new file mode 100644 index 0000000000..a4e13cd4ac --- /dev/null +++ b/challenge-214/paulo-custodio/t/test-1.yaml @@ -0,0 +1,20 @@ +- setup: + cleanup: + args: 1 2 4 3 5 + input: + output: 5 4 S B G +- setup: + cleanup: + args: 8 5 6 7 4 + input: + output: G 4 B S 5 +- setup: + cleanup: + args: 3 5 4 2 + input: + output: B G S 4 +- setup: + cleanup: + args: 2 5 2 1 7 5 1 + input: + output: 4 S 4 6 G S 6 diff --git a/challenge-214/paulo-custodio/t/test-2.yaml b/challenge-214/paulo-custodio/t/test-2.yaml new file mode 100644 index 0000000000..104f6ef58c --- /dev/null +++ b/challenge-214/paulo-custodio/t/test-2.yaml @@ -0,0 +1,20 @@ +- setup: + cleanup: + args: 2 4 3 3 3 4 5 4 2 + input: + output: 23 +- setup: + cleanup: + args: 1 2 2 2 2 1 + input: + output: 20 +- setup: + cleanup: + args: 1 + input: + output: 1 +- setup: + cleanup: + args: 2 2 2 1 1 2 2 2 + input: + output: 40 diff --git a/challenge-215/paulo-custodio/Makefile b/challenge-215/paulo-custodio/Makefile new file mode 100644 index 0000000000..c3c762d746 --- /dev/null +++ b/challenge-215/paulo-custodio/Makefile @@ -0,0 +1,2 @@ +all: + perl ../../challenge-001/paulo-custodio/test.pl diff --git a/challenge-215/paulo-custodio/perl/ch-1.pl b/challenge-215/paulo-custodio/perl/ch-1.pl new file mode 100644 index 0000000000..04e13da339 --- /dev/null +++ b/challenge-215/paulo-custodio/perl/ch-1.pl @@ -0,0 +1,47 @@ +#!/usr/bin/perl + +# Challenge 215 +# +# Task 1: Odd one Out +# Submitted by: Mohammad S Anwar +# +# You are given a list of words (alphabetic characters only) of same size. +# +# Write a script to remove all words not sorted alphabetically and print +# the number of words in the list that are not alphabetically sorted. +# +# Example 1 +# +# Input: @words = ('abc', 'xyz', 'tsu') +# Output: 1 +# +# The words 'abc' and 'xyz' are sorted and can't be removed. +# The word 'tsu' is not sorted and hence can be removed. +# +# Example 2 +# +# Input: @words = ('rat', 'cab', 'dad') +# Output: 3 +# +# None of the words in the given list are sorted. +# Therefore all three needs to be removed. +# +# Example 3 +# +# Input: @words = ('x', 'y', 'z') +# Output: 0 + +use Modern::Perl; + +sub is_sorted { + my($str) = @_; + my $sorted = join '', sort {$a cmp $b} split //, $str; + return $str eq $sorted; +} + +sub odd_out { + my(@in) = @_; + return scalar(grep {!is_sorted($_)} @in); +} + +say odd_out(@ARGV); diff --git a/challenge-215/paulo-custodio/perl/ch-2.pl b/challenge-215/paulo-custodio/perl/ch-2.pl new file mode 100644 index 0000000000..9a55f27be1 --- /dev/null +++ b/challenge-215/paulo-custodio/perl/ch-2.pl @@ -0,0 +1,53 @@ +#!/usr/bin/perl + +# Challenge 215 +# +# Task 2: Number Placement +# Submitted by: Mohammad S Anwar +# +# You are given a list of numbers having just 0 and 1. You are also given +# placement count (>=1). +# +# Write a script to find out if it is possible to replace 0 with 1 in the +# given list. The only condition is that you can only replace when there +# is no 1 on either side. Print 1 if it is possible otherwise 0. +# Example 1: +# +# Input: @numbers = (1,0,0,0,1), $count = 1 +# Output: 1 +# +# You are asked to replace only one 0 as given count is 1. +# We can easily replace middle 0 in the list i.e. (1,0,1,0,1). +# +# Example 2: +# +# Input: @numbers = (1,0,0,0,1), $count = 2 +# Output: 0 +# +# You are asked to replace two 0's as given count is 2. +# It is impossible to replace two 0's. +# +# Example 3: +# +# Input: @numbers = (1,0,0,0,0,0,0,0,1), $count = 3 +# Output: 1 + +use Modern::Perl; + +sub can_place { + my($nums, $count) = @_; + my $str = join '', @$nums; + for (1 .. $count) { + if (!($str =~ s/000/010/)) { + return 0; + } + } + return 1; +} + +@ARGV==2 or die "usage: ch-2.pl 1,0,... n\n"; +my @nums = split /,/, shift; +my $count = shift; +say can_place(\@nums, $count); + + diff --git a/challenge-215/paulo-custodio/t/test-1.yaml b/challenge-215/paulo-custodio/t/test-1.yaml new file mode 100644 index 0000000000..6c78cec738 --- /dev/null +++ b/challenge-215/paulo-custodio/t/test-1.yaml @@ -0,0 +1,15 @@ +- setup: + cleanup: + args: abc xyz tsu + input: + output: 1 +- setup: + cleanup: + args: rat cab dad + input: + output: 3 +- setup: + cleanup: + args: x y z + input: + output: 0 diff --git a/challenge-215/paulo-custodio/t/test-2.yaml b/challenge-215/paulo-custodio/t/test-2.yaml new file mode 100644 index 0000000000..b3a794a3b1 --- /dev/null +++ b/challenge-215/paulo-custodio/t/test-2.yaml @@ -0,0 +1,15 @@ +- setup: + cleanup: + args: 1,0,0,0,1 1 + input: + output: 1 +- setup: + cleanup: + args: 1,0,0,0,1 2 + input: + output: 0 +- setup: + cleanup: + args: 1,0,0,0,0,0,0,0,1 3 + input: + output: 1 |
