Skip to content

Commit ebac975

Browse files
committed
Changed everything to use Boost
1 parent e460924 commit ebac975

4 files changed

Lines changed: 70 additions & 73 deletions

File tree

exercises/practice/baffling-birthdays/.meta/example.cpp

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,33 @@
1-
#include <chrono>
21
#include <random>
2+
#include <unordered_set>
33

44
#include "baffling_birthdays.h"
55

66
namespace baffling_birthdays {
77

88
Date parse_date(const std::string& iso) {
9-
Date d{0, 0, 0};
10-
if (iso.size() < 10) return d;
119
try {
12-
d.year = std::stoi(iso.substr(0, 4));
13-
d.month = std::stoi(iso.substr(5, 2));
14-
d.day = std::stoi(iso.substr(8, 2));
10+
return boost::gregorian::from_simple_string(iso);
1511
} catch (...) {
16-
d = {0, 0, 0};
12+
return Date(boost::gregorian::not_a_date_time);
1713
}
18-
return d;
19-
}
20-
21-
std::string to_string(const Date& d) {
22-
std::ostringstream oss;
23-
oss << std::setw(4) << std::setfill('0') << d.year << '-' << std::setw(2)
24-
<< std::setfill('0') << d.month << '-' << std::setw(2)
25-
<< std::setfill('0') << d.day;
26-
return oss.str();
2714
}
2815

2916
bool shared_birthday(const std::vector<Date>& dates) {
30-
std::unordered_set<int> seen_md;
17+
std::unordered_set<unsigned> seen_md;
3118
seen_md.reserve(dates.size());
3219
for (auto const& d : dates) {
33-
if (d.month < 1 || d.month > 12 || d.day < 1 || d.day > 31) continue;
34-
int key = d.month * 100 + d.day;
20+
if (d.is_not_a_date()) continue;
21+
unsigned key = d.month().as_number() * 100 + d.day();
3522
if (seen_md.count(key)) return true;
3623
seen_md.insert(key);
3724
}
3825
return false;
3926
}
4027

41-
std::vector<Date> random_birthdates_dates(std::size_t group_size) {
28+
std::vector<Date> random_birthdates(std::size_t group_size) {
4229
static std::mt19937_64 gen(
43-
std::chrono::system_clock::now().time_since_epoch().count());
30+
static_cast<unsigned long>(std::random_device{}()));
4431
std::uniform_int_distribution<int> month_dist(1, 12);
4532
const int days_in_month[12] = {31, 28, 31, 30, 31, 30,
4633
31, 31, 30, 31, 30, 31};
@@ -49,7 +36,8 @@ std::vector<Date> random_birthdates_dates(std::size_t group_size) {
4936
for (std::size_t i = 0; i < group_size; ++i) {
5037
int m = month_dist(gen);
5138
std::uniform_int_distribution<int> day_dist(1, days_in_month[m - 1]);
52-
dates.push_back(Date{2001, m, day_dist(gen)});
39+
int d = day_dist(gen);
40+
dates.push_back(Date(2001, m, d));
5341
}
5442
return dates;
5543
}

exercises/practice/baffling-birthdays/.meta/example.h

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
11
#pragma once
22

3-
#include <iomanip>
4-
#include <sstream>
3+
#include <boost/date_time/gregorian/gregorian.hpp>
54
#include <string>
6-
#include <unordered_set>
75
#include <vector>
86

97
namespace baffling_birthdays {
108

11-
struct Date {
12-
int year;
13-
int month;
14-
int day;
15-
};
9+
using Date = boost::gregorian::date;
1610

1711
Date parse_date(const std::string& iso);
1812

19-
std::string to_string(const Date& d);
20-
2113
bool shared_birthday(const std::vector<Date>& dates);
22-
std::vector<Date> random_birthdates_dates(std::size_t group_size);
14+
std::vector<Date> random_birthdates(std::size_t group_size);
2315

2416
double estimated_probability_of_shared_birthday(std::size_t group_size);
2517

@@ -32,11 +24,12 @@ inline bool shared_birthday(const std::vector<std::string>& birthdates) {
3224
return shared_birthday(dates);
3325
}
3426

35-
inline std::vector<std::string> random_birthdates(std::size_t group_size) {
36-
auto dates = random_birthdates_dates(group_size);
27+
inline std::vector<std::string> random_birthdates_str(std::size_t group_size) {
28+
auto dates = random_birthdates(group_size);
3729
std::vector<std::string> out;
3830
out.reserve(group_size);
39-
for (auto const& d : dates) out.push_back(to_string(d));
31+
for (auto const& d : dates)
32+
out.push_back(boost::gregorian::to_iso_extended_string(d));
4033
return out;
4134
}
4235

exercises/practice/baffling-birthdays/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ cmake_minimum_required(VERSION 3.5.1)
77
# Name the project after the exercise
88
project(${exercise} CXX)
99

10+
# Locate Boost date_time library
11+
set(Boost_USE_MULTITHREADED ON)
12+
set(Boost_USE_STATIC_RUNTIME OFF)
13+
find_package(Boost 1.58 REQUIRED COMPONENTS date_time)
14+
1015
# Get a source filename from the exercise name by replacing -'s with _'s
1116
string(REPLACE "-" "_" file ${exercise})
1217

@@ -49,6 +54,12 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
4954
)
5055
endif()
5156

57+
# We need boost libraries
58+
target_link_libraries(${exercise}
59+
PRIVATE
60+
Boost::date_time
61+
)
62+
5263
# Configure to run all the tests?
5364
if(${EXERCISM_RUN_ALL_TESTS})
5465
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS)
Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,122 @@
11
#include "baffling_birthdays.h"
2+
3+
#include <boost/date_time/gregorian/gregorian.hpp>
24
#ifdef EXERCISM_TEST_SUITE
35
#include <catch2/catch.hpp>
46
#else
57
#include "test/catch.hpp"
68
#endif
79

10+
using namespace baffling_birthdays;
11+
using boost::gregorian::date;
12+
813
TEST_CASE("one_birthdate", "[716dcc2b-8fe4-4fc9-8c48-cbe70d8e6b67]") {
9-
std::vector<std::string> birthdates{"2000-01-01"};
10-
REQUIRE_FALSE(baffling_birthdays::shared_birthday(birthdates));
14+
std::vector<date> dates{date(2000, 1, 1)};
15+
REQUIRE_FALSE(shared_birthday(dates));
1116
}
1217

1318
#if defined(EXERCISM_RUN_ALL_TESTS)
1419

1520
TEST_CASE("two_birthdates_with_same_year_month_and_day",
16-
"[f7b3eb26-bcfc-4a1e-a2de-af07afc33f45]") {
17-
std::vector<std::string> birthdates{"2000-01-01", "2000-01-01"};
18-
REQUIRE(baffling_birthdays::shared_birthday(birthdates));
21+
"[f7b3eb26-bcfc-4e1e-a2de-af07afc33f45]") {
22+
std::vector<date> dates{date(2000, 1, 1), date(2000, 1, 1)};
23+
REQUIRE(shared_birthday(dates));
1924
}
2025

2126
TEST_CASE("two_birthdates_with_same_year_and_month_but_different_day",
2227
"[7193409a-6e16-4bcb-b4cc-9ffe55f79b25]") {
23-
std::vector<std::string> birthdates{"2012-05-09", "2012-05-17"};
24-
REQUIRE_FALSE(baffling_birthdays::shared_birthday(birthdates));
28+
std::vector<date> dates{date(2012, 5, 9), date(2012, 5, 17)};
29+
REQUIRE_FALSE(shared_birthday(dates));
2530
}
2631

2732
TEST_CASE("two_birthdates_with_same_month_and_day_but_different_year",
2833
"[d04db648-121b-4b72-93e8-d7d2dced4495]") {
29-
std::vector<std::string> birthdates{"1999-10-23", "1988-10-23"};
30-
REQUIRE(baffling_birthdays::shared_birthday(birthdates));
34+
std::vector<date> dates{date(1999, 10, 23), date(1988, 10, 23)};
35+
REQUIRE(shared_birthday(dates));
3136
}
3237

3338
TEST_CASE("two_birthdates_with_same_year_but_different_month_and_day",
3439
"[3c8bd0f0-14c6-4d4c-975a-4c636bfdc233]") {
35-
std::vector<std::string> birthdates{"2007-12-19", "2007-04-27"};
36-
REQUIRE_FALSE(baffling_birthdays::shared_birthday(birthdates));
40+
std::vector<date> dates{date(2007, 12, 19), date(2007, 4, 27)};
41+
REQUIRE_FALSE(shared_birthday(dates));
3742
}
3843

3944
TEST_CASE("two_birthdates_with_different_year_month_and_day",
4045
"[df5daba6-0879-4480-883c-e855c99cdaa3]") {
41-
std::vector<std::string> birthdates{"1997-08-04", "1963-11-23"};
42-
REQUIRE_FALSE(baffling_birthdays::shared_birthday(birthdates));
46+
std::vector<date> dates{date(1997, 8, 4), date(1963, 11, 23)};
47+
REQUIRE_FALSE(shared_birthday(dates));
4348
}
4449

4550
TEST_CASE("multiple_birthdates_without_shared_birthday",
4651
"[0c17b220-cbb9-4bd7-872f-373044c7b406]") {
47-
std::vector<std::string> birthdates{"1966-07-29", "1977-02-12",
48-
"2001-12-25", "1980-11-10"};
49-
REQUIRE_FALSE(baffling_birthdays::shared_birthday(birthdates));
52+
std::vector<date> dates{date(1966, 7, 29), date(1977, 2, 12),
53+
date(2001, 12, 25), date(1980, 11, 10)};
54+
REQUIRE_FALSE(shared_birthday(dates));
5055
}
5156

5257
TEST_CASE("multiple_birthdates_with_one_shared_birthday",
5358
"[966d6b0b-5c0a-4b8c-bc2d-64939ada49f8]") {
54-
std::vector<std::string> birthdates{"1966-07-29", "1977-02-12",
55-
"2001-07-29", "1980-11-10"};
56-
REQUIRE(baffling_birthdays::shared_birthday(birthdates));
59+
std::vector<date> dates{date(1966, 7, 29), date(1977, 2, 12),
60+
date(2001, 7, 29), date(1980, 11, 10)};
61+
REQUIRE(shared_birthday(dates));
5762
}
5863

5964
TEST_CASE("multiple_birthdates_with_more_than_one_shared_birthday",
6065
"[b7937d28-403b-4500-acce-4d9fe3a9620d]") {
61-
std::vector<std::string> birthdates{
62-
"1966-07-29", "1977-02-12", "2001-12-25", "1980-07-29", "2019-02-12"};
63-
REQUIRE(baffling_birthdays::shared_birthday(birthdates));
66+
std::vector<date> dates{date(1966, 7, 29), date(1977, 2, 12),
67+
date(2001, 12, 25), date(1980, 7, 29),
68+
date(2019, 2, 12)};
69+
REQUIRE(shared_birthday(dates));
6470
}
6571

6672
TEST_CASE("generate_requested_number_of_birthdates",
6773
"[70b38cea-d234-4697-b146-7d130cd4ee12]") {
6874
const std::size_t group_size = 10;
69-
auto dates = baffling_birthdays::random_birthdates(group_size);
70-
REQUIRE(dates.size() == group_size);
75+
auto d_dates = random_birthdates(group_size);
76+
REQUIRE(d_dates.size() == group_size);
7177
}
7278

7379
TEST_CASE("years_are_not_leap_years",
7480
"[d9d5b7d3-5fea-4752-b9c1-3fcd176d1b03]") {
7581
const std::size_t group_size = 1000;
76-
auto dates = baffling_birthdays::random_birthdates(group_size);
77-
for (auto const& date : dates) {
78-
REQUIRE(!(date.substr(5, 2) == "02" && date.substr(8, 2) == "29"));
82+
auto d_dates = random_birthdates(group_size);
83+
for (auto const& d : d_dates) {
84+
REQUIRE(!(d.month().as_number() == 2 && d.day() == 29));
7985
}
8086
}
8187

8288
TEST_CASE("months_are_random", "[d1074327-f68c-4c8a-b0ff-e3730d0f0521]") {
8389
const std::size_t group_size = 1000;
84-
auto d1 = baffling_birthdays::random_birthdates(group_size);
85-
auto d2 = baffling_birthdays::random_birthdates(group_size);
90+
auto d1 = random_birthdates(group_size);
91+
auto d2 = random_birthdates(group_size);
8692
REQUIRE(d1 != d2);
8793
}
8894

8995
TEST_CASE("days_are_random", "[7df706b3-c3f5-471d-9563-23a4d0577940]") {
9096
const std::size_t group_size = 1000;
91-
auto d1 = baffling_birthdays::random_birthdates(group_size);
92-
auto d2 = baffling_birthdays::random_birthdates(group_size);
97+
auto d1 = random_birthdates(group_size);
98+
auto d2 = random_birthdates(group_size);
9399
REQUIRE(d1 != d2);
94100
}
95101

96102
TEST_CASE("for_one_person", "[89a462a4-4265-4912-9506-fb027913f221]") {
97-
REQUIRE(baffling_birthdays::estimated_probability_of_shared_birthday(1) ==
98-
Approx(0.0));
103+
REQUIRE(estimated_probability_of_shared_birthday(1) == Approx(0.0));
99104
}
100105

101106
TEST_CASE("among_ten_people", "[ec31c787-0ebb-4548-970c-5dcb4eadfb5f]") {
102-
REQUIRE(baffling_birthdays::estimated_probability_of_shared_birthday(10) ==
107+
REQUIRE(estimated_probability_of_shared_birthday(10) ==
103108
Approx(11.694818).epsilon(0.01));
104109
}
105110

106111
TEST_CASE("among_twenty-three_people",
107112
"[b548afac-a451-46a3-9bb0-cb1f60c48e2f]") {
108-
REQUIRE(baffling_birthdays::estimated_probability_of_shared_birthday(23) ==
113+
REQUIRE(estimated_probability_of_shared_birthday(23) ==
109114
Approx(50.729723).epsilon(0.01));
110115
}
111116

112117
TEST_CASE("among_seventy_people", "[e43e6b9d-d77b-4f6c-a960-0fc0129a0bc5]") {
113-
REQUIRE(baffling_birthdays::estimated_probability_of_shared_birthday(70) ==
118+
REQUIRE(estimated_probability_of_shared_birthday(70) ==
114119
Approx(99.915958).epsilon(0.01));
115120
}
116121

117-
#endif
122+
#endif

0 commit comments

Comments
 (0)