Skip to content

Commit 292c654

Browse files
committed
Solve 18/07.2 and configure
1 parent 7dfadb5 commit 292c654

File tree

7 files changed

+323
-17
lines changed

7 files changed

+323
-17
lines changed

2018/.bazelrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build --cxxopt="-std=c++17"
2+
build --cxxopt="-fdiagnostics-color"
3+
build --disk_cache=/tmp/bazelcache/

2018/.clang-format

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
Language: Cpp
3+
# BasedOnStyle: Google
4+
AccessModifierOffset: -1
5+
AlignAfterOpenBracket: Align
6+
AlignConsecutiveMacros: false
7+
AlignConsecutiveAssignments: false
8+
AlignConsecutiveDeclarations: false
9+
AlignEscapedNewlines: Left
10+
AlignOperands: true
11+
AlignTrailingComments: true
12+
AllowAllArgumentsOnNextLine: true
13+
AllowAllConstructorInitializersOnNextLine: true
14+
AllowAllParametersOfDeclarationOnNextLine: true
15+
AllowShortBlocksOnASingleLine: Never
16+
AllowShortCaseLabelsOnASingleLine: false
17+
AllowShortFunctionsOnASingleLine: All
18+
AllowShortLambdasOnASingleLine: All
19+
AllowShortIfStatementsOnASingleLine: WithoutElse
20+
AllowShortLoopsOnASingleLine: true
21+
AlwaysBreakAfterDefinitionReturnType: None
22+
AlwaysBreakAfterReturnType: None
23+
AlwaysBreakBeforeMultilineStrings: true
24+
AlwaysBreakTemplateDeclarations: Yes
25+
BinPackArguments: true
26+
BinPackParameters: true
27+
BraceWrapping:
28+
AfterCaseLabel: false
29+
AfterClass: false
30+
AfterControlStatement: false
31+
AfterEnum: false
32+
AfterFunction: false
33+
AfterNamespace: false
34+
AfterObjCDeclaration: false
35+
AfterStruct: false
36+
AfterUnion: false
37+
AfterExternBlock: false
38+
BeforeCatch: false
39+
BeforeElse: false
40+
IndentBraces: false
41+
SplitEmptyFunction: true
42+
SplitEmptyRecord: true
43+
SplitEmptyNamespace: true
44+
BreakBeforeBinaryOperators: None
45+
BreakBeforeBraces: Attach
46+
BreakBeforeInheritanceComma: false
47+
BreakInheritanceList: BeforeColon
48+
BreakBeforeTernaryOperators: true
49+
BreakConstructorInitializersBeforeComma: false
50+
BreakConstructorInitializers: BeforeColon
51+
BreakAfterJavaFieldAnnotations: false
52+
BreakStringLiterals: true
53+
ColumnLimit: 80
54+
CommentPragmas: '^ IWYU pragma:'
55+
CompactNamespaces: false
56+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
57+
ConstructorInitializerIndentWidth: 4
58+
ContinuationIndentWidth: 4
59+
Cpp11BracedListStyle: true
60+
DeriveLineEnding: true
61+
DerivePointerAlignment: true
62+
DisableFormat: false
63+
ExperimentalAutoDetectBinPacking: false
64+
FixNamespaceComments: true
65+
ForEachMacros:
66+
- foreach
67+
- Q_FOREACH
68+
- BOOST_FOREACH
69+
IncludeBlocks: Regroup
70+
IncludeCategories:
71+
- Regex: '^<ext/.*\.h>'
72+
Priority: 2
73+
SortPriority: 0
74+
- Regex: '^<.*\.h>'
75+
Priority: 1
76+
SortPriority: 0
77+
- Regex: '^<.*'
78+
Priority: 2
79+
SortPriority: 0
80+
- Regex: '.*'
81+
Priority: 3
82+
SortPriority: 0
83+
IncludeIsMainRegex: '([-_](test|unittest))?$'
84+
IncludeIsMainSourceRegex: ''
85+
IndentCaseLabels: true
86+
IndentGotoLabels: true
87+
IndentPPDirectives: None
88+
IndentWidth: 2
89+
IndentWrappedFunctionNames: false
90+
JavaScriptQuotes: Leave
91+
JavaScriptWrapImports: true
92+
KeepEmptyLinesAtTheStartOfBlocks: false
93+
MacroBlockBegin: ''
94+
MacroBlockEnd: ''
95+
MaxEmptyLinesToKeep: 1
96+
NamespaceIndentation: None
97+
ObjCBinPackProtocolList: Never
98+
ObjCBlockIndentWidth: 2
99+
ObjCSpaceAfterProperty: false
100+
ObjCSpaceBeforeProtocolList: true
101+
PenaltyBreakAssignment: 2
102+
PenaltyBreakBeforeFirstCallParameter: 1
103+
PenaltyBreakComment: 300
104+
PenaltyBreakFirstLessLess: 120
105+
PenaltyBreakString: 1000
106+
PenaltyBreakTemplateDeclaration: 10
107+
PenaltyExcessCharacter: 1000000
108+
PenaltyReturnTypeOnItsOwnLine: 200
109+
PointerAlignment: Left
110+
RawStringFormats:
111+
- Language: Cpp
112+
Delimiters:
113+
- cc
114+
- CC
115+
- cpp
116+
- Cpp
117+
- CPP
118+
- 'c++'
119+
- 'C++'
120+
CanonicalDelimiter: ''
121+
BasedOnStyle: google
122+
- Language: TextProto
123+
Delimiters:
124+
- pb
125+
- PB
126+
- proto
127+
- PROTO
128+
EnclosingFunctions:
129+
- EqualsProto
130+
- EquivToProto
131+
- PARSE_PARTIAL_TEXT_PROTO
132+
- PARSE_TEST_PROTO
133+
- PARSE_TEXT_PROTO
134+
- ParseTextOrDie
135+
- ParseTextProtoOrDie
136+
CanonicalDelimiter: ''
137+
BasedOnStyle: google
138+
ReflowComments: true
139+
SortIncludes: true
140+
SortUsingDeclarations: true
141+
SpaceAfterCStyleCast: false
142+
SpaceAfterLogicalNot: false
143+
SpaceAfterTemplateKeyword: true
144+
SpaceBeforeAssignmentOperators: true
145+
SpaceBeforeCpp11BracedList: false
146+
SpaceBeforeCtorInitializerColon: true
147+
SpaceBeforeInheritanceColon: true
148+
SpaceBeforeParens: ControlStatements
149+
SpaceBeforeRangeBasedForLoopColon: true
150+
SpaceInEmptyBlock: false
151+
SpaceInEmptyParentheses: false
152+
SpacesBeforeTrailingComments: 2
153+
SpacesInAngles: false
154+
SpacesInConditionalStatement: false
155+
SpacesInContainerLiterals: true
156+
SpacesInCStyleCastParentheses: false
157+
SpacesInParentheses: false
158+
SpacesInSquareBrackets: false
159+
SpaceBeforeSquareBrackets: false
160+
Standard: Auto
161+
StatementMacros:
162+
- Q_UNUSED
163+
- QT_REQUIRE_VERSION
164+
TabWidth: 8
165+
UseCRLF: false
166+
UseTab: Never
167+
...
168+

2018/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
input/
2+
bazel-*

2018/kd/day7.cc

+113-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "kd/day7.h"
22

33
#include <functional>
4+
#include <iostream>
5+
#include <optional>
46
#include <queue>
57
#include <regex>
68
#include <string>
@@ -17,8 +19,7 @@ using PQ = std::priority_queue<Node, std::vector<Node>, std::greater<Node>>;
1719

1820
Graph BuildDependencyGraph(const std::vector<std::string>& lines) {
1921
static const std::regex re(
20-
R"(^Step ([A-Z]) must be finished before step ([A-Z]) can begin.$)"
21-
);
22+
R"(^Step ([A-Z]) must be finished before step ([A-Z]) can begin.$)");
2223
Graph g;
2324
for (const auto& line : lines) {
2425
std::smatch match;
@@ -81,5 +82,115 @@ std::vector<Node> Kahn(const Graph& graph) {
8182
return result;
8283
}
8384

85+
int NodeTime(const Node& node) { return node[0] - 'A' + 1; }
86+
87+
class Worker {
88+
public:
89+
Worker() : timer_{0}, work_{std::nullopt} {}
90+
91+
bool busy() const { return timer_ != 0; }
92+
93+
void Start(int timer, Node&& work) {
94+
timer_ = timer;
95+
work_.emplace(std::forward<Node>(work));
96+
}
97+
98+
std::optional<Node> Tick() {
99+
if (!busy()) {
100+
return std::nullopt;
101+
}
102+
--timer_;
103+
if (busy()) {
104+
return std::nullopt;
105+
}
106+
// Done with work
107+
std::optional<Node> result;
108+
std::swap(result, work_);
109+
return result;
110+
}
111+
112+
public:
113+
int timer_;
114+
std::optional<Node> work_;
115+
};
116+
117+
class Scheduler {
118+
public:
119+
explicit Scheduler(const Graph& graph) : graph_(&graph) {
120+
for (const auto& node_and_adj : graph) {
121+
for (const Node& node : node_and_adj.second) {
122+
++incoming_[node];
123+
}
124+
}
125+
std::vector<Node> zero_incoming;
126+
for (const auto& node_and_adj : graph) {
127+
const Node& node = node_and_adj.first;
128+
if (incoming_[node] == 0) {
129+
zero_incoming.push_back(node);
130+
}
131+
}
132+
pq_ = PQ(zero_incoming.begin(), zero_incoming.end());
133+
}
134+
135+
// Doesn't account for tasks that are still being worked on.
136+
bool Done() const { return seen_.size() == graph_->size(); }
137+
138+
bool HasWork() const { return !pq_.empty(); }
139+
140+
// Calling code has to make sure HasWork()
141+
Node GetWork() {
142+
Node n = pq_.top();
143+
pq_.pop();
144+
seen_.insert(n);
145+
return n;
146+
}
147+
148+
void Finish(Node n) {
149+
const auto it_adj = graph_->find(n);
150+
if (it_adj == graph_->end()) {
151+
return;
152+
}
153+
for (const Node& n : it_adj->second) {
154+
int x = --incoming_[n];
155+
if (x == 0) {
156+
pq_.push(n);
157+
}
158+
}
159+
}
160+
161+
private:
162+
const Graph* const graph_;
163+
std::unordered_map<Node, int> incoming_;
164+
std::unordered_set<Node> seen_;
165+
PQ pq_;
166+
};
167+
168+
int TimeKahnWithWorkers(const TimerFunction& timer, const Graph& graph,
169+
int num_workers) {
170+
int time = -1;
171+
std::vector<Worker> workers(num_workers);
172+
Scheduler sched(graph);
173+
bool any_worker_busy = false;
174+
while (!sched.Done() || any_worker_busy) {
175+
any_worker_busy = false;
176+
++time;
177+
for (Worker& worker : workers) {
178+
auto maybe_finished = worker.Tick();
179+
if (maybe_finished) {
180+
sched.Finish(*maybe_finished);
181+
}
182+
if (worker.busy()) {
183+
any_worker_busy = true;
184+
} else if (sched.HasWork()) {
185+
Node work = sched.GetWork();
186+
int t = timer(work);
187+
worker.Start(t, std::move(work));
188+
any_worker_busy = true;
189+
}
190+
}
191+
}
192+
return time;
193+
}
194+
84195
} // namespace day7
85196
} // namespace kd

2018/kd/day7.h

+11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ std::string Join(const std::vector<Node>& nodes);
2020

2121
std::vector<Node> Kahn(const Graph& graph);
2222

23+
// -------
24+
// Part II
25+
// -------
26+
27+
using TimerFunction = std::function<int(const Node&)>;
28+
29+
int NodeTime(const Node& node);
30+
31+
int TimeKahnWithWorkers(const TimerFunction& timer, const Graph& graph,
32+
int num_workers);
33+
2334
} // namespace day7
2435
} // namespace kd
2536

2018/kd/day7_main.cc

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
#include "kd/day7.h"
2-
31
#include <iostream>
42
#include <string>
53
#include <vector>
64

5+
#include "kd/day7.h"
76

8-
int main(int argc, char *argv[]) {
7+
constexpr int kNumWorkers = 10;
8+
9+
int main(int argc, char* argv[]) {
910
std::vector<std::string> lines;
1011
std::string line;
1112
while (std::getline(std::cin, line)) {
1213
lines.push_back(line);
1314
}
15+
const auto graph = kd::day7::BuildDependencyGraph(lines);
16+
17+
const std::string result = kd::day7::Join(kd::day7::Kahn(graph));
18+
std::cout << result << std::endl;
1419

15-
const std::string result = kd::day7::Join(
16-
kd::day7::Kahn(
17-
kd::day7::BuildDependencyGraph(lines)
18-
)
19-
);
20-
std::cout << result << '\n';
20+
const int result2 = kd::day7::TimeKahnWithWorkers(
21+
[](const auto& node) { return 60 + node[0] - 'A' + 1; }, graph,
22+
kNumWorkers);
23+
std::cout << result2 << std::endl;
2124
}

0 commit comments

Comments
 (0)