aboutsummaryrefslogtreecommitdiff
path: root/challenge-098/paulo-custodio/cpp
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 /challenge-098/paulo-custodio/cpp
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
Diffstat (limited to 'challenge-098/paulo-custodio/cpp')
-rw-r--r--challenge-098/paulo-custodio/cpp/ch-1.cpp76
-rw-r--r--challenge-098/paulo-custodio/cpp/ch-2.cpp69
2 files changed, 145 insertions, 0 deletions
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 <algorithm>
+#include <iostream>
+#include <vector>
+
+int search_index(std::vector<int>& nums, int n) {
+ auto it = std::lower_bound(nums.begin(), nums.end(), n);
+ if (it == nums.end()) { // not found
+ nums.push_back(n);
+ return nums.size() - 1;
+ }
+ else if (*it != n) { // found an higher value
+ int index = std::distance(nums.begin(), it); // insert may move memory
+ nums.insert(it, n);
+ return index;
+ }
+ else { // found value
+ return std::distance(nums.begin(), it);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ std::cerr << "Usage: ch-2 N n0 n1 n2..." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ std::vector<int> nums;
+ int n = atoi(argv[1]);
+ for (int i = 2; i < argc; i++)
+ nums.push_back(atoi(argv[i]));
+
+ int pos = search_index(nums, n);
+
+ std::cout << pos << std::endl;
+
+ const char* sep = "(";
+ for (auto& i : nums) {
+ std::cout << sep << i;
+ sep = ", ";
+ }
+ std::cout << ")" << std::endl;
+}