summaryrefslogtreecommitdiff
path: root/2020/src/bin/day_5.rs
blob: 15c8a703b030989fd8c887ced08f8b1eba412060 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use bevy::prelude::*;
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    App::build()
        .add_resource(WindowDescriptor {
            title: "Advent of Code".to_string(),
            width: 1920,
            height: 1080,
            ..Default::default()
        })
        .add_resource(ClearColor(Color::rgb(0., 0., 0.)))
        .add_startup_system(setup_camera.system())
        .add_startup_system(read_input_file.system())
        .add_startup_stage("search")
        .add_startup_system_to_stage("search", find_unoccupied_seat.system())
        .add_startup_stage("metadata")
        .add_startup_system_to_stage("metadata", add_seat_ids.system())
        .add_startup_system_to_stage("metadata", add_seat_sprites.system())
        .add_startup_stage("report")
        .add_startup_system_to_stage("report", print_highest_seat_id.system())
        .add_startup_system_to_stage("report", print_my_seat_id.system())
        .add_plugins(DefaultPlugins)
        .run();
}

fn setup_camera(mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
    commands.spawn(Camera2dComponents {
        transform: Transform::from_translation(Vec3::new(80. / 2., 1280. / 2., 0.)),
        ..Default::default()
    });

    commands.insert_resource(Materials {
        my_seat_material: materials.add(Color::rgb(0., 0., 255.).into()),
        seat_material: materials.add(Color::rgb(0., 255., 0.).into()),
    });
}

struct Materials {
    my_seat_material: Handle<ColorMaterial>,
    seat_material: Handle<ColorMaterial>,
}

#[derive(PartialEq, Eq)]
struct Position {
    x: u32,
    y: u32,
}
struct SeatId(u32);
struct MySeat;

fn read_input_file(mut commands: Commands) {
    let f = File::open("./inputs/day_5.txt").unwrap();
    for line in BufReader::new(f).lines() {
        let mut max_y = 128;
        let mut min_y = 0;
        let mut max_x = 8;
        let mut min_x = 0;
        for c in line.unwrap().trim().chars() {
            let mid_x = (min_x + max_x) / 2;
            let mid_y = (min_y + max_y) / 2;
            match c {
                'F' => {
                    max_y = mid_y;
                }
                'B' => {
                    min_y = mid_y;
                }
                'L' => {
                    max_x = mid_x;
                }
                'R' => {
                    min_x = mid_x;
                }
                _ => panic!("Unexpected character {}", c),
            }
        }

        assert_eq!(max_y - min_y, 1);
        assert_eq!(max_x - min_x, 1);

        commands.spawn((Position { x: min_x, y: min_y },));
    }
}

fn find_unoccupied_seat(mut commands: Commands, seats: Query<&Position>) {
    for y in 1..127 {
        for x in 0..8 {
            let potential_position = Position { x, y };
            let required_left = if x == 0 {
                Position { x: 7, y: y - 1 }
            } else {
                Position { x: x - 1, y }
            };
            let required_right = if x == 7 {
                Position { x: 0, y: y + 1 }
            } else {
                Position { x: x + 1, y }
            };

            let required_surrounds = [required_left, required_right];
            if !seats.iter().any(|p| p == &potential_position) {
                if required_surrounds
                    .iter()
                    .all(|required| seats.iter().any(|p| p == required))
                {
                    commands.spawn((MySeat, potential_position));
                }
            }
        }
    }
}

fn add_seat_ids(mut commands: Commands, seats: Query<(Entity, &Position)>) {
    for (entity, position) in seats.iter() {
        let seat_id = position.y * 8 + position.x;
        commands.insert_one(entity, SeatId(seat_id));
    }
}

fn add_seat_sprites(
    mut commands: Commands,
    materials: Res<Materials>,
    seats: Query<(Entity, &Position, Option<&MySeat>)>,
) {
    for (entity, position, my_seat) in seats.iter() {
        commands.insert(
            entity,
            SpriteComponents {
                sprite: Sprite::new(Vec2::new(10., 10.)),
                material: if my_seat.is_some() {
                    materials.my_seat_material.clone()
                } else {
                    materials.seat_material.clone()
                },
                transform: Transform::from_translation(Vec3::new(
                    position.x as f32 * 10.,
                    position.y as f32 * 10.,
                    0.,
                )),
                ..Default::default()
            },
        );
    }
}

fn print_highest_seat_id(seats: Query<&SeatId>) {
    let max = seats.iter().map(|s| s.0).max();
    println!("Max seat id: {:?}", max);
}

fn print_my_seat_id(seats: Query<With<MySeat, &SeatId>>) {
    for seat_id in seats.iter() {
        println!("My seat id: {}", seat_id.0);
    }
}