Skip to content

Commit

Permalink
Solution for advent of code day 3, both parts.
Browse files Browse the repository at this point in the history
  • Loading branch information
zygoloid committed Dec 19, 2024
1 parent f874b98 commit 3868e7c
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 16 deletions.
16 changes: 16 additions & 0 deletions examples/advent2024/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,19 @@ carbon_binary(
"day2_part2.carbon",
] + utils,
)

carbon_binary(
name = "day3_part1",
srcs = [
"day3_common.carbon",
"day3_part1.carbon",
] + utils,
)

carbon_binary(
name = "day3_part2",
srcs = [
"day3_common.carbon",
"day3_part2.carbon",
] + utils,
)
45 changes: 45 additions & 0 deletions examples/advent2024/day3_common.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

library "day3_common";

import library "io_utils";

// Reads "mul(a,b)", and returns (true, a, b).
// On error, stops before the first invalid character and returns (false, 0, 0).
// TODO: -> Optional((i32, i32))
fn ReadMul() -> (bool, i32, i32) {
var a: i32;
var b: i32;
if (ConsumeChar(0x6D) and ConsumeChar(0x75) and ConsumeChar(0x6C) and
ConsumeChar(0x28) and ReadInt(&a) and ConsumeChar(0x2C) and
ReadInt(&b) and ConsumeChar(0x29)) {
return (true, a, b);
}
return (false, 0, 0);
}

// Reads "do()" or "don't()", and returns (true, was_do).
// On error, stops before the first invalid character and returns (false, false).
fn ReadDoOrDont() -> (bool, bool) {
// "do"
if (not ConsumeChar(0x64) or not ConsumeChar(0x6F)) {
return (false, false);
}

var do: bool = true;
// "n't"
if (ConsumeChar(0x6E)) {
if (not ConsumeChar(0x27) or not ConsumeChar(0x74)) {
return (false, false);
}
do = false;
}

// "()"
if (not ConsumeChar(0x28) or not ConsumeChar(0x29)) {
return (false, false);
}
return (true, do);
}
24 changes: 24 additions & 0 deletions examples/advent2024/day3_part1.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

import Core library "io";

import library "day3_common";
import library "io_utils";

fn Run() {
var total: i32 = 0;
while (PeekChar() != Core.EOF()) {
if (PeekChar() == 0x6D) {
// TODO: Use `if let` when available.
let result: (bool, i32, i32) = ReadMul();
if (result.0) {
total += result.1 * result.2;
}
} else {
ReadChar();
}
}
Core.Print(total);
}
31 changes: 31 additions & 0 deletions examples/advent2024/day3_part2.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

import Core library "io";

import library "day3_common";
import library "io_utils";

fn Run() {
var total: i32 = 0;
var enabled: bool = true;
while (PeekChar() != Core.EOF()) {
if (PeekChar() == 0x6D) {
// TODO: Use `if let` when available.
let result: (bool, i32, i32) = ReadMul();
if (result.0 and enabled) {
total += result.1 * result.2;
}
} else if (PeekChar() == 0x64) {
// TODO: Use `if let` when available.
let result: (bool, bool) = ReadDoOrDont();
if (result.0) {
enabled = result.1;
}
} else {
ReadChar();
}
}
Core.Print(total);
}
35 changes: 19 additions & 16 deletions examples/advent2024/io_utils.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,33 @@ fn ReadInt(p: i32*) -> bool {
return read_any_digits;
}

fn PeekChar() -> i32 {
var next: i32 = ReadChar();
UnreadChar(next);
return next;
}

fn ConsumeChar(c: i32) -> bool {
var next: i32 = ReadChar();
if (next != c) {
UnreadChar(next);
return false;
}
return true;
}

fn SkipSpaces() -> bool {
var skipped_any_spaces: bool = false;
while (true) {
var c: i32 = ReadChar();
if (c != 0x20) {
UnreadChar(c);
break;
}
while (ConsumeChar(0x20)) {
skipped_any_spaces = true;
}
return skipped_any_spaces;
}

fn SkipNewline() -> bool {
var c: i32 = ReadChar();
// Optional carriage return.
if (c == 0x0D) {
c = ReadChar();
}
ConsumeChar(0x0D);
// Newline.
if (c == 0x0A) {
return true;
}
// TODO: Unread the CR?
UnreadChar(c);
return false;
// TODO: Unread the CR if it was present?
return ConsumeChar(0x0A);
}

0 comments on commit 3868e7c

Please sign in to comment.