# LogParser

Given a txt document consisting of log information, find time as a percentage - spent connected.

* The time started is the first line, and the time ended is the last line.
* Information inbetween consists of various information, but what we are interested in the total amount of time connected vs time total amount of time disconnected.

Examples

```
(11/01/2015-04:00:00) :: START
(11/01/2015-04:00:00) :: CONNECTED
(11/01/2015-04:30:00) :: DISCONNECTED
(11/01/2015-04:45:00) :: CONNECTED
(11/01/2015-05:00:00) :: SHUTDOWN

output: 75%
```

```
(11/01/2015-03:30:00) :: START
(11/01/2015-03:30:00) :: CONNECTED
(11/01/2015-04:00:00) :: DISCONNECTED
(11/01/2015-04:15:00) :: SHUTDOWN

output: 66%
```

```
(01/01/2015-00:00:00) :: START
(01/01/2015-00:00:05) :: CONNECTED
(01/01/2015-00:01:23) :: UI - HUD animation state changed
(01/01/2015-00:03:47) :: ERROR - Unknown error
(01/01/2015-00:12:11) :: DISCONNECTED
(01/01/2015-00:13:14) :: UI - HUD animation state changed
(01/01/2015-00:13:50) :: CONNECTED
(01/01/2015-00:17:20) :: UI - HUD animation state changed
(01/01/2015-00:21:06) :: Crash report sent to server successfully
(01/01/2015-00:22:00) :: Warning: please implement this
(01/01/2015-00:23:50) :: Warning: please implement this
(01/01/2015-00:28:41) :: DISCONNECTED
(01/01/2015-00:31:31) :: UI - HUD animation state changed
(01/01/2015-00:32:12) :: ERROR - Unknown error
(01/01/2015-00:35:45) :: CONNECTED
(01/01/2015-00:36:50) :: DISCONNECTED
(01/01/2015-00:37:01) :: Warning: please implement this
(01/01/2015-00:38:22) :: Crash report sent to server unsuccessfully
(01/01/2015-00:38:23) :: ERROR - Unknown error
(01/01/2015-00:39:17) :: CONNECTED
(01/01/2015-00:40:40) :: UI - HUD animation state changed
(01/01/2015-00:40:42) :: UI - HUD animation state changed
(01/01/2015-00:42:15) :: Crash report sent to server successfully
(01/01/2015-00:42:30) :: DISCONNECTED
(01/01/2015-00:43:56) :: UI - HUD animation state changed
(01/01/2015-00:44:18) :: CONNECTED
(01/01/2015-01:00:00) :: SHUTDOWN

78%
```

```cpp
class LogParser {
public:
    static std::string parseFile(const std::string&);
    static std::string parseLines(const std::vector < std::string >& lines);
};

class Time {
public:
    Time(string time) {
        parse(time);
    }

    Time(int short h, int short m, int short s) {
        hr = h; min = m; sec = s;
    }

    Time() { hr = min = sec = 0; }

    friend Time operator-(const Time &one, const Time &two);

    void operator +=(const Time& rhs) {
        hr  = rhs.hr + hr;
        min = rhs.min + min;
        sec = rhs.sec + sec;
    }

    void operator=(const Time &rhs) {
        hr  = rhs.hr;
        min = rhs.min;
        sec = rhs.sec;
    }

    // this function also takes care of 
    // negatives e.g. 01:-15:00
    float convert_to_min() {
        float hr_min = hr * 60;
        float sec_min = sec / 60;
        return hr_min + min + sec_min;
    }

    int short hr, min, sec;

private:
    void parse(string &time) {
        hr  =  atoi(time.substr(0, 2).c_str());
        min =  atoi(time.substr(3, 5).c_str());
        sec =  atoi(time.substr(6, 8).c_str());
    }
};

float get_ratio(Time & t1, Time & t2)
{
    return t1.convert_to_min() / t2.convert_to_min();
}

Time operator-(const Time &one, const Time &two) {
    int h, m, s;
    h = one.hr - two.hr;
    m = one.min - two.min;
    s = one.sec - two.sec;

    return Time(h, m, s);
}


std::string LogParser::parseFile(const std::string& filename) {
    std::ifstream ifs(filename.c_str(), std::ios::in);
    if (!ifs) { throw "File not found!"; }

    std::vector < std::string > lines;
    std::string line;
    while (std::getline(ifs, line)) {
        lines.push_back(line);
    };

    return LogParser::parseLines(lines);
}

std::string LogParser::parseLines(const std::vector <std::string>& lines) {
    // get the start and end time
    Time very_start(lines.at(0).substr(12, 8));
    Time very_end(lines.at(lines.size() - 1).substr(12, 8));

    Time length = very_start - very_end;

    bool is_disconnect = false;
    bool is_connected = false;

    Time sum_disconnect;
    Time start, end;

    // ignore first 2 lines
    for (int i = 2; i < lines.size(); i++) {
        string cur_str = lines.at(i);
        string sub_str_status = cur_str.substr(25, cur_str.length() - 1);
        string cur_time = cur_str.substr(12, 8);
        if (sub_str_status == "CONNECTED" || sub_str_status == "SHUTDOWN") {
            is_connected = true;
            end = Time(cur_time);
        }
        else if (sub_str_status == "DISCONNECTED" ){
            is_disconnect = true;
            start = Time(cur_time);
        }

        if (is_disconnect && is_connected) {
            sum_disconnect += start - end;
            is_disconnect = is_connected = false;
        }
    }

    Time diff = length - sum_disconnect;
    string final_str = to_string(get_ratio(diff, length));
    return final_str.substr(2,2) + "%";
}

int main(int argc, char** argv)
{
    LogParser p;
    cout << p.parseFile(argv[1]) << endl;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://maksimdan.gitbook.io/interview-practice-problems/leetcode_sessions/design/logparser.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
