Created
December 2, 2023 19:34
-
-
Save RNGKing/19500e0e4f9e70c2d81793947d123513 to your computer and use it in GitHub Desktop.
AoC in Gleam
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import simplifile as file | |
import gleam/string | |
import gleam/regex.{type Regex} | |
import gleam/io | |
import gleam/list | |
import gleam/int | |
import gleam/bool | |
pub type Game { | |
Game(id: Int, red: Int, blue: Int, green: Int) | |
} | |
pub type GameRules { | |
GameRules(total_blue: Int, total_red: Int, total_green: Int) | |
} | |
pub type GameRegex { | |
GameRegex( | |
game_id: Regex, | |
blue_regex: Regex, | |
red_regex: Regex, | |
green_regex: Regex, | |
number_regex: Regex, | |
) | |
} | |
fn get_game_regex() -> GameRegex { | |
let assert Ok(game_id_regex) = regex.from_string("(Game [0-9]+)") | |
let assert Ok(blue_regex) = regex.from_string("([0-9]+ blue)") | |
let assert Ok(red_regex) = regex.from_string("([0-9]+ red)") | |
let assert Ok(green_regex) = regex.from_string("([0-9]+ green)") | |
let assert Ok(number_regex) = regex.from_string("([0-9]+)") | |
GameRegex(game_id_regex, blue_regex, red_regex, green_regex, number_regex) | |
} | |
fn parse_file_to_games(file_path: String) -> List(Game) { | |
let game_regex: GameRegex = get_game_regex() | |
let assert Ok(file_data) = file.read(file_path) | |
file_data | |
|> string.split("\n") | |
|> list.map(fn(line) { parse_string_to_game(line, game_regex) }) | |
} | |
fn parse_string_to_game(line: String, gex: GameRegex) -> Game { | |
let game_id = sum_matches(line, gex.game_id, gex.number_regex) | |
let blue_count = sum_matches(line, gex.blue_regex, gex.number_regex) | |
let red_count = sum_matches(line, gex.red_regex, gex.number_regex) | |
let green_count = sum_matches(line, gex.green_regex, gex.number_regex) | |
Game(game_id, blue_count, red_count, green_count) | |
} | |
fn sum_matches(line: String, c_regex: Regex, number_regex: Regex) -> Int { | |
regex.scan(c_regex, line) | |
|> list.map(fn(match) { match.content }) | |
|> list.map(fn(content) { | |
regex.scan(number_regex, content) | |
|> list.map(fn(match) { match.content }) | |
|> list.map(fn(number) { parse_string_to_int(number) }) | |
}) | |
|> list.flatten | |
|> int.sum | |
} | |
fn parse_string_to_int(input: String) { | |
let assert Ok(output) = int.parse(input) | |
output | |
} | |
pub fn day_2_runner_test() { | |
part_one("./data/day_2/part_one_sample.dat") | |
part_one("./data/day_2/day_two_input.dat") | |
} | |
fn part_one(file_path: String) { | |
let game_rules = GameRules(14, 12, 13) | |
parse_file_to_games(file_path) | |
|> list.filter(fn(game) { | |
use <- bool.guard(when: game.blue >= game_rules.total_blue, return: False) | |
use <- bool.guard(when: game.red >= game_rules.total_red, return: False) | |
use <- bool.guard(when: game.green >= game_rules.total_green, return: False) | |
True | |
}) | |
|> list.map(fn(game) { game.id }) | |
|> int.sum | |
|> io.debug | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment