mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 19:11:11 +01:00
A collection of additional Carbon examples demonstrating current language capabilities and some limitations of the current state of the toolchain. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
140 lines
3.2 KiB
Plaintext
140 lines
3.2 KiB
Plaintext
// 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
|
|
|
|
// https://adventofcode.com/2024/day/5
|
|
|
|
library "day5_common";
|
|
|
|
import library "io_utils";
|
|
|
|
// fn LeftShift(a: Core.UInt(100), b: i32) -> Core.UInt(100) = "int.left_shift";
|
|
fn LeftShift_u100(a: Core.UInt(100), b: Core.UInt(100)) -> Core.UInt(100) = "int.left_shift";
|
|
|
|
// TODO: Add a builtin that can do this!
|
|
fn Promote(a: i32) -> Core.UInt(100) {
|
|
var result: Core.UInt(100) = 0;
|
|
var bit_i32: i32 = 1;
|
|
var bit_u100: Core.UInt(100) = 1;
|
|
while (bit_i32 != 0) {
|
|
if (a & bit_i32 != 0) {
|
|
result = result | bit_u100;
|
|
}
|
|
bit_i32 <<= 1;
|
|
// TODO: bit_u100 <<= 1;
|
|
bit_u100 = bit_u100 << 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
fn LeftShift(a: Core.UInt(100), b: i32) -> Core.UInt(100) {
|
|
return LeftShift_u100(a, Promote(b));
|
|
}
|
|
|
|
fn PageMask(page: i32) -> Core.UInt(100) {
|
|
return LeftShift(1 as Core.UInt(100), page);
|
|
}
|
|
|
|
class Rules {
|
|
fn Read() -> Rules {
|
|
returned var rules: Rules;
|
|
var i: i32 = 0;
|
|
while (i < 100) {
|
|
rules.disallowed_before[i] = 0;
|
|
++i;
|
|
}
|
|
|
|
var a: i32;
|
|
var b: i32;
|
|
while (ReadInt(&a) and ConsumeChar(0x7C) and ReadInt(&b)) {
|
|
// TODO: rules.disallowed_before[a] |= PageMask(b);
|
|
rules.disallowed_before[a] = rules.disallowed_before[a] | PageMask(b);
|
|
SkipNewline();
|
|
}
|
|
return var;
|
|
}
|
|
|
|
fn IsValidOrder[self: Self](a: i32, b: i32) -> bool {
|
|
return self.disallowed_before[b] & PageMask(a) == 0;
|
|
}
|
|
|
|
var disallowed_before: [Core.UInt(100); 100];
|
|
};
|
|
|
|
class PageList {
|
|
fn Empty() -> PageList {
|
|
returned var me: PageList;
|
|
me.num_pages = 0;
|
|
return var;
|
|
}
|
|
|
|
fn Read() -> PageList {
|
|
returned var me: PageList = Empty();
|
|
|
|
var page: i32;
|
|
if (not ReadInt(&page)) {
|
|
return var;
|
|
}
|
|
me.Add(page);
|
|
while (ConsumeChar(0x2C)) {
|
|
ReadInt(&page);
|
|
me.Add(page);
|
|
}
|
|
SkipNewline();
|
|
return var;
|
|
}
|
|
|
|
fn Add[addr self: Self*](page: i32) {
|
|
self->pages[self->num_pages] = page;
|
|
++self->num_pages;
|
|
}
|
|
|
|
fn FollowsRules[self: Self](rules: Rules) -> bool {
|
|
var seen: Core.UInt(100) = 0;
|
|
var i: i32 = 0;
|
|
while (i < self.num_pages) {
|
|
let page: i32 = self.pages[i];
|
|
if (seen & rules.disallowed_before[page] != 0) {
|
|
return false;
|
|
}
|
|
// TODO: seen |= PageMask(page);
|
|
seen = seen | PageMask(page);
|
|
++i;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
fn IsPossibleFirstPage[self: Self](rules: Rules, page: i32) -> bool {
|
|
var i: i32 = 0;
|
|
while (i < self.num_pages) {
|
|
if (not rules.IsValidOrder(page, self.pages[i])) {
|
|
return false;
|
|
}
|
|
++i;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
fn ExtractPossibleFirstPage[addr self: Self*](rules: Rules) -> i32 {
|
|
var i: i32 = 0;
|
|
while (i < self->num_pages) {
|
|
var page: i32 = self->pages[i];
|
|
if (self->IsPossibleFirstPage(rules, page)) {
|
|
self->pages[i] = self->pages[self->num_pages - 1];
|
|
--self->num_pages;
|
|
return page;
|
|
}
|
|
++i;
|
|
}
|
|
// TODO: Assert.
|
|
return 0;
|
|
}
|
|
|
|
fn MiddlePage[self: Self]() -> i32 {
|
|
return self.pages[self.num_pages / 2];
|
|
}
|
|
|
|
var pages: [i32; 24];
|
|
var num_pages: i32;
|
|
};
|