1
1
#include " common.h"
2
2
#include < gmpxx.h>
3
3
4
- // I SOLVED THE PROBLEM BUT WAS TRYING TO BE AS FUNCTIONAL AS POSSIBLE BUT.. c++
5
4
namespace {
6
5
constexpr size_t MaxSize{1024 };
7
6
#define ASSERT_SCAN (expr, err ) \
8
7
if ((expr) == 0 ) \
9
8
throw std::runtime_error ((err));
10
9
11
- size_t play (long &worry, auto amplify, auto pacify, int test, size_t test_true,
12
- size_t test_false) {
13
- worry = amplify (worry);
14
- worry = pacify (worry);
15
- return ((worry % test) == 0 ) ? test_true : test_false;
16
- };
17
-
18
10
struct Monkey {
19
- decltype (play) play;
11
+ char op;
12
+ int wrry;
13
+ int test;
14
+ size_t test_true;
15
+ size_t test_false;
20
16
long inspects{};
21
17
};
22
18
23
- // parse with input
24
- // send the mkys array
25
- // send the items array
26
- void parse (const auto &input, auto &mkys, auto &items) {
27
- using namespace std ::placeholders;
28
-
29
- for (size_t i{0 }; i < input.size (); i += 7 ) {
30
- size_t j = i / 7UL ;
31
- auto &m = mkys[j];
32
- {
33
- std::istringstream ss{input[i + 1 ]};
34
- std::string s, _;
35
- ss >> _ >> _;
36
- while (ss >> s) {
37
- if (s[s.size () - 1 ] == ' ,' )
38
- s.resize (s.size () - 1 );
39
- long l{};
40
- std::from_chars (s.data (), s.data () + s.size (), l);
41
- items.emplace_back (std::make_tuple (j, l));
42
- }
43
- }
44
-
45
- char c;
46
- long w;
47
- auto scans = std::sscanf (input[i + 2 ].c_str (),
48
- " Operation: new = old %c %d" , &c, &w);
49
- switch (c) {
50
- case ' +' :
51
- auto f = std::bind (std::plus{}, w, _1);
52
- m.play = std::bind (play, _1, f, _2, _3, _4, _5);
53
- break ;
54
- case ' *' :
55
- if (scans != 2 ) {
56
- auto f = [](long worry) { return std::multiplies{}(worry, worry); };
57
- m.play = std::bind (play, _1, f, _2, _3, _4, _5)
58
- } else {
59
- auto f = std::bind (std::multiplies{}, w, _1);
60
- m.play = std::bind (play, _1, f, _2, _3, _4, _5)
61
- }
62
- default :
63
- throw std::runtime_error (" unknow operator " + m.op );
64
- }
65
-
66
- int t;
67
- size_t tt, tf;
68
- ASSERT_SCAN (
69
- std::sscanf (input[i + 3 ].c_str (), " Test: divisible by %d" , &t),
70
- " no test" );
71
- ASSERT_SCAN (std::sscanf (input[i + 4 ].c_str (),
72
- " If true: throw to monkey %lu" , &tt),
73
- " no true" );
74
- ASSERT_SCAN (std::sscanf (input[i + 5 ].c_str (),
75
- " If false: throw to monkey %lu" , &tf),
76
- " no false" );
77
- std::bind (m.play , _1, _2, t, tt, tf);
78
- }
79
- }
80
-
81
- template <size_t N, size_t M> long p1 (const auto &input) {
19
+ template <size_t N, size_t M, bool p2> long p (const auto &input) {
82
20
std::array<Monkey, M> mkys{};
83
21
std::vector<std::tuple<size_t , long >> items{};
84
22
for (size_t i{0 }; i < input.size (); i += 7 ) {
@@ -132,7 +70,11 @@ template <size_t N, size_t M> long p1(const auto &input) {
132
70
default :
133
71
throw std::runtime_error (" unknow operator " + m.op );
134
72
}
135
- w %= (11 * 5 * 19 * 13 * 7 * 17 * 2 * 3 );
73
+ if (p2) {
74
+ w %= (11 * 5 * 19 * 13 * 7 * 17 * 2 * 3 );
75
+ } else {
76
+ w /= 3 ;
77
+ }
136
78
const auto &tgt = ((w % m.test ) == 0 ) ? m.test_true : m.test_false ;
137
79
std::get<0 >(item) = tgt;
138
80
++ins;
@@ -147,5 +89,6 @@ template <size_t N, size_t M> long p1(const auto &input) {
147
89
148
90
int main () {
149
91
const auto &input = gb::advent2021::readIn ();
150
- gb::advent2021::writeOut (std::to_string (p1<10000 , 8 >(input)));
92
+ gb::advent2021::writeOut (std::to_string (p<20 , 8 , false >(input)));
93
+ gb::advent2021::writeOut (std::to_string (p<10000 , 8 , true >(input)));
151
94
}
0 commit comments