aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-02-05 07:31:19 +0000
committerGitHub <noreply@github.com>2021-02-05 07:31:19 +0000
commit67fca6c791bea102aed6dedb587b5bfc6a9557dc (patch)
treedf9bb4c065f2394e66d5ec56ef8de74b33613186
parent189f15dd2d9dd72420b721b2a7cbe55268aa494e (diff)
parenta91e07565f5d43ac116a92cd16385a0c272847b3 (diff)
downloadperlweeklychallenge-club-67fca6c791bea102aed6dedb587b5bfc6a9557dc.tar.gz
perlweeklychallenge-club-67fca6c791bea102aed6dedb587b5bfc6a9557dc.tar.bz2
perlweeklychallenge-club-67fca6c791bea102aed6dedb587b5bfc6a9557dc.zip
Merge pull request #3456 from pauloscustodio/098
098
-rw-r--r--.gitignore2
-rw-r--r--challenge-003/paulo-custodio/lua/ch-1.lua2
-rw-r--r--challenge-003/paulo-custodio/lua/ch-2.lua4
-rw-r--r--challenge-097/paulo-custodio/lua/ch-1.lua2
-rw-r--r--challenge-098/paulo-custodio/ada/ch_1.adb86
-rw-r--r--challenge-098/paulo-custodio/ada/ch_2.adb100
-rw-r--r--challenge-098/paulo-custodio/awk/ch-1.awk38
-rw-r--r--challenge-098/paulo-custodio/awk/ch-2.awk92
-rw-r--r--challenge-098/paulo-custodio/basic/ch-1.bas66
-rw-r--r--challenge-098/paulo-custodio/basic/ch-2.bas89
-rw-r--r--challenge-098/paulo-custodio/c/ch-1.c90
-rw-r--r--challenge-098/paulo-custodio/c/ch-2.c102
-rw-r--r--challenge-098/paulo-custodio/cpp/ch-1.cpp76
-rw-r--r--challenge-098/paulo-custodio/cpp/ch-2.cpp69
-rw-r--r--challenge-098/paulo-custodio/forth/ch-1.fs95
-rw-r--r--challenge-098/paulo-custodio/forth/ch-2.fs140
-rw-r--r--challenge-098/paulo-custodio/lua/ch-1.lua43
-rw-r--r--challenge-098/paulo-custodio/lua/ch-2.lua76
-rw-r--r--challenge-098/paulo-custodio/perl/ch-1.pl36
-rw-r--r--challenge-098/paulo-custodio/perl/ch-2.pl67
-rw-r--r--challenge-098/paulo-custodio/python/ch-1.py29
-rw-r--r--challenge-098/paulo-custodio/python/ch-2.py64
-rw-r--r--challenge-098/paulo-custodio/t/test-1.yaml38
-rw-r--r--challenge-098/paulo-custodio/t/test-2.yaml55
-rwxr-xr-xchallenge-098/paulo-custodio/test.pl138
25 files changed, 1595 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index b6dca4e062..ab8c2f5f55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@
*~
*.class
*.exe
+*.o
+*.ali
# Rust languageoutput directory
target/
diff --git a/challenge-003/paulo-custodio/lua/ch-1.lua b/challenge-003/paulo-custodio/lua/ch-1.lua
index 525469191a..5c40f03256 100644
--- a/challenge-003/paulo-custodio/lua/ch-1.lua
+++ b/challenge-003/paulo-custodio/lua/ch-1.lua
@@ -16,7 +16,7 @@ seq5 = {1}
function next_hamming()
-- get the smallest of the queue heads
- n = math.min(seq2[1], seq3[1], seq5[1])
+ local n = math.min(seq2[1], seq3[1], seq5[1])
-- shift used multiples
if n == seq2[1] then table.remove(seq2, 1); end
diff --git a/challenge-003/paulo-custodio/lua/ch-2.lua b/challenge-003/paulo-custodio/lua/ch-2.lua
index d8c661014c..8853469774 100644
--- a/challenge-003/paulo-custodio/lua/ch-2.lua
+++ b/challenge-003/paulo-custodio/lua/ch-2.lua
@@ -10,7 +10,7 @@ information about Pascal Triangle, check this wikipedia page.
--]]
function draw_pascal(rows)
- data = {1}
+ local data = {1}
for row=1,rows do
-- print current row
for col=1,rows-row do io.write(" "); end
@@ -18,7 +18,7 @@ function draw_pascal(rows)
io.write("\n")
-- compute next row
- nxt = {1}
+ local nxt = {1}
for col=1,row-1 do
table.insert(nxt, data[col] + data[col+1])
end
diff --git a/challenge-097/paulo-custodio/lua/ch-1.lua b/challenge-097/paulo-custodio/lua/ch-1.lua
index 4bb62c085d..46c6b0f418 100644
--- a/challenge-097/paulo-custodio/lua/ch-1.lua
+++ b/challenge-097/paulo-custodio/lua/ch-1.lua
@@ -22,7 +22,7 @@ Ciphertext: QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD
--]]
function caesar(n, text)
- text = string.upper(text)
+ local text = string.upper(text)
local cipher = ""
for i=1, #text do
diff --git a/challenge-098/paulo-custodio/ada/ch_1.adb b/challenge-098/paulo-custodio/ada/ch_1.adb
new file mode 100644
index 0000000000..47c6decd43
--- /dev/null
+++ b/challenge-098/paulo-custodio/ada/ch_1.adb
@@ -0,0 +1,86 @@
+-- Challenge 098
+--
+-- TASK #1 › Read N-characters
+-- Submitted by: Mohammad S Anwar
+-- You are given file $FILE.
+--
+-- Create subroutine readN($FILE, $number) returns the first n-characters and
+-- moves the pointer to the (n+1)th character.
+--
+-- Example:
+-- Input: Suppose the file (input.txt) contains "1234567890"
+-- Output:
+-- print readN("input.txt", 4); # returns "1234"
+-- print readN("input.txt", 4); # returns "5678"
+-- print readN("input.txt", 4); # returns "90"
+
+
+with Ada.Text_IO; use Ada.Text_IO;
+with Ada.Command_Line;
+with Ada.Strings.Bounded;
+
+procedure ch_1 is
+ -- command line arguments
+ package CL renames Ada.Command_Line;
+
+ -- strings for filenames
+ package SB is new Ada.Strings.Bounded.Generic_Bounded_Length(Max => 100);
+ use SB;
+
+ -- maximum number of different files
+ Max_Files : constant := 100;
+
+ -- arrays of already seen files and their File_Type's
+ Filenames : array (1 .. Max_Files) of SB.Bounded_String;
+ File_IDs : array (1 .. Max_Files) of File_Type;
+ Last_ID : Integer := 0;
+
+ -- either open file and append to array, or return index if already open
+ function open_file(Filename : SB.Bounded_String)
+ return Integer is
+ begin
+ -- search already open file
+ for I in 1 .. Last_ID loop
+ if Filename = Filenames(I) then
+ return I;
+ end if;
+ end loop;
+
+ -- open new file
+ Last_ID := Last_ID + 1;
+ Filenames(Last_ID) := Filename;
+ Open(File_IDs(Last_ID), In_File, To_String(Filename));
+ return Last_ID;
+ end open_file;
+
+ -- read the next N chars from the given file
+ function readN(Filename : SB.Bounded_String; Number_Chars : Integer)
+ return SB.Bounded_String is
+ ID : Integer;
+ C : Character;
+ Text : SB.Bounded_String;
+ begin
+ ID := open_file(Filename);
+ for I in 1 .. Number_Chars loop
+ if not End_Of_File(File_IDs(ID)) then
+ Get(File_IDs(ID), C);
+ SB.Append(Text, C);
+ end if;
+ end loop;
+ return Text;
+ end readN;
+
+ -- local variables
+ Filename : SB.Bounded_String;
+ Number_Chars : Integer := 0;
+ I : Integer := 1;
+ Text : SB.Bounded_String;
+begin
+ while I+1 <= CL.Argument_Count loop
+ Filename := SB.To_Bounded_String(CL.Argument(I));
+ Number_Chars := Integer'Value(CL.Argument(I+1));
+ Text := readN(Filename, Number_Chars);
+ Put_Line(To_String(Text));
+ I := I + 2;
+ end loop;
+end ch_1;
diff --git a/challenge-098/paulo-custodio/ada/ch_2.adb b/challenge-098/paulo-custodio/ada/ch_2.adb
new file mode 100644
index 0000000000..7cf52f9fb0
--- /dev/null
+++ b/challenge-098/paulo-custodio/ada/ch_2.adb
@@ -0,0 +1,100 @@
+-- Challenge 098
+--
+-- TASK #2 › Search Insert Position
+-- Submitted by: Mohammad S Anwar
+-- You are given a sorted array of distinct integers @N and a target $N.
+--
+-- Write a script to return the index of the given target if found
+-- otherwise place the target in the sorted array and return the index.
+--
+-- Example 1:
+-- Input: @N = (1, 2, 3, 4) and $N = 3
+-- Output: 2 since the target 3 is in the array at the index 2.
+-- Example 2:
+-- Input: @N = (1, 3, 5, 7) and $N = 6
+-- Output: 3 since the target 6 is missing and should be placed at
+-- the index 3.
+-- Example 3:
+-- Input: @N = (12, 14, 16, 18) and $N = 10
+-- Output: 0 since the target 10 is missing and should be placed at
+-- the index 0.
+-- Example 4:
+-- Input: @N = (11, 13, 15, 17) and $N = 19
+-- Output: 4 since the target 19 is missing and should be placed at
+-- the index 4.
+
+with Ada.Text_IO; use Ada.Text_IO;
+with Ada.Command_Line;
+with Ada.Containers.Vectors;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+
+procedure ch_2 is
+ -- command line arguments
+ package CL renames Ada.Command_Line;
+
+ -- vector of integers
+ package IV is new Ada.Containers.Vectors
+ (Index_Type => Natural,
+ Element_Type => Integer);
+ use IV;
+
+ -- print a vector
+ procedure print_vector(V : Vector) is
+ begin
+ Put("(");
+ for I in V.First_Index .. V.Last_Index loop
+ if I /= V.First_Index then
+ Put(", ");
+ end if;
+ Put(Trim(Integer'Image(V(I)), Ada.Strings.Left));
+ end loop;
+ Put(")");
+ end print_vector;
+
+ -- search for index of element, insert in array if not found
+ function search_insert(V : in out Vector; N : Integer) return Integer is
+ B, T, M : Integer;
+ begin
+ B := V.First_Index;
+ T := V.Last_Index;
+ if T < B then -- vector empty
+ V.Append(N);
+ return 0;
+ elsif N < V(B) then -- before first
+ V.Prepend(N);
+ return 0;
+ elsif N > V(T) then -- after last
+ V.Append(N);
+ return V.Last_Index;
+ else -- do binary search
+ M := (T+B)/2;
+ while B+1<T loop
+ if N = V(M) then -- found
+ return M;
+ elsif N < V(M) then
+ T := M;
+ else
+ B := M;
+ end if;
+ M := (T+B)/2;
+ end loop;
+ V.Insert(M+1, N);
+ return M+1;
+ end if;
+ end search_insert;
+
+ -- variables
+ Nums : Vector;
+ I, N, Pos : Integer;
+begin
+ N := Integer'Value(CL.Argument(1));
+ I := 2;
+ while I <= CL.Argument_Count loop
+ Nums.Append(Integer'Value(CL.Argument(I)));
+ I := I + 1;
+ end loop;
+ Pos := search_insert(Nums, N);
+ Put_Line(Trim(Integer'Image(Pos), Ada.Strings.Left));
+ print_vector(Nums);
+ Put_Line("");
+end ch_2;
diff --git a/challenge-098/paulo-custodio/awk/ch-1.awk b/challenge-098/paulo-custodio/awk/ch-1.awk
new file mode 100644
index 0000000000..51d8f3a8f6
--- /dev/null
+++ b/challenge-098/paulo-custodio/awk/ch-1.awk
@@ -0,0 +1,38 @@
+#!/usr/bin/gawk
+
+# Challenge 098
+#
+# TASK #1 › Read N-characters
+# Submitted by: Mohammad S Anwar
+# You are given file $FILE.
+#
+# Create subroutine readN($FILE, $number) returns the first n-characters and
+# moves the pointer to the (n+1)th character.
+#
+# Example:
+# Input: Suppose the file (input.txt) contains "1234567890"
+# Output:
+# print readN("input.txt", 4); # returns "1234"
+# print readN("input.txt", 4); # returns "5678"
+# print readN("input.txt", 4); # returns "90"
+
+# read next N chars from file
+function readN(filename, read_len) {
+ skip_len = 0
+ if (read_files[filename]) {
+ skip_len = read_files[filename]
+ }
+ read_files[filename] = skip_len + read_len
+
+ dd = "dd if=" filename " status=none bs=1 skip=" skip_len " count=" read_len
+ dd | getline text
+ return text
+}
+
+BEGIN {
+ for (i = 1; i < ARGC - 1; i += 2) {
+ text = readN(ARGV[i], ARGV[i+1]);
+ print text
+ }
+ exit 0
+}
diff --git a/challenge-098/paulo-custodio/awk/ch-2.awk b/challenge-098/paulo-custodio/awk/ch-2.awk
new file mode 100644
index 0000000000..cbb40fd7dc
--- /dev/null
+++ b/challenge-098/paulo-custodio/awk/ch-2.awk
@@ -0,0 +1,92 @@
+#!/usr/bin/gawk
+
+# Challenge 098
+#
+# TASK #2 › Search Insert Position
+# Submitted by: Mohammad S Anwar
+# You are given a sorted array of distinct integers @N and a target $N.
+#
+# Write a script to return the index of the given target if found
+# otherwise place the target in the sorted array and return the index.
+#
+# Example 1:
+# Input: @N = (1, 2, 3, 4) and $N = 3
+# Output: 2 since the target 3 is in the array at the index 2.
+# Example 2:
+# Input: @N = (1, 3, 5, 7) and $N = 6
+# Output: 3 since the target 6 is missing and should be placed at
+# the index 3.
+# Example 3:
+# Input: @N = (12, 14, 16, 18) and $N = 10
+# Output: 0 since the target 10 is missing and should be placed at
+# the index 0.
+# Example 4:
+# Input: @N = (11, 13, 15, 17) and $N = 19
+# Output: 4 since the target 19 is missing and should be placed at
+# the index 4.
+
+# print contents of array (nums, nums_size)
+function print_array() {
+ sep = ""
+ printf "("
+ for (i=0; i<nums_size; i++) {
+ printf sep nums[i]
+ sep = ", "
+ }
+ print ")"
+}
+
+# insert an element in (nums, nums_size), shifting all other positions up
+function insert(p, n) {
+ nums_size++
+ for (i=nums_size-1; i>p; i--) {
+ nums[i] = nums[i-1]
+ }
+ nums[p] = n
+}
+
+# use bisect method to search for position
+function search_insert(n) {
+ if (nums_size == 0) { # input empty
+ nums[nums_size++] = n;
+ return 0;
+ }
+ else if (n < nums[0]) { # before first
+ insert(0, n)
+ return 0;
+ }
+ else if (n > nums[nums_size-1]) {# after last
+ nums[nums_size++] = n;
+ return nums_size-1;
+ }
+ else { # bisect
+ bot = 0; top = nums_size
+ mid = int((top + bot) / 2)
+ while (bot+1 < top) {
+ if (n == nums[mid])
+ return mid;
+ else if (n < nums[mid])
+ top = mid
+ else
+ bot = mid
+ mid = int((top + bot) / 2)
+ }
+
+ # not found, insert at mid+1
+ insert(mid+1, n)
+ return mid+1
+ }
+}
+
+BEGIN {
+ n = ARGV[1]
+ nums_size = 0 # nums[] size
+
+ for (i = 2; i < ARGC; i++) {
+ nums[nums_size++] = ARGV[i]
+ }
+ p = search_insert(n)
+ print p
+ print_array()
+ exit 0
+}
diff --git a/challenge-098/paulo-custodio/basic/ch-1.bas b/challenge-098/paulo-custodio/basic/ch-1.bas
new file mode 100644
index 0000000000..4aa064ad66
--- /dev/null
+++ b/challenge-098/paulo-custodio/basic/ch-1.bas
@@ -0,0 +1,66 @@
+' Challenge 098
+'
+' TASK #1 › Read N-characters
+' Submitted by: Mohammad S Anwar
+' You are given file $FILE.
+'
+' Create subroutine readN($FILE, $number) returns the first n-characters and
+' moves the pointer to the (n+1)th character.
+'
+' Example:
+' Input: Suppose the file (input.txt) contains "1234567890"
+' Output:
+' print readN("input.txt", 4); # returns "1234"
+' print readN("input.txt", 4); # returns "5678"
+' print readN("input.txt", 4); # returns "90"
+
+' store list of seen files
+type tFile
+ sName as string
+ nFile as integer
+end type
+
+dim shared aFiles() as tFile
+
+' return filenum of open file or open it if first time
+function next_file(sName as string) as integer
+ dim i as integer
+
+ for i=lbound(aFiles) to uBound(aFiles)
+ if aFiles(i).sName=sName then
+ next_file=aFiles(i).nFile
+ exit function
+ end if
+ next
+
+ i=ubound(aFiles)+1
+ redim preserve aFiles(i)
+ aFiles(i).sName=sName
+ aFiles(i).nFile=FreeFile
+ if open(sName for binary access read as #aFiles(i).nFile) <> 0 then
+ print "File not found:"; sName
+ end
+ end if
+
+ next_file=aFiles(i).nFile
+end function
+
+' read next N chars from file
+function readN(sName as string, nNum as integer) as string
+ dim nFile as integer, sText as string
+
+ nFile=next_file(sName)
+ sText=string(nNum,0) ' allocate nNum zeros
+ get #nFile, , sText ' read
+ sText=rtrim(sText) ' remove zeros if file ended short
+
+ readN=sText
+end function
+
+' main
+dim i as integer
+i=1
+do while command(i+1)<>""
+ print readN(command(i), val(command(i+1)))
+ i=i+2
+loop
diff --git a/challenge-098/paulo-custodio/basic/ch-2.bas b/challenge-098/paulo-custodio/basic/ch-2.bas
new file mode 100644
index 0000000000..4cc8a5717d
--- /dev/null
+++ b/challenge-098/paulo-custodio/basic/ch-2.bas
@@ -0,0 +1,89 @@
+' Challenge 098
+'
+' TASK #2 › Search Insert Position
+' Submitted by: Mohammad S Anwar
+' You are given a sorted array of distinct integers @N and a target $N.
+'
+' Write a script to return the index of the given target if found
+' otherwise place the target in the sorted array and return the index.
+'
+' Example 1:
+' Input: @N = (1, 2, 3, 4) and $N = 3
+' Output: 2 since the target 3 is in the array at the index 2.
+' Example 2:
+' Input: @N = (1, 3, 5, 7) and $N = 6
+' Output: 3 since the target 6 is missing and should be placed at
+' the index 3.
+' Example 3:
+' Input: @N = (12, 14, 16, 18) and $N = 10
+' Output: 0 since the target 10 is missing and should be placed at
+' the index 0.
+' Example 4:
+' Input: @N = (11, 13, 15, 17) and $N = 19
+' Output: 4 since the target 19 is missing and should be placed at
+' the index 4.
+
+' insert element in array at the given position
+sub insert(aN() as integer, nPos as integer, n as integer)
+ dim u as integer, i as integer
+ u=ubound(aN)
+ redim preserve aN(u+1)
+ if nPos>u then ' append
+ aN(u+1)=n
+ else ' shift all and insert
+ for i = u+1 to nPos step -1
+ aN(i)=aN(i-1)
+ next i
+ aN(nPos)=n
+ end if
+end sub
+
+' print list of numbers
+sub print_numbers(aN() as integer)
+ dim sep as string, i as integer
+ sep="("
+ for i=lbound(aN) to ubound(aN)
+ print sep;trim(str(aN(i)));
+ sep=", "
+ next i
+ print ")"
+end sub
+
+' search for index of element, insert in array if not found
+function search_insert(aN() as integer, n as integer) as integer
+ dim b as integer, t as integer, m as integer
+ b=lbound(aN): t=ubound(aN)
+ if t<b then ' empty
+ insert aN(), 0, n: search_insert=0
+ elseif n<aN(b) then ' before first
+ insert aN(), b, n: search_insert=b
+ elseif n>aN(t) then ' after last
+ insert aN(), t+1, n: search_insert=t+1
+ else
+ m=(t+b)/2
+ do while b+1<t ' bisect loop
+ if n=aN(m) then
+ search_insert=m: exit function
+ elseif n<aN(m) then
+ t=m
+ else
+ b=m
+ end if
+ m=(t+b)/2
+ loop
+ insert aN(), m+1, n: search_insert=m+1 ' not found, insert
+ end if
+end function
+
+' main
+dim aN() as integer, i as integer, n as integer
+n=val(command(1))
+i=2
+do while command(i)<>""
+ redim preserve aN(i-2)
+ aN(i-2)=val(command(i))
+ i=i+1
+loop
+
+print trim(str(search_insert(aN(), n)))
+print_numbers aN()
diff --git a/challenge-098/paulo-custodio/c/ch-1.c b/challenge-098/paulo-custodio/c/ch-1.c
new file mode 100644
index 0000000000..96f916d2eb
--- /dev/null
+++ b/challenge-098/paulo-custodio/c/ch-1.c
@@ -0,0 +1,90 @@
+/*
+Challenge 098
+
+TASK #1 › Read N-characters
+Submitted by: Mohammad S Anwar
+You are given file $FILE.
+
+Create subroutine readN($FILE, $number) returns the first n-characters and
+moves the pointer to the (n+1)th character.
+
+Example:
+Input: Suppose the file (input.txt) contains "1234567890"
+Output:
+ print readN("input.txt", 4); # returns "1234"
+ print readN("input.txt", 4); # returns "5678"
+ print readN("input.txt", 4); # returns "90"
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// store list of seen files
+typedef struct File {
+ char* filename;
+ FILE* fp;
+} File;
+
+File* files = NULL;
+int num_files = 0;
+
+// memory allocation
+void* check_mem(void* p) {
+ if (!p) {
+ fputs("Out of memory", stderr);
+ exit(EXIT_FAILURE);
+ }
+ return p;
+}
+
+// add a new file, return FILE*
+FILE* next_file(const char* filename) {
+ // find in already open files
+ for (int i = 0; i < num_files; i++) {
+ if (strcmp(filename, files[i].filename)==0)
+ return files[i].fp; // found, return
+ }
+
+ // extend array and open a new file
+ int i = num_files++;
+ files = check_mem(realloc(files, (num_files)*sizeof(File)));
+ files[i].filename = check_mem(strdup(filename));
+ files[i].fp = fopen(filename, "r");
+ if (!files[i].fp) {
+ perror(filename);
+ exit(EXIT_FAILURE);
+ }
+
+ return files[i].fp;
+}
+
+void free_files(void) {
+ if (files) {
+ for (int i = 0; i < num_files; i++) {
+ free(files[i].filename);
+ fclose(files[i].fp);
+ }
+ free(files);
+ files = NULL;
+ num_files = 0;
+ }
+}
+
+// read next N chars from file, user must free memory
+char* readN(const char* filename, int num) {
+ FILE* fp = next_file(filename);
+ char* text = check_mem(malloc(num+1));
+ int n_read = fread(text, 1, num, fp);
+ text[n_read] = '\0';
+ return text;
+}
+
+int main(int argc, char* argv[]) {
+ for (int i = 1; i+1 < argc; i+=2) {
+ char* text = readN(argv[i], atoi(argv[i+1]));
+ printf("%s\n", text);
+ free(text);
+ }
+ free_files();
+}
diff --git a/challenge-098/paulo-custodio/c/ch-2.c b/challenge-098/paulo-custodio/c/ch-2.c
new file mode 100644
index 0000000000..61ee568a7c
--- /dev/null
+++ b/challenge-098/paulo-custodio/c/ch-2.c
@@ -0,0 +1,102 @@
+/*
+Challenge 098
+
+TASK #2 › Search Insert Position
+Submitted by: Mohammad S Anwar
+You are given a sorted array of distinct integers @N and a target $N.
+
+Write a script to return the index of the given target if found
+otherwise place the target in the sorted array and return the index.
+
+Example 1:
+Input: @N = (1, 2, 3, 4) and $N = 3
+Output: 2 since the target 3 is in the array at the index 2.
+Example 2:
+Input: @N = (1, 3, 5, 7) and $N = 6
+Output: 3 since the target 6 is missing and should be placed at
+the index 3.
+Example 3:
+Input: @N = (12, 14, 16, 18) and $N = 10
+Output: 0 since the target 10 is missing and should be placed at
+the index 0.
+Example 4:
+Input: @N = (11, 13, 15, 17) and $N = 19
+Output: 4 since the target 19 is missing and should be placed at
+the index 4.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// memory allocation
+void* check_mem(void* p) {
+ if (!p) {
+ fputs("Out of memory", stderr);
+ exit(EXIT_FAILURE);
+ }
+ return p;
+}
+
+int* nums = NULL;
+int nums_size = 0;
+
+// append number to array
+void append(int n) {
+ nums = check_mem(realloc(nums, ++nums_size * sizeof(int)));
+ nums[nums_size-1] = n;
+}
+
+// use bsearch to find value or insert position
+const int* last_b = NULL;
+int compare(const void* a, const void *b) {
+ last_b = (const int*)b;
+ return *(int*)a - *(int*)b;
+}
+
+int search_index(int n) {
+ if (!nums) { // empty array
+ append(n);
+ return 0;
+ }
+ else if (n > nums[nums_size - 1]) { // larger than last
+ append(n);
+ return nums_size - 1;
+ }
+ else {
+ int* found = bsearch(&n, nums, nums_size, sizeof(int), compare);
+ if (found) // found index
+ return found-nums;
+ else { // last_b has the insert position
+ int last_i = last_b-nums; // note index before realloc ...
+ append(0); // ... in append
+ memmove(nums+last_i+1, nums+last_i,
+ (nums_size-last_i-1) * sizeof(int));
+ nums[last_i] = n;
+ return last_i;
+ }
+ }
+}
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ fputs("Usage: ch-2 N n0 n1 n2...", stderr);
+ return EXIT_FAILURE;
+ }
+
+ int n = atoi(argv[1]);
+ for (int i = 2; i < argc; i++)
+ append(atoi(argv[i]));
+
+ int pos = search_index(n);
+
+ printf("%d\n", pos);
+ const char* sep = "(";
+ for (int i = 0; i < nums_size; i++) {
+ printf("%s%d", sep, nums[i]);
+ sep = ", ";
+ }
+ printf(")\n");
+
+ free(nums);
+}
diff --git a/challenge-098/paulo-custodio/cpp/ch-1.cpp b/challenge-098/paulo-custodio/cpp/ch-1.cpp
new file mode 100644
index 0000000000..0d3f5c0cc3
--- /dev/null
+++ b/challenge-098/paulo-custodio/cpp/ch-1.cpp
@@ -0,0 +1,76 @@
+/*
+Challenge 098
+
+TASK #1 › Read N-characters
+Submitted by: Mohammad S Anwar
+You are given file $FILE.
+
+Create subroutine readN($FILE, $number) returns the first n-characters and
+moves the pointer to the (n+1)th character.
+
+Example:
+Input: Suppose the file (input.txt) contains "1234567890"
+Output:
+ print readN("input.txt", 4); # returns "1234"
+ print readN("input.txt", 4); # returns "5678"
+ print readN("input.txt", 4); # returns "90"
+*/
+
+#include <algorithm>
+#include <array>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+#include <cstring>
+
+// store list of open files
+class Files {
+public:
+ std::string readN(const std::string filename, int n) {
+ std::ifstream& ifs = add_file(filename);
+ char* buffer = new char[n + 1];
+ memset(buffer, 0, n + 1);
+ ifs.read(buffer, n);
+ auto text = std::string(buffer);
+ delete[] buffer;
+ return text;
+ }
+
+private:
+ // store std::ifstream in a pre-aloocated array as storing pointers to
+ // std::ifstream in an unordered_map was causing a heap corruption in
+ // GCC - probably a compiler/stdlib bug
+ static const int MAX_FILES = 20;
+ std::array<std::ifstream, MAX_FILES> files;
+ std::array<std::string, MAX_FILES> filenames;
+ size_t num_files{ 0 };
+
+ std::ifstream& add_file(const std::string filename) {
+ auto end = filenames.begin() + num_files;
+ auto found = std::find(filenames.begin(), end, filename);
+ if (found != end) { // found in filename
+ size_t i = std::distance(filenames.begin(), found);
+ return files[i];
+ }
+ else { // not found, must create new entry
+ if (num_files >= MAX_FILES) {
+ std::cerr << "too many files" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ filenames[num_files] = filename;
+ files[num_files].open(filename);
+ if (!files[num_files].is_open()) {
+ std::cerr << "open file " << filename << " failed" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ return files[num_files++];
+ }
+ }
+};
+
+int main(int argc, char* argv[]) {
+ Files f;
+ for (int i = 1; i + 1 < argc; i += 2)
+ std::cout << f.readN(argv[i], atoi(argv[i + 1])) << std::endl;
+}
diff --git a/challenge-098/paulo-custodio/cpp/ch-2.cpp b/challenge-098/paulo-custodio/cpp/ch-2.cpp
new file mode 100644
index 0000000000..310347f3ab
--- /dev/null
+++ b/challenge-098/paulo-custodio/cpp/ch-2.cpp
@@ -0,0 +1,69 @@
+/*
+Challenge 098
+
+TASK #2 › Search Insert Position
+Submitted by: Mohammad S Anwar
+You are given a sorted array of distinct integers @N and a target $N.
+
+Write a script to return the index of the given target if found
+otherwise place the target in the sorted array and return the index.
+
+Example 1:
+Input: @N = (1, 2, 3, 4) and $N = 3
+Output: 2 since the target 3 is in the array at the index 2.
+Example 2:
+Input: @N = (1, 3, 5, 7) and $N = 6
+Output: 3 since the target 6 is missing and should be placed at
+the index 3.
+Example 3:
+Input: @N = (12, 14, 16, 18) and $N = 10
+Output: 0 since the target 10 is missing and should be placed at
+the index 0.
+Example 4:
+Input: @N = (11, 13, 15, 17) and $N = 19
+Output: 4 since the target 19 is missing and should be placed at
+the index 4.
+*/
+
+#include <alg