diff --git a/05/Makefile b/05/Makefile new file mode 100644 index 0000000..2a6f68d --- /dev/null +++ b/05/Makefile @@ -0,0 +1,36 @@ +# Compiler +CXX = g++ + +# Compiler flags +CXXFLAGS = -Wall -g + +# Target executable +TARGET = ./main + +# For deleting the target +TARGET_DEL = ./main + +# Source files +SRCS = src/main.cpp src/produce_database.cpp src/read_input.cpp src/merge_sort.cpp + +# Object files +OBJS = $(SRCS:.cpp=.o) + +# Default rule to build and run the executable +all: $(TARGET) run + +# Rule to link object files into the target executable +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) + +# Rule to compile .cpp files into .o files +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $< -o $@ + +# Rule to run the executable +run: $(TARGET) + $(TARGET) + +# Clean rule to remove generated files +clean: + rm $(TARGET_DEL) $(OBJS) \ No newline at end of file diff --git a/05/src/main.cpp b/05/src/main.cpp new file mode 100644 index 0000000..84c6ddc --- /dev/null +++ b/05/src/main.cpp @@ -0,0 +1,22 @@ +/* Filename: main.cpp + * Author: Alice Winters + * Created: 05/12/2025 + */ + +#include "produce_database.h" + +const std::string INPUT_FILEPATH = "input/ingredients.txt"; + +int main() +{ + produce_database produce_db(INPUT_FILEPATH); + // produce_db.debug_fresh_ranges(); + // produce_db.debug_available_ids(); + produce_db.union_ranges(); + // produce_db.debug_fresh_ranges(); + int64_t available_fresh_ingredients = produce_db.get_available_fresh_ids(); + std::cout << "Available fresh ingredients: " << available_fresh_ingredients << std::endl; + int64_t fresh_ingedients = produce_db.get_fresh_ids(); + std::cout << "Total fresh ingredients: " << fresh_ingedients << std::endl; + return 0; +} diff --git a/05/src/merge_sort.cpp b/05/src/merge_sort.cpp new file mode 100644 index 0000000..1ed496a --- /dev/null +++ b/05/src/merge_sort.cpp @@ -0,0 +1,77 @@ +// Credit: https://www.geeksforgeeks.org/cpp/cpp-program-for-merge-sort/ +// C++ program for the implementation of merge sort +#include "merge_sort.h" + +using namespace std; + +// Merges two subarrays of vec. +// First subarray is vec[left..mid] +// Second subarray is vec[mid+1..right] +void merge(vector> &vec, int left, int mid, int right) +{ + int i, j, k; + int n1 = mid - left + 1; + int n2 = right - mid; + + // Create temporary vectors + vector> leftVec(n1), rightVec(n2); + + // Copy data to temporary vectors + for (i = 0; i < n1; i++) + leftVec[i] = vec[left + i]; + for (j = 0; j < n2; j++) + rightVec[j] = vec[mid + 1 + j]; + + // Merge the temporary vectors back into vec[left..right] + i = 0; + j = 0; + k = left; + while (i < n1 && j < n2) + { + if (get<0>(leftVec[i]) <= get<0>(rightVec[j])) + { + vec[k] = leftVec[i]; + i++; + } + else + { + vec[k] = rightVec[j]; + j++; + } + k++; + } + + // Copy the remaining elements of leftVec[], if any + while (i < n1) + { + vec[k] = leftVec[i]; + i++; + k++; + } + + // Copy the remaining elements of rightVec[], if any + while (j < n2) + { + vec[k] = rightVec[j]; + j++; + k++; + } +} + +// The subarray to be sorted is in the index range [left..right] +void mergeSort(vector> &vec, int left, int right) +{ + if (left < right) + { + + // Calculate the midpoint + int mid = left + (right - left) / 2; + + // Sort first and second halves + mergeSort(vec, left, mid); + mergeSort(vec, mid + 1, right); + + // Merge the sorted halves + merge(vec, left, mid, right); + } +} \ No newline at end of file diff --git a/05/src/merge_sort.h b/05/src/merge_sort.h new file mode 100644 index 0000000..382df39 --- /dev/null +++ b/05/src/merge_sort.h @@ -0,0 +1,13 @@ +#ifndef MERGE_SORT_H + +#define MERGE_SORT_H + +#include +#include +#include +#include + +void merge(std::vector> &vec, int left, int mid, int right); +void mergeSort(std::vector> &vec, int left, int right); + +#endif \ No newline at end of file diff --git a/05/src/produce_database.cpp b/05/src/produce_database.cpp new file mode 100644 index 0000000..232faa7 --- /dev/null +++ b/05/src/produce_database.cpp @@ -0,0 +1,136 @@ +#include "produce_database.h" +#include "read_input.h" +#include "merge_sort.h" + +void produce_database::parse_input(std::vector input_ranges, std::vector input_ids) +{ + std::string temp_string; + std::tuple temp_tuple; + for (int i = 0; i < (int)input_ranges.size(); i++) + { + temp_string = ""; + for (int j = 0; j < (int)input_ranges[i].size(); j++) + { + if (input_ranges[i][j] == '-') + { + std::get<0>(temp_tuple) = std::stoll(temp_string); + temp_string = ""; + continue; + } + temp_string.push_back(input_ranges[i][j]); + } + std::get<1>(temp_tuple) = std::stoll(temp_string); + this->fresh_ingredient_id_ranges.push_back(temp_tuple); + } + + for (int i = 0; i < (int)input_ids.size(); i++) + { + this->available_ingredient_ids.push_back(std::stoll(input_ids[i])); + } + + return; +} + +produce_database::produce_database(std::string filename) +{ + std::tuple, std::vector> input = read_input_from_file(filename); + this->parse_input(std::get<0>(input), std::get<1>(input)); +} + +int produce_database::get_fresh_ranges_size() +{ + return this->fresh_ingredient_id_ranges.size(); +} + +std::tuple produce_database::get_fresh_range_from_index(int index) +{ + return this->fresh_ingredient_id_ranges[index]; +} + +int produce_database::get_available_ids_size() +{ + return this->available_ingredient_ids.size(); +} + +int64_t produce_database::get_available_id_from_index(int index) +{ + return this->available_ingredient_ids[index]; +} + +void produce_database::debug_fresh_ranges() +{ + for (int i = 0; i < (int)this->get_fresh_ranges_size(); i++) + { + std::cout << std::get<0>(this->get_fresh_range_from_index(i)); + std::cout << "-"; + std::cout << std::get<1>(this->get_fresh_range_from_index(i)); + std::cout << std::endl; + } +} + +void produce_database::debug_available_ids() +{ + for (int i = 0; i < (int)this->get_available_ids_size(); i++) + { + std::cout << this->get_available_id_from_index(i) << std::endl; + } +} + +void produce_database::union_ranges() +{ + mergeSort(this->fresh_ingredient_id_ranges, 0, (int)this->fresh_ingredient_id_ranges.size() - 1); + + std::tuple temp_tuple = this->fresh_ingredient_id_ranges[0]; + std::vector> unioned_ranges; + for (int i = 1; i < (int)this->get_fresh_ranges_size(); i++) + { + if (std::get<1>(temp_tuple) > std::get<1>(this->fresh_ingredient_id_ranges[i])) + { + continue; + } + if (std::get<1>(temp_tuple) < std::get<0>(this->fresh_ingredient_id_ranges[i])) + { + std::cout << std::get<0>(temp_tuple) << "-" << std::get<1>(temp_tuple) << std::endl; + unioned_ranges.push_back(temp_tuple); + temp_tuple = this->fresh_ingredient_id_ranges[i]; + continue; + } + std::get<1>(temp_tuple) = std::get<1>(this->fresh_ingredient_id_ranges[i]); + } + unioned_ranges.push_back(temp_tuple); + + this->fresh_ingredient_id_ranges = unioned_ranges; + + return; +} + +int64_t produce_database::get_available_fresh_ids() +{ + int count = 0; + + for (int i = 0; i < (int)this->available_ingredient_ids.size(); i++) + { + for (int j = 0; j < (int)this->fresh_ingredient_id_ranges.size(); j++) + { + if (this->available_ingredient_ids[i] >= std::get<0>(this->fresh_ingredient_id_ranges[j]) && this->available_ingredient_ids[i] <= std::get<1>(this->fresh_ingredient_id_ranges[j])) + { + ++count; + break; + } + } + } + + return count; +} + +int64_t produce_database::get_fresh_ids() +{ + int64_t sum = 0; + + for (int i = 0; i < (int)this->fresh_ingredient_id_ranges.size(); i++) + { + sum += std::get<1>(this->fresh_ingredient_id_ranges[i]) - std::get<0>(this->fresh_ingredient_id_ranges[i]) + 1; + } + + return sum; +} \ No newline at end of file diff --git a/05/src/produce_database.h b/05/src/produce_database.h new file mode 100644 index 0000000..881e49f --- /dev/null +++ b/05/src/produce_database.h @@ -0,0 +1,30 @@ +#ifndef PRODUCE_DATABASE_H + +#define PRODUCE_DATABASE_H + +#include +#include +#include +#include + +class produce_database +{ +private: + std::vector> fresh_ingredient_id_ranges; + std::vector available_ingredient_ids; + void parse_input(std::vector input_ranges, std::vector input_ids); + +public: + produce_database(std::string filename); + int get_fresh_ranges_size(); + std::tuple get_fresh_range_from_index(int index); + int get_available_ids_size(); + int64_t get_available_id_from_index(int index); + void debug_fresh_ranges(); + void debug_available_ids(); + void union_ranges(); + int64_t get_available_fresh_ids(); + int64_t get_fresh_ids(); +}; + +#endif \ No newline at end of file diff --git a/05/src/read_input.cpp b/05/src/read_input.cpp new file mode 100644 index 0000000..f3f8f15 --- /dev/null +++ b/05/src/read_input.cpp @@ -0,0 +1,30 @@ +#include "read_input.h" + +using namespace std; + +tuple, vector> read_input_from_file(string filepath) +{ + vector ranges; + vector ids; + ifstream input_file(filepath); + string input_buffer = " "; + bool is_after_ranges = false; + while (getline(input_file, input_buffer)) + { + if (input_buffer == "") + { + is_after_ranges = true; + continue; + } + if (is_after_ranges) + { + ids.push_back(input_buffer); + continue; + } + ranges.push_back(input_buffer); + } + input_file.close(); + + tuple, vector> output(ranges, ids); + return output; +} \ No newline at end of file diff --git a/05/src/read_input.h b/05/src/read_input.h new file mode 100644 index 0000000..b856a2f --- /dev/null +++ b/05/src/read_input.h @@ -0,0 +1,14 @@ +#ifndef READ_INPUT_H + +#define READ_INPUT_H + +#include +#include +#include +#include +#include +#include "produce_database.h" + +std::tuple, std::vector> read_input_from_file(std::string filepath); + +#endif \ No newline at end of file