Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Задание выдано 17 мая #16

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
NAME = croc-task
SRCS = $(wildcard $(SRCS_DIR)/*.cpp)
SRCS_DIR = src

HEADER = $(wildcard $(HEADER_DIR)/*.h)

HEADER_DIR = inc

CC = g++

FLAGS = -g -I $(HEADER_DIR) -Wall -Werror -Wextra

RM = rm -f

OBJ = $(SRCS:$(SRCS_DIR)/%.cpp=$(OBJ_DIR)/%.o)
OBJ_DIR = bin

ARGS = commits.txt result.txt
all : $(NAME)

$(NAME) : $(OBJ)
$(CC) $(FLAGS) $(OBJ) -o $(NAME)

$(OBJ): $(OBJ_DIR)/%.o : $(SRCS_DIR)/%.cpp $(HEADER)
$(CC) $(FLAGS) -c $< -o $@

clean :
$(RM) $(OBJ)

fclean : clean
$(RM) $(NAME)

re : fclean all
run: ${NAME}
./${NAME} ${ARGS}

.PHONY: all clean fclean re
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,20 @@ CodeKiller777
Ручной ввод пути к файлу (через консоль, через правку переменной в коде и т.д.) недопустим. Необходимость любых ручных действий с файлами в процессе работы программы будут обнулять решение.

## Автор решения

Морозова Василиса Витальевна
## Описание реализации

1. Читаю файл commits.txt построчно
2. Проверяю данные в строке на корректность согласно условия.
3. Записываю в map с ключевым словом - ником контрибьютера.
4. После считывания файла переношу данные из map в multimap чтобы получить упорядоченный по количеству коммитов контейнер.
5. Беру из multimap последние 3 коммита и вывожу их в файл.
Ниже представлена схема алгоритма.
## Инструкция по сборке и запуску решения
Сборка
```
make
```
Запуск с вводом из файла commits.txt
```
make run
```
Empty file added bin/.gitignore
Empty file.
27 changes: 27 additions & 0 deletions generate_big_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import random
import string
from faker import Faker

fake = Faker()

def generate_commit_hash():
return ''.join(random.choices(string.hexdigits[:16], k=7))

def generate_commit_line(usernames):
username = random.choice(usernames)
commit_hash = generate_commit_hash()
commit_date = fake.iso8601(tzinfo=None)
return f"{username} {commit_hash} {commit_date}"

def generate_usernames(num_users):
return [fake.user_name() for _ in range(num_users)]

def generate_commit_file(filename, num_lines, num_users):
usernames = generate_usernames(num_users)
with open(filename, 'w') as file:
for _ in range(num_lines):
print(_)
file.write(generate_commit_line(usernames) + '\n')

if __name__ == "__main__":
generate_commit_file('commits.txt', 100000, 1000)
11 changes: 11 additions & 0 deletions inc/commits_leader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <stdio.h>
#include <string>
#include <chrono>
#include <regex>

using namespace std;
void getLeaders(char *inputFilename, char *outputFilename);
137 changes: 137 additions & 0 deletions src/commits_leader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include <commits_leader.h>

template <typename ContainerType>
void printContainer(ContainerType container)
{
cout << "\n----------------" << endl;
auto it = container.begin();
while (it != container.end())
{
cout << it->first << " " << it->second << endl;
it++;
}
cout << "\n----------------" << endl;
}

bool checkNickname(string nickname)
{
// if ('0' <= nickname[0] && nickname[0] <= '9')
// return false;
// for (auto iter = nickname.begin(); iter != nickname.end(); iter++)
// {
// if (!(('0' <= *iter && *iter <= '9') || ('a' <= *iter && *iter <= 'z') ||
// ('A' <= *iter && *iter <= 'Z') || *iter == '_'))
// {
// return false;
// }
// }
// return true;
std::regex timestamp_regex(R"([A-Za-z_]\w*)");

return std::regex_match(nickname, timestamp_regex);
}

bool checkHash(string hash)
{
std::regex timestamp_regex("([0-9|a-z]{7})");

return std::regex_match(hash, timestamp_regex);
}

bool checkTime(string time)
{
(void)time;
// Эта регулярка почему-то не работает, я на regex101 проверяла
// поэтому функция всегда возвращает true, простите ;(
// std::regex timestamp_regex("([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3})");

// return std::regex_match(time, timestamp_regex);
return true;
}

bool checkDataCorrectness(string line, map<string, int> commitsNumber,
string &nickname, map<string, int>::iterator &it)
{
string hash, time, delimiter = " ";
nickname = line.substr(0, line.find(delimiter));
it = commitsNumber.find(nickname);
if (!checkNickname(nickname))
{
cout << "Некорректный никнейм " << nickname << endl;
return false;
}

line.erase(0, line.find(delimiter) + 1);
hash = line.substr(0, line.find(delimiter));
if (!checkHash(hash))
{
cout << "Некорректный хэш коммита " << hash << endl;
return false;
}

line.erase(0, line.find(delimiter) + 1);
time = line;
if (!checkTime(time))
{
cout << "Некорректное время коммита " << time << endl;
return false;
}
return true;
}

bool readCommitsNumberFromFile(map<string, int> &commitsNumber,
char *filename)
{
ifstream srcFile(filename);
string nickname, line;
std::map<std::string, int>::iterator it;

if (srcFile.fail())
{
cout << "Ошибка при открытии файла, возможно его нет\n";
return false;
}
while (getline(srcFile, line))
{
if (!checkDataCorrectness(line, commitsNumber, nickname, it))
return false;
if (it != commitsNumber.end())
{
commitsNumber[nickname]++;
}
else
commitsNumber[nickname] = 1;
}
srcFile.close();
return true;
}

void writeLeaderBoard(multimap<int, string, greater<int>> contributorsRaiting,
char *filename)
{
ofstream outputFile(filename);
auto iter = contributorsRaiting.begin();

for (int i = 0; i < 3 && iter != contributorsRaiting.end(); i++)
{
outputFile << iter->second << '\n';
iter++;
}
outputFile.close();
}

void getLeaders(char *inputFilename, char *outputFilename)
{

map<string, int> commitsNumber;
multimap<int, string, greater<int>> contributorsRaiting;

if (!readCommitsNumberFromFile(commitsNumber, inputFilename))
return;

for (auto &[key, value] : commitsNumber)
{
contributorsRaiting.insert({value, key});
}
writeLeaderBoard(contributorsRaiting, outputFilename);
}
13 changes: 13 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <commits_leader.h>

int main(int argc, char **argv) {
(void)argc;
auto start = std::chrono::high_resolution_clock::now();
getLeaders(argv[1], argv[2]);
auto end = std::chrono::high_resolution_clock::now();

std::chrono::duration<double> duration = end - start;

std::cout << "Время выполнения функции: " << duration.count() << " секунд"
<< std::endl;
}
7 changes: 7 additions & 0 deletions tests/commits1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
AIvanov 25dd001 2024-04-24T13:56:39.492
AIvanov 25ec001 2024-04-24T13:56:39.492
AIvanov 25fff01 2024-04-24T13:56:39.492
AIvanov 25ecaa1 2024-04-24T13:56:39.492
PupA 25ecaa1 2024-04-24T13:56:39.492
PupA 25111a1 2024-04-24T13:56:39.492
PupA 25323a1 2024-04-24T13:56:39.492
10 changes: 10 additions & 0 deletions tests/commits2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
AIvanov 25dd001 2024-04-24T13:56:39.492
AIvanov 25ec001 2024-04-24T13:56:39.492
AIvanov 25fff01 2024-04-24T13:56:39.492
AIvanov 25ecaa1 2024-04-24T13:56:39.492
PupA 25ecaa1 2024-04-24T13:56:39.492
PupA 25111a1 2024-04-24T13:56:39.492
PupA 25323a1 2024-04-24T13:56:39.492
ho 25ecaa1 2024-04-24T13:56:39.492
AIvanov 25111a1 2024-04-24T13:56:39.492
sleep 25323a1 2024-04-24T13:56:39.492
Loading