Skip to content

Commit

Permalink
Refactor examples and add a README.
Browse files Browse the repository at this point in the history
  • Loading branch information
zygoloid committed Dec 13, 2024
1 parent 53d3858 commit 10378f2
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 238 deletions.
15 changes: 13 additions & 2 deletions examples/advent2024/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@

load("//bazel/carbon_rules:defs.bzl", "carbon_binary")

utils = [
"io_utils.carbon",
"sort.carbon",
]

carbon_binary(
name = "day1_part1",
srcs = ["day1_part1.carbon"],
srcs = [
"day1_common.carbon",
"day1_part1.carbon",
] + utils,
)

carbon_binary(
name = "day1_part2",
srcs = ["day1_part2.carbon"],
srcs = [
"day1_common.carbon",
"day1_part2.carbon",
] + utils,
)
17 changes: 17 additions & 0 deletions examples/advent2024/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Advent of Code 2024

<!--
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
-->

This directory contains sample solutions written in Carbon for
[Advent of Code 2024](https://adventofcode.com/2024/).

The Carbon toolchain is in a very early state, so these samples frequently need
to work around missing functionality and are not reflective of expected Carbon
style and idioms. Instead, the purpose of these examples are to test the current
state of the toolchain against larger code examples than those that are present
in the toolchain's own tests, to find bugs in the toolchain, and to drive
feature development in the toolchain by presenting somewhat realistic testcases.
21 changes: 21 additions & 0 deletions examples/advent2024/day1_common.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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 "day1_common";

import library "io_utils";

// Read a sequence of lines each containing a pair of numbers into two arrays.
// Returns the number of lines read.
fn ReadInputs(ap: [i32; 1000]*, bp: [i32; 1000]*) -> i32 {
var n: i32 = 0;
var a: i32;
var b: i32;
while (n < 1000 and ReadInt(&a) and SkipSpaces() and ReadInt(&b) and SkipNewline()) {
(*ap)[n] = a;
(*bp)[n] = b;
++n;
}
return n;
}
120 changes: 2 additions & 118 deletions examples/advent2024/day1_part1.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -4,128 +4,12 @@

import Core library "io";

var push_back: i32 = Core.EOF();

fn ReadCharRaw() -> i32 = "read.char";

fn ReadChar() -> i32 {
var next: i32 = push_back;
push_back = Core.EOF();
if (next == Core.EOF()) {
next = ReadCharRaw();
}
return next;
}

fn UnreadChar(c: i32) {
// TODO: assert(push_back == Core.EOF());
push_back = c;
}

fn ReadInt(p: i32*) -> bool {
var read_any_digits: bool = false;
*p = 0;

while (true) {
var c: i32 = ReadChar();
if (c < 0x30 or c > 0x39) {
UnreadChar(c);
break;
}
// TODO: Check for overflow.
*p *= 10;
*p += c - 0x30;
read_any_digits = true;
}
return read_any_digits;
}

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

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

// let N:! i32 = 1000;
// TODO: let Array:! type = [i32; N];

// Read a sequence of lines each containing a pair of numbers into two arrays.
// Returns the number of lines read.
fn ReadInputs(ap: [i32; 1000]*, bp: [i32; 1000]*) -> i32 {
var n: i32 = 0;
var a: i32;
var b: i32;
while (n < 1000 and ReadInt(&a) and SkipSpaces() and ReadInt(&b) and SkipNewline()) {
(*ap)[n] = a;
(*bp)[n] = b;
++n;
}
return n;
}

fn Swap(p: [i32; 1000]*, from: i32, to: i32) {
var tmp: i32 = (*p)[from];
(*p)[from] = (*p)[to];
(*p)[to] = tmp;
}

fn Partition(p: [i32; 1000]*, from_in: i32, to_in: i32) -> i32 {
var pivot_index: i32 = from_in;
var pivot: i32 = (*p)[pivot_index];
var from: i32 = from_in + 1;
var to: i32 = to_in;
while (from < to) {
if ((*p)[from] <= pivot) {
++from;
} else if ((*p)[to - 1] > pivot) {
--to;
} else {
// Element at `from` is > pivot, and
// element at `to` is <= pivot.
Swap(p, from, to - 1);
++from;
--to;
}
}
Swap(p, pivot_index, from - 1);
return from - 1;
}

fn Quicksort(p: [i32; 1000]*, from: i32, to: i32) {
if (from + 1 >= to) { return; }
var pivot: i32 = Partition(p, from, to);
Quicksort(p, from, pivot);
Quicksort(p, pivot + 1, to);
}
import library "day1_common";
import library "sort";

fn Abs(n: i32) -> i32 { return if n < 0 then -n else n; }

fn Run() {
// TODO: Global initialization is not implemented yet.
push_back = Core.EOF();

var a: [i32; 1000];
var b: [i32; 1000];
var n: i32 = ReadInputs(&a, &b);
Expand Down
120 changes: 2 additions & 118 deletions examples/advent2024/day1_part2.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -4,126 +4,10 @@

import Core library "io";

var push_back: i32 = Core.EOF();

fn ReadCharRaw() -> i32 = "read.char";

fn ReadChar() -> i32 {
var next: i32 = push_back;
push_back = Core.EOF();
if (next == Core.EOF()) {
next = ReadCharRaw();
}
return next;
}

fn UnreadChar(c: i32) {
// TODO: assert(push_back == Core.EOF());
push_back = c;
}

fn ReadInt(p: i32*) -> bool {
var read_any_digits: bool = false;
*p = 0;

while (true) {
var c: i32 = ReadChar();
if (c < 0x30 or c > 0x39) {
UnreadChar(c);
break;
}
// TODO: Check for overflow.
*p *= 10;
*p += c - 0x30;
read_any_digits = true;
}
return read_any_digits;
}

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

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

// let N:! i32 = 1000;
// TODO: let Array:! type = [i32; N];

// Read a sequence of lines each containing a pair of numbers into two arrays.
// Returns the number of lines read.
fn ReadInputs(ap: [i32; 1000]*, bp: [i32; 1000]*) -> i32 {
var n: i32 = 0;
var a: i32;
var b: i32;
while (n < 1000 and ReadInt(&a) and SkipSpaces() and ReadInt(&b) and SkipNewline()) {
(*ap)[n] = a;
(*bp)[n] = b;
++n;
}
return n;
}

fn Swap(p: [i32; 1000]*, from: i32, to: i32) {
var tmp: i32 = (*p)[from];
(*p)[from] = (*p)[to];
(*p)[to] = tmp;
}

fn Partition(p: [i32; 1000]*, from_in: i32, to_in: i32) -> i32 {
var pivot_index: i32 = from_in;
var pivot: i32 = (*p)[pivot_index];
var from: i32 = from_in + 1;
var to: i32 = to_in;
while (from < to) {
if ((*p)[from] <= pivot) {
++from;
} else if ((*p)[to - 1] > pivot) {
--to;
} else {
// Element at `from` is > pivot, and
// element at `to` is <= pivot.
Swap(p, from, to - 1);
++from;
--to;
}
}
Swap(p, pivot_index, from - 1);
return from - 1;
}

fn Quicksort(p: [i32; 1000]*, from: i32, to: i32) {
if (from + 1 >= to) { return; }
var pivot: i32 = Partition(p, from, to);
Quicksort(p, from, pivot);
Quicksort(p, pivot + 1, to);
}
import library "day1_common";
import library "sort";

fn Run() {
// TODO: Global initialization is not implemented yet.
push_back = Core.EOF();

var a: [i32; 1000];
var b: [i32; 1000];
var n: i32 = ReadInputs(&a, &b);
Expand Down
73 changes: 73 additions & 0 deletions examples/advent2024/io_utils.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// 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 "io_utils";

import Core library "io";

// TODO: Use Core.EOF() rather than 0 as a sentinel here.
// At the moment, 0 is the only value we can initialize a global to,
// so we store the value plus 1 here.
var push_back: i32 = 0;

fn ReadChar() -> i32 {
var next: i32 = push_back - 1;
push_back = 0;
// TODO: assert(push_back == Core.EOF());
if (next == Core.EOF()) {
next = Core.ReadChar();
}
return next;
}

fn UnreadChar(c: i32) {
// TODO: assert(push_back == Core.EOF());
push_back = c + 1;
}

fn ReadInt(p: i32*) -> bool {
var read_any_digits: bool = false;
*p = 0;

while (true) {
var c: i32 = ReadChar();
if (c < 0x30 or c > 0x39) {
UnreadChar(c);
break;
}
// TODO: Check for overflow.
*p *= 10;
*p += c - 0x30;
read_any_digits = true;
}
return read_any_digits;
}

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

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

0 comments on commit 10378f2

Please sign in to comment.