Merge pull request 'Implementing Day 05's Solution in C++' (#1) from cpp into main
Reviewed-on: #1
This commit is contained in:
commit
88815a5d19
8 changed files with 358 additions and 0 deletions
36
05/Makefile
Normal file
36
05/Makefile
Normal file
|
|
@ -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)
|
||||
22
05/src/main.cpp
Normal file
22
05/src/main.cpp
Normal file
|
|
@ -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;
|
||||
}
|
||||
77
05/src/merge_sort.cpp
Normal file
77
05/src/merge_sort.cpp
Normal file
|
|
@ -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<tuple<int64_t, int64_t>> &vec, int left, int mid, int right)
|
||||
{
|
||||
int i, j, k;
|
||||
int n1 = mid - left + 1;
|
||||
int n2 = right - mid;
|
||||
|
||||
// Create temporary vectors
|
||||
vector<tuple<int64_t, int64_t>> 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<tuple<int64_t, int64_t>> &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);
|
||||
}
|
||||
}
|
||||
13
05/src/merge_sort.h
Normal file
13
05/src/merge_sort.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef MERGE_SORT_H
|
||||
|
||||
#define MERGE_SORT_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <stdint.h>
|
||||
|
||||
void merge(std::vector<std::tuple<int64_t, int64_t>> &vec, int left, int mid, int right);
|
||||
void mergeSort(std::vector<std::tuple<int64_t, int64_t>> &vec, int left, int right);
|
||||
|
||||
#endif
|
||||
136
05/src/produce_database.cpp
Normal file
136
05/src/produce_database.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#include "produce_database.h"
|
||||
#include "read_input.h"
|
||||
#include "merge_sort.h"
|
||||
|
||||
void produce_database::parse_input(std::vector<std::string> input_ranges, std::vector<std::string> input_ids)
|
||||
{
|
||||
std::string temp_string;
|
||||
std::tuple<int64_t, int64_t> 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<std::string>, std::vector<std::string>> 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<int64_t, int64_t> 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<int64_t, int64_t> temp_tuple = this->fresh_ingredient_id_ranges[0];
|
||||
std::vector<std::tuple<int64_t, int64_t>> 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;
|
||||
}
|
||||
30
05/src/produce_database.h
Normal file
30
05/src/produce_database.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef PRODUCE_DATABASE_H
|
||||
|
||||
#define PRODUCE_DATABASE_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
|
||||
class produce_database
|
||||
{
|
||||
private:
|
||||
std::vector<std::tuple<int64_t, int64_t>> fresh_ingredient_id_ranges;
|
||||
std::vector<int64_t> available_ingredient_ids;
|
||||
void parse_input(std::vector<std::string> input_ranges, std::vector<std::string> input_ids);
|
||||
|
||||
public:
|
||||
produce_database(std::string filename);
|
||||
int get_fresh_ranges_size();
|
||||
std::tuple<int64_t, int64_t> 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
|
||||
30
05/src/read_input.cpp
Normal file
30
05/src/read_input.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "read_input.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
tuple<vector<string>, vector<string>> read_input_from_file(string filepath)
|
||||
{
|
||||
vector<string> ranges;
|
||||
vector<string> 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<string>, vector<string>> output(ranges, ids);
|
||||
return output;
|
||||
}
|
||||
14
05/src/read_input.h
Normal file
14
05/src/read_input.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef READ_INPUT_H
|
||||
|
||||
#define READ_INPUT_H
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include "produce_database.h"
|
||||
|
||||
std::tuple<std::vector<std::string>, std::vector<std::string>> read_input_from_file(std::string filepath);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue