I am so glad I never *have* to write C++ again.
This commit is contained in:
parent
c6caab0c7e
commit
2a58978931
8 changed files with 261 additions and 37 deletions
|
|
@ -5,13 +5,13 @@ CXX = g++
|
||||||
CXXFLAGS = -Wall -g
|
CXXFLAGS = -Wall -g
|
||||||
|
|
||||||
# Target executable
|
# Target executable
|
||||||
TARGET = main
|
TARGET = ./main
|
||||||
|
|
||||||
# For deleting the target
|
# For deleting the target
|
||||||
TARGET_DEL = main
|
TARGET_DEL = ./main
|
||||||
|
|
||||||
# Source files
|
# Source files
|
||||||
SRCS = src/main.cpp src/produce_database.cpp src/read_input.cpp
|
SRCS = src/main.cpp src/produce_database.cpp src/read_input.cpp src/merge_sort.cpp
|
||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
OBJS = $(SRCS:.cpp=.o)
|
OBJS = $(SRCS:.cpp=.o)
|
||||||
|
|
@ -33,4 +33,4 @@ run: $(TARGET)
|
||||||
|
|
||||||
# Clean rule to remove generated files
|
# Clean rule to remove generated files
|
||||||
clean:
|
clean:
|
||||||
del $(TARGET_DEL) $(OBJS)
|
rm $(TARGET_DEL) $(OBJS)
|
||||||
|
|
@ -3,22 +3,20 @@
|
||||||
* Created: 05/12/2025
|
* Created: 05/12/2025
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "produce_database.h"
|
#include "produce_database.h"
|
||||||
#include "read_input.h"
|
|
||||||
|
|
||||||
const std::string INPUT_FILEPATH = "input/test_ingredients.txt";
|
const std::string INPUT_FILEPATH = "input/ingredients.txt";
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
produce_database produce_db = read_input_from_file(INPUT_FILEPATH);
|
produce_database produce_db(INPUT_FILEPATH);
|
||||||
for (int i = 0; i < produce_db.get_fresh_ranges_size(); i++)
|
// produce_db.debug_fresh_ranges();
|
||||||
{
|
// produce_db.debug_available_ids();
|
||||||
std::cout << produce_db.get_fresh_range_from_index(i) << std::endl;
|
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;
|
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
|
||||||
|
|
@ -1,19 +1,136 @@
|
||||||
#include "produce_database.h"
|
#include "produce_database.h"
|
||||||
#include <vector>
|
#include "read_input.h"
|
||||||
#include <string>
|
#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()
|
int produce_database::get_fresh_ranges_size()
|
||||||
{
|
{
|
||||||
return this->fresh_ingredient_id_ranges.size();
|
return this->fresh_ingredient_id_ranges.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string produce_database::get_fresh_range_from_index(int index)
|
std::tuple<int64_t, int64_t> produce_database::get_fresh_range_from_index(int index)
|
||||||
{
|
{
|
||||||
return this->fresh_ingredient_id_ranges[index];
|
return this->fresh_ingredient_id_ranges[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void produce_database::add_fresh_range(std::string range)
|
int produce_database::get_available_ids_size()
|
||||||
{
|
{
|
||||||
this->fresh_ingredient_id_ranges.push_back(range);
|
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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
@ -4,17 +4,27 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
class produce_database
|
class produce_database
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> fresh_ingredient_id_ranges;
|
std::vector<std::tuple<int64_t, int64_t>> fresh_ingredient_id_ranges;
|
||||||
std::vector<std::string> available_ingredient_ids;
|
std::vector<int64_t> available_ingredient_ids;
|
||||||
|
void parse_input(std::vector<std::string> input_ranges, std::vector<std::string> input_ids);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
produce_database(std::string filename);
|
||||||
int get_fresh_ranges_size();
|
int get_fresh_ranges_size();
|
||||||
std::string get_fresh_range_from_index(int index);
|
std::tuple<int64_t, int64_t> get_fresh_range_from_index(int index);
|
||||||
void add_fresh_range(std::string range);
|
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
|
#endif
|
||||||
|
|
@ -1,22 +1,30 @@
|
||||||
#include "read_input.h"
|
#include "read_input.h"
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include "produce_database.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
produce_database read_input_from_file(string filepath)
|
tuple<vector<string>, vector<string>> read_input_from_file(string filepath)
|
||||||
{
|
{
|
||||||
produce_database produce_db;
|
vector<string> ranges;
|
||||||
|
vector<string> ids;
|
||||||
ifstream input_file(filepath);
|
ifstream input_file(filepath);
|
||||||
string input_buffer = " ";
|
string input_buffer = " ";
|
||||||
while (input_buffer != "")
|
bool is_after_ranges = false;
|
||||||
|
while (getline(input_file, input_buffer))
|
||||||
{
|
{
|
||||||
getline(input_file, input_buffer);
|
if (input_buffer == "")
|
||||||
produce_db.add_fresh_range(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();
|
input_file.close();
|
||||||
return produce_db;
|
|
||||||
|
tuple<vector<string>, vector<string>> output(ranges, ids);
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
@ -6,8 +6,9 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include "produce_database.h"
|
#include "produce_database.h"
|
||||||
|
|
||||||
produce_database read_input_from_file(std::string filepath);
|
std::tuple<std::vector<std::string>, std::vector<std::string>> read_input_from_file(std::string filepath);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in a new issue