ium_452639/normalize.cc

109 lines
2.4 KiB
C++

#include <iostream>
#include <fstream>
#include <unordered_set>
#include <optional>
namespace split
{
struct sentinel {};
struct iterator
{
using difference_type = ptrdiff_t;
using value_type = std::string_view;
using iterator_category = std::input_iterator_tag;
using pointer = void;
using reference = std::string_view&;
explicit iterator(std::convertible_to<std::string_view> auto&& source, char delim)
: source{source}
, delim{delim}
{
++*this; // Compute first cell
}
inline iterator begin() const
{
return *this;
}
inline sentinel end() const
{
return sentinel{};
}
inline bool operator==(sentinel) const
{
return reached_end;
}
inline iterator& operator++()
{
if (source.empty()) {
reached_end = true;
return *this;
}
if (auto tab = source.find(delim); tab != std::string_view::npos) {
current = source.substr(0, tab);
source.remove_prefix(tab+1);
} else {
current = source;
source = {};
}
return *this;
}
inline iterator operator++(int)
{
auto copy = *this;
++*this;
return copy;
}
inline std::string_view operator*() const
{
return current;
}
std::string_view current;
std::string_view source;
char delim;
bool reached_end = false;
};
}
std::optional<float> time2float(std::string_view time)
{
if (time.size() != 8) return std::nullopt; // Expected time in format hh:mm:ss
auto const hours = ((time[0] - '0') * 10 + time[1] - '0');
auto const minutes = ((time[3] - '0') * 10 + time[4] - '0');
if (hours >= 24) return std::nullopt; // Single day has only 24 hours
return (float(hours) * 60 + float(minutes)) / (60 * 24);
}
int main()
{
std::cout.sync_with_stdio(false);
bool passed_header = false;
for (std::string line; std::getline(std::cin, line);) {
split::iterator row(line, '\t');
std::advance(row, 2); if (row == split::sentinel{}) continue; std::string_view const departure_time = *row;
std::advance(row, 1); if (row == split::sentinel{}) continue; std::string_view const stop_id = *row;
std::advance(row, 2); if (row == split::sentinel{}) continue; std::string_view const stop_headsign = *row;
if (!passed_header) {
std::cout << departure_time << '\t' << stop_id << '\t' << stop_headsign << '\n';
passed_header = true;
continue;
}
auto const departure = time2float(departure_time); if (!departure) continue;
std::cout << *departure << '\t' << stop_id << '\t' << stop_headsign << '\n';
}
}