Skip to content

Commit ce44aae

Browse files
committed
Day 9
1 parent ede071a commit ce44aae

File tree

6 files changed

+218
-0
lines changed

6 files changed

+218
-0
lines changed

AdventOfCode23.cabal

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,8 @@ executable Day6
8383
import: warnings, dependencies
8484
main-is: Main.hs
8585
hs-source-dirs: Day6
86+
87+
executable Day9
88+
import: warnings, dependencies
89+
main-is: Main.hs
90+
hs-source-dirs: Day9

Day9/Main.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module Main where
2+
3+
-- https://stackoverflow.com/questions/9512513/how-do-you-compute-the-difference-between-successive-elements-of-a-list-of-unkno
4+
diffs :: Num a => [a] -> [a]
5+
diffs [] = []
6+
diffs l = zipWith (-) (tail l) l
7+
8+
part1 :: [[Int]] -> Int
9+
part1 = sum . map f
10+
where
11+
f [] = 0
12+
f xs | all (0 ==) xs = 0
13+
| otherwise = last xs + f (diffs xs)
14+
15+
part2 :: [[Int]] -> Int
16+
part2 = sum . map f
17+
where
18+
f [] = 0
19+
f xs | all (0 ==) xs = 0
20+
| otherwise = head xs - f (diffs xs)
21+
22+
main :: IO ()
23+
main = do
24+
input <- map (map read . words) . lines <$> getContents
25+
putStrLn $ "Part 1: " ++ show (part1 input)
26+
putStrLn $ "Part 2: " ++ show (part2 input)

Day9/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CC = g++-13
2+
CFLAGS = -O2 -std=c++20 -Wall
3+
4+
all: sol
5+
6+
sol: sol.cpp
7+
$(CC) $(CFLAGS) -o sol sol.cpp
8+
9+
gen: gen.cpp
10+
$(CC) $(CFLAGS) -o gen gen.cpp
11+
12+
brute: brute.cpp
13+
$(CC) $(CFLAGS) -o brute brute.cpp
14+
15+
clean:
16+
$(RM) sol gen brute

Day9/old.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
using ll = long long;
4+
5+
// Template
6+
#define REP(n) for (int _=0; _<(n); _++)
7+
#define FOR(i, a, b) for (int i=a; i<(b); i++)
8+
#define F0R(i, a) for (int i=0; i<(a); i++)
9+
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
10+
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
11+
12+
#define sz(x) (int)(x).size()
13+
#define all(x) x.begin(), x.end()
14+
15+
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
16+
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
17+
18+
namespace std {
19+
template<class Fun>
20+
class y_combinator_result {
21+
Fun fun_;
22+
public:
23+
template<class T>
24+
explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {}
25+
26+
template<class ...Args>
27+
decltype(auto) operator()(Args &&...args) {
28+
return fun_(std::ref(*this), std::forward<Args>(args)...);
29+
}
30+
};
31+
32+
template<class Fun>
33+
decltype(auto) y_combinator(Fun &&fun) {
34+
return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
35+
}
36+
} // namespace std
37+
38+
#define DEBUG(x) cerr << #x << ": " << x << '\n'
39+
template<typename A, typename B>
40+
ostream& operator<<(ostream &os, const pair<A, B> &p) {
41+
return os << '(' << p.first << ", " << p.second << ')';
42+
}
43+
template<typename T_container,
44+
typename T = typename enable_if<!is_same<T_container, string>::value,
45+
typename T_container::value_type>::type>
46+
ostream& operator<<(ostream &os, const T_container &v) {
47+
os << '['; string sep;
48+
for (const T &x : v)
49+
os << sep << x, sep = ", ";
50+
return os << ']';
51+
}
52+
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
53+
54+
vector<ll> diff(vector<ll> A) {
55+
vector<ll> B;
56+
for (int i = 1; i < sz(A); i++) {
57+
B.push_back(A[i] - A[i-1]);
58+
}
59+
return B;
60+
}
61+
62+
ll solve(vector<ll> A) {
63+
if (all_of(A.begin(), A.end(), [&](ll x) { return x == 0; })) return 0;
64+
auto B = diff(A);
65+
return A.back() + solve(B);
66+
}
67+
68+
int main() {
69+
ios_base::sync_with_stdio(false); cin.tie(NULL);
70+
string line;
71+
72+
ll ans = 0;
73+
while (getline(cin, line)) {
74+
stringstream ss(line);
75+
vector<ll> A;
76+
ll x;
77+
while (ss >> x) {
78+
A.push_back(x);
79+
}
80+
ans += solve(A);
81+
}
82+
cout << ans << '\n';
83+
}

Day9/sol.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
using ll = long long;
4+
5+
// Template
6+
#define REP(n) for (int _=0; _<(n); _++)
7+
#define FOR(i, a, b) for (int i=a; i<(b); i++)
8+
#define F0R(i, a) for (int i=0; i<(a); i++)
9+
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
10+
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
11+
12+
#define sz(x) (int)(x).size()
13+
#define all(x) x.begin(), x.end()
14+
15+
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
16+
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
17+
18+
namespace std {
19+
template<class Fun>
20+
class y_combinator_result {
21+
Fun fun_;
22+
public:
23+
template<class T>
24+
explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {}
25+
26+
template<class ...Args>
27+
decltype(auto) operator()(Args &&...args) {
28+
return fun_(std::ref(*this), std::forward<Args>(args)...);
29+
}
30+
};
31+
32+
template<class Fun>
33+
decltype(auto) y_combinator(Fun &&fun) {
34+
return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
35+
}
36+
} // namespace std
37+
38+
#define DEBUG(x) cerr << #x << ": " << x << '\n'
39+
template<typename A, typename B>
40+
ostream& operator<<(ostream &os, const pair<A, B> &p) {
41+
return os << '(' << p.first << ", " << p.second << ')';
42+
}
43+
template<typename T_container,
44+
typename T = typename enable_if<!is_same<T_container, string>::value,
45+
typename T_container::value_type>::type>
46+
ostream& operator<<(ostream &os, const T_container &v) {
47+
os << '['; string sep;
48+
for (const T &x : v)
49+
os << sep << x, sep = ", ";
50+
return os << ']';
51+
}
52+
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
53+
54+
vector<ll> diff(vector<ll> A) {
55+
vector<ll> B;
56+
for (int i = 1; i < sz(A); i++) {
57+
B.push_back(A[i] - A[i-1]);
58+
}
59+
return B;
60+
}
61+
62+
ll solve(vector<ll> A) {
63+
if (all_of(A.begin(), A.end(), [&](ll x) { return x == 0; })) return 0;
64+
auto B = diff(A);
65+
return A[0] - solve(B);
66+
}
67+
68+
int main() {
69+
ios_base::sync_with_stdio(false); cin.tie(NULL);
70+
string line;
71+
72+
ll ans = 0;
73+
while (getline(cin, line)) {
74+
stringstream ss(line);
75+
vector<ll> A;
76+
ll x;
77+
while (ss >> x) {
78+
A.push_back(x);
79+
}
80+
ans += solve(A);
81+
}
82+
cout << ans << '\n';
83+
}

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Unless otherwise specified, programs read from standard input and print to stand
1919
| 6 | 00:03:11 / 00:06:50 | 102 / 354 |
2020
| 7 | 00:14:08 / 00:28:48 | 333 / 726 |
2121
| 8 | 00:02:53 / 00:56:12 | 35 / 4397 |
22+
| 9 | 00:05:44 / 00:06:52 | 295 / 191 |
2223

2324
### Day 7 (Camel Cards)
2425

@@ -38,3 +39,7 @@ Part 1 is a quick implementation exercise.
3839
Part 2 seems nearly intractable in the general case. After sitting for a while being confused why the problem was so hard, I looked at the inputs and discovered there were only 6 "A"-rooms, and their paths/cycles were disjoint, and only contained one "Z"-room, *and* the lengths of the cycles are equal to the distance to the "Z"-room!
3940
Therefore the problem reduces to a CRT problem, which itself degenerates to an LCM calculation.
4041

42+
### Day 9 (Mirage Maintenance)
43+
44+
This was a pretty straightforward problem. Unfortunately my performance was hindered by my slow typing today.
45+
I was also unsure how to handle a case where the list would become empty before we hit all zeros (e.g, `1 2`), but I eventually assumed this wouldn't be a problem and chugged on.

0 commit comments

Comments
 (0)