Skip to content

Commit 415ea7c

Browse files
authored
Week 15: Задание 31.03.25 : 12.14 - 12.20 / 75 баллов / 08.04.25 23:59:59 (#18)
* add task 12-14 * add task 12.15 * initial calculator * task 12.20: calculator
1 parent 82a7a2f commit 415ea7c

14 files changed

Lines changed: 316 additions & 1 deletion

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ include_directories(shared)
6262

6363

6464
##### subdirectories #####
65-
set(DIRS week-W week-2 week-3 week-4 week-5 week-6 week-7 week-8 week-9 week-10 week-11 week-12 week-13 week-14)
65+
set(DIRS week-W week-2 week-3 week-4 week-5 week-6 week-7 week-8 week-9 week-10 week-11 week-12 week-13 week-14 week-15)
6666
foreach(DIR ${DIRS})
6767
add_subdirectory(${DIR})
6868
endforeach()

week-15/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
set(DIRS task-12-14 task-12-15 task-12-20)
2+
foreach(DIR ${DIRS})
3+
add_subdirectory(${DIR})
4+
endforeach()

week-15/task-12-14/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include_directories(include)
2+
3+
add_subdirectory(test)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <algorithm>
4+
#include <ranges>
5+
#include <regex>
6+
#include <string>
7+
#include <vector>
8+
9+
std::vector<std::string> rus_car_numbers(const std::string& str) {
10+
const std::regex pattern(R"(\b[ABEKMHOPCTYX]\d{3}[ABEKMHOPCTYX]{2}\b)");
11+
std::vector<std::string> numbers;
12+
std::ranges::for_each(std::sregex_iterator(std::cbegin(str), std::cend(str), pattern),
13+
std::sregex_iterator(),
14+
[&numbers](const auto& matches) { numbers.push_back(matches[0]); });
15+
return numbers;
16+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp_test(test-12-14.cpp)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include "car_numbers.hpp"
2+
#include "gtest/gtest.h"
3+
4+
TEST(RusCarNumbersTest, EmptyInput) {
5+
EXPECT_EQ(rus_car_numbers(""), std::vector<std::string>({}));
6+
}
7+
8+
TEST(RusCarNumbersTest, NoNumbersInText) {
9+
const std::string text = R"(
10+
Just text without license plates.
11+
Examples: 12345, ABCDEF, !@#$%^&*
12+
Similar looking: AB12CD, X9Y9Z9
13+
)";
14+
EXPECT_EQ(rus_car_numbers(text), std::vector<std::string>({}));
15+
}
16+
17+
TEST(RusCarNumbersTest, ValidNumbersWithoutRegion) {
18+
const std::string text = R"(
19+
Correct plates: A123BC, E555EE, K321AM
20+
Parking spots: M111MM and T444YX
21+
With trash: A123BC45 -> A123BC
22+
Almost valid: X999XZ -> invalid (Z)
23+
)";
24+
EXPECT_EQ(rus_car_numbers(text), std::vector<std::string>({"A123BC", "E555EE", "K321AM",
25+
"M111MM", "T444YX", "A123BC"}));
26+
}
27+
28+
TEST(RusCarNumbersTest, InvalidFormats) {
29+
const std::string text = R"(
30+
Invalid:
31+
ABC123 (wrong order)
32+
123ABC (starts with digits)
33+
A1B2C3 (alternating)
34+
A123BC45 (with region, but takes A123BC)
35+
A12BC (too short)
36+
Z999ZZ (invalid letter Z)
37+
)";
38+
EXPECT_EQ(rus_car_numbers(text), std::vector<std::string>({"A123BC"}));
39+
}
40+
41+
TEST(RusCarNumbersTest, MixedContent) {
42+
const std::string text = R"(
43+
Valid: A777BC and C666CT
44+
Invalid: AB123C, X9Y9Z9
45+
With region: T123TX42 -> T123TX
46+
Trash: !Y222YA@
47+
Almost valid: O999OI -> invalid (I)
48+
)";
49+
EXPECT_EQ(rus_car_numbers(text),
50+
std::vector<std::string>({"A777BC", "C666CT", "T123TX", "Y222YA"}));
51+
}
52+
53+
TEST(RusCarNumbersTest, EdgeCases) {
54+
const std::string text = R"(
55+
Edge cases:
56+
A001AX (minimum)
57+
X999XX (maximum)
58+
B000TB (zeros in digits)
59+
H555HH (same letters)
60+
Almost valid:
61+
A000AA0 (extra zero)
62+
Y123YF (invalid F)
63+
)";
64+
EXPECT_EQ(rus_car_numbers(text),
65+
std::vector<std::string>({"A001AX", "X999XX", "B000TB", "H555HH"}));
66+
}
67+
68+
TEST(RusCarNumbersTest, AllValidLettersCombinations) {
69+
const std::string text = R"(
70+
All valid letters:
71+
A123BC, B456TE, E789KX
72+
K321AM, M111MO, H555OP
73+
O999PC, P777CT, C666TY
74+
T444YX, Y222XA, X888AB
75+
)";
76+
EXPECT_EQ(
77+
rus_car_numbers(text),
78+
std::vector<std::string>({"A123BC", "B456TE", "E789KX", "K321AM", "M111MO", "H555OP",
79+
"O999PC", "P777CT", "C666TY", "T444YX", "Y222XA", "X888AB"}));
80+
}

week-15/task-12-15/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include_directories(include)
2+
3+
add_subdirectory(test)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <algorithm>
4+
#include <ranges>
5+
#include <regex>
6+
#include <string>
7+
#include <vector>
8+
9+
std::vector<std::string> emails(const std::string& str) {
10+
const std::regex pattern(R"(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{1,}\b)");
11+
std::vector<std::string> emails;
12+
std::ranges::for_each(std::sregex_iterator(std::cbegin(str), std::cend(str), pattern),
13+
std::sregex_iterator(),
14+
[&emails](const auto& matches) { emails.push_back(matches[0]); });
15+
return emails;
16+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp_test(test-12-15.cpp)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include "emails.hpp"
2+
#include "gtest/gtest.h"
3+
4+
TEST(EmailExtractionTest, EmptyInput) { EXPECT_EQ(emails(""), std::vector<std::string>({})); }
5+
6+
TEST(EmailExtractionTest, NoEmailsInText) {
7+
const std::string text = R"(
8+
This is just regular text without any emails.
9+
Some symbols: @hello, test@, @test.com
10+
Numbers: 12345, random!text
11+
)";
12+
EXPECT_EQ(emails(text), std::vector<std::string>({}));
13+
}
14+
15+
TEST(EmailExtractionTest, ValidEmails) {
16+
const std::string text = R"(
17+
Contact us at: john.doe@example.com or support@company.org.
18+
Student emails: student_2023@university.edu, a.b@c.d.xyz
19+
Special cases: email+filter@gmail.com, name@sub.domain.co.uk
20+
)";
21+
EXPECT_EQ(emails(text),
22+
std::vector<std::string>({"john.doe@example.com", "support@company.org",
23+
"student_2023@university.edu", "a.b@c.d.xyz",
24+
"email+filter@gmail.com", "name@sub.domain.co.uk"}));
25+
}
26+
27+
TEST(EmailExtractionTest, InvalidEmails) {
28+
const std::string text = R"(
29+
Invalid formats:
30+
plaintext
31+
@missing.start
32+
missing@at
33+
double@@sign.com
34+
invalid@chars_here.com
35+
missing@tld.
36+
)";
37+
EXPECT_EQ(emails(text), std::vector<std::string>({}));
38+
}
39+
40+
TEST(EmailExtractionTest, MixedContent) {
41+
const std::string text = R"(
42+
Valid: contact@valid.com, another@good.org
43+
Invalid: bad@email, @wrong.com
44+
Almost valid: almost@valid. but with space
45+
Trash: !@#$%^&*
46+
Valid but tricky: "spaces@around.com" (should extract without quotes)
47+
)";
48+
EXPECT_EQ(emails(text), std::vector<std::string>(
49+
{"contact@valid.com", "another@good.org", "spaces@around.com"}));
50+
}
51+
52+
TEST(EmailExtractionTest, EdgeCases) {
53+
const std::string text = R"(
54+
Minimal: a@b.c
55+
Long domain: email@sub.sub2.sub3.example.com
56+
Special chars: user+filter@domain.com
57+
Numbers: 1234@numbers.com
58+
Hyphens: hyphen-ated@domain-name.com
59+
Quotes: "email@inside.quotes"
60+
)";
61+
EXPECT_EQ(emails(text),
62+
std::vector<std::string>({"a@b.c", "email@sub.sub2.sub3.example.com",
63+
"user+filter@domain.com", "1234@numbers.com",
64+
"hyphen-ated@domain-name.com", "email@inside.quotes"}));
65+
}

0 commit comments

Comments
 (0)