mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:00:13 +01:00
Add Core.Range(N) facility to construct an integer range. (#5699)
Use it in examples where appropriate. Depends on #5698.
This commit is contained in:
+3
-2
@@ -1,8 +1,9 @@
|
||||
// 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
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
// TODO: This library is not part of the design. Either write a matching
|
||||
// proposal or remove this.
|
||||
|
||||
package Core library "io";
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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
|
||||
|
||||
// TODO: This library is not part of the design. Either write a matching
|
||||
// proposal or remove this.
|
||||
|
||||
package Core library "range";
|
||||
|
||||
import library "prelude/iterate";
|
||||
import library "prelude/operators/arithmetic";
|
||||
import library "prelude/operators/as";
|
||||
import library "prelude/operators/comparison";
|
||||
import library "prelude/types/int";
|
||||
import library "prelude/types/int_literal";
|
||||
import library "prelude/types/optional";
|
||||
|
||||
class IntRange(N:! IntLiteral()) {
|
||||
fn Make(start: Int(N), end: Int(N)) -> Self {
|
||||
return {.start = start, .end = end};
|
||||
}
|
||||
|
||||
impl as Iterate where .CursorType = Int(N) and .ElementType = Int(N) {
|
||||
fn NewCursor[self: Self]() -> Int(N) { return self.start; }
|
||||
fn Next[self: Self](cursor: Int(N)*) -> Optional(Int(N)) {
|
||||
var value: Int(N) = *cursor;
|
||||
if (value < self.end) {
|
||||
++*cursor;
|
||||
return Optional(Int(N)).Some(value);
|
||||
} else {
|
||||
return Optional(Int(N)).None();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var start: Int(N);
|
||||
private var end: Int(N);
|
||||
}
|
||||
|
||||
fn Range(end: i32) -> IntRange(32) {
|
||||
return IntRange(32).Make(0, end);
|
||||
}
|
||||
|
||||
fn InclusiveRange(start: i32, end: i32) -> IntRange(32) {
|
||||
return IntRange(32).Make(start, end + 1);
|
||||
}
|
||||
@@ -7,20 +7,17 @@
|
||||
library "day10_common";
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
import library "io_utils";
|
||||
|
||||
class Terrain {
|
||||
fn Read() -> Terrain {
|
||||
returned var me: Terrain;
|
||||
var y: i32 = 0;
|
||||
while (y < 43) {
|
||||
var x: i32 = 0;
|
||||
while (x < 43) {
|
||||
for (y: i32 in Core.Range(43)) {
|
||||
for (x: i32 in Core.Range(43)) {
|
||||
me.height[x][y] = ReadChar() - 0x30;
|
||||
++x;
|
||||
}
|
||||
SkipNewline();
|
||||
++y;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/10
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day10_common";
|
||||
import library "io_utils";
|
||||
@@ -26,27 +27,21 @@ class Reachable {
|
||||
fn Make(terrain: Terrain) -> Reachable {
|
||||
returned var me: Reachable;
|
||||
var next: u256 = 1;
|
||||
var y: i32 = 0;
|
||||
while (y < 43) {
|
||||
var x: i32 = 0;
|
||||
while (x < 43) {
|
||||
for (y: i32 in Core.Range(43)) {
|
||||
for (x: i32 in Core.Range(43)) {
|
||||
if (terrain.height[x][y] == 0) {
|
||||
me.trailheads[x][y] = next;
|
||||
next <<= 1;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
fn AddLevel[addr self: Self*](terrain: Terrain, level: i32) {
|
||||
let adj: array((i32, i32), 4) = ((-1, 0), (0, -1), (1, 0), (0, 1));
|
||||
var y: i32 = 0;
|
||||
while (y < 43) {
|
||||
var x: i32 = 0;
|
||||
while (x < 43) {
|
||||
for (y: i32 in Core.Range(43)) {
|
||||
for (x: i32 in Core.Range(43)) {
|
||||
if (terrain.height[x][y] == level) {
|
||||
var reach: u256 = 0;
|
||||
var i: i32 = 0;
|
||||
@@ -62,24 +57,18 @@ class Reachable {
|
||||
}
|
||||
self->trailheads[x][y] = reach;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
}
|
||||
|
||||
fn Count[self: Self](terrain: Terrain, level: i32) -> i32 {
|
||||
var total: i32 = 0;
|
||||
var y: i32 = 0;
|
||||
while (y < 43) {
|
||||
var x: i32 = 0;
|
||||
while (x < 43) {
|
||||
for (y: i32 in Core.Range(43)) {
|
||||
for (x: i32 in Core.Range(43)) {
|
||||
if (terrain.height[x][y] == level) {
|
||||
total += PopCount(self.trailheads[x][y]);
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
@@ -90,10 +79,8 @@ class Reachable {
|
||||
fn Run() {
|
||||
var terrain: Terrain = Terrain.Read();
|
||||
var reachable: Reachable = Reachable.Make(terrain);
|
||||
var i: i32 = 1;
|
||||
while (i <= 9) {
|
||||
for (i: i32 in Core.InclusiveRange(1, 9)) {
|
||||
reachable.AddLevel(terrain, i);
|
||||
++i;
|
||||
}
|
||||
Core.Print(reachable.Count(terrain, 9));
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/10
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day10_common";
|
||||
import library "io_utils";
|
||||
@@ -12,16 +13,12 @@ import library "io_utils";
|
||||
class PathsToTop {
|
||||
fn Make(terrain: Terrain) -> PathsToTop {
|
||||
returned var me: PathsToTop;
|
||||
var y: i32 = 0;
|
||||
while (y < 43) {
|
||||
var x: i32 = 0;
|
||||
while (x < 43) {
|
||||
for (y: i32 in Core.Range(43)) {
|
||||
for (x: i32 in Core.Range(43)) {
|
||||
// TODO: We shouldn't need an explicit cast here.
|
||||
me.paths[x][y] =
|
||||
if terrain.height[x][y] == 9 then 1 as i64 else 0;
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
@@ -29,14 +26,12 @@ class PathsToTop {
|
||||
fn AddLevel[addr self: Self*](terrain: Terrain, level: i32) -> i64 {
|
||||
var total: i64 = 0;
|
||||
let adj: array((i32, i32), 4) = ((-1, 0), (0, -1), (1, 0), (0, 1));
|
||||
var y: i32 = 0;
|
||||
while (y < 43) {
|
||||
var x: i32 = 0;
|
||||
while (x < 43) {
|
||||
for (y: i32 in Core.Range(43)) {
|
||||
for (x: i32 in Core.Range(43)) {
|
||||
if (terrain.height[x][y] == level) {
|
||||
var paths: i64 = 0;
|
||||
var i: i32 = 0;
|
||||
while (i < 4) {
|
||||
// TODO: for ((adj_x: i32, adj_y: i32) in adj) {
|
||||
for (i: i32 in Core.Range(4)) {
|
||||
let adj_x: i32 = x + adj[i].0;
|
||||
let adj_y: i32 = y + adj[i].1;
|
||||
if (adj_x >= 0 and adj_x < 43 and
|
||||
@@ -44,14 +39,11 @@ class PathsToTop {
|
||||
terrain.height[adj_x][adj_y] == level + 1) {
|
||||
paths += self->paths[adj_x][adj_y];
|
||||
}
|
||||
++i;
|
||||
}
|
||||
self->paths[x][y] = paths;
|
||||
total += paths;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
@@ -62,11 +54,9 @@ class PathsToTop {
|
||||
fn Run() {
|
||||
var terrain: Terrain = Terrain.Read();
|
||||
var paths: PathsToTop = PathsToTop.Make(terrain);
|
||||
var i: i32 = 8;
|
||||
var total: i64;
|
||||
while (i >= 0) {
|
||||
total = paths.AddLevel(terrain, i);
|
||||
--i;
|
||||
for (i: i32 in Core.InclusiveRange(0, 8)) {
|
||||
total = paths.AddLevel(terrain, 8 - i);
|
||||
}
|
||||
PrintInt64(total);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/11
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day11_common";
|
||||
import library "io_utils";
|
||||
@@ -12,31 +13,23 @@ import library "io_utils";
|
||||
class Digits {
|
||||
fn Make() -> Digits {
|
||||
returned var me: Digits;
|
||||
var digit: i32 = 0;
|
||||
while (digit < 10) {
|
||||
var depth: i32 = 0;
|
||||
while (depth < 75) {
|
||||
for (digit: i32 in Core.Range(10)) {
|
||||
for (depth: i32 in Core.Range(75)) {
|
||||
me.count[digit][depth] = 0;
|
||||
++depth;
|
||||
}
|
||||
++digit;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
fn Print[self: Self](max_depth: i32) {
|
||||
var digit: i32 = 0;
|
||||
while (digit < 10) {
|
||||
for (digit: i32 in Core.Range(10)) {
|
||||
Core.PrintChar(digit + 0x30);
|
||||
Core.PrintChar(0x3A);
|
||||
var depth: i32 = 0;
|
||||
while (depth <= max_depth) {
|
||||
for (depth: i32 in Core.Range(max_depth)) {
|
||||
Core.PrintChar(0x20);
|
||||
PrintInt64NoNewline(self.count[digit][depth]);
|
||||
++depth;
|
||||
}
|
||||
Core.PrintChar(0x0A);
|
||||
++digit;
|
||||
}
|
||||
Core.PrintChar(0x0A);
|
||||
}
|
||||
@@ -74,15 +67,13 @@ fn Run() {
|
||||
while (depth >= 0) {
|
||||
PrintInt64(total);
|
||||
digits.Print(depth);
|
||||
var digit: i64 = 0;
|
||||
while (digit < 10) {
|
||||
let m: i64 = digits.count[digit as i32][depth];
|
||||
for (digit: i32 in Core.Range(10)) {
|
||||
let m: i64 = digits.count[digit][depth];
|
||||
if (m > 0) {
|
||||
let next: (i64, i64) = Next(digit);
|
||||
let next: (i64, i64) = Next(digit as i64);
|
||||
total += ReduceToDigits(next.0, depth, m, &digits) +
|
||||
ReduceToDigits(next.1, depth, m, &digits);
|
||||
}
|
||||
++digit;
|
||||
}
|
||||
--depth;
|
||||
}
|
||||
|
||||
@@ -7,20 +7,17 @@
|
||||
library "day12_common";
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
import library "io_utils";
|
||||
|
||||
class Map {
|
||||
fn Read() -> Map {
|
||||
returned var me: Self;
|
||||
var y: i32 = 0;
|
||||
while (y < 140) {
|
||||
var x: i32 = 0;
|
||||
while (x < 140) {
|
||||
for (y: i32 in Core.Range(140)) {
|
||||
for (x: i32 in Core.Range(140)) {
|
||||
me.kind[x][y] = ReadChar();
|
||||
++x;
|
||||
}
|
||||
SkipNewline();
|
||||
++y;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
@@ -37,12 +34,10 @@ class Map {
|
||||
class DisjointSetForest {
|
||||
fn Make() -> DisjointSetForest {
|
||||
returned var me: Self;
|
||||
var i: i32 = 0;
|
||||
while (i < 140 * 140) {
|
||||
for (i: i32 in Core.Range(140 * 140)) {
|
||||
me.nodes[i].next = i;
|
||||
me.nodes[i].weight = 1;
|
||||
me.nodes[i].unions = 0;
|
||||
++i;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
@@ -93,12 +88,9 @@ fn MakeRegions(map: Map) -> DisjointSetForest {
|
||||
returned var forest: DisjointSetForest =
|
||||
DisjointSetForest.Make();
|
||||
|
||||
var x: i32 = 0;
|
||||
while (x < 140) {
|
||||
var y: i32 = 0;
|
||||
while (y < 140) {
|
||||
var a: i32 = 0;
|
||||
while (a < 2) {
|
||||
for (x: i32 in Core.Range(140)) {
|
||||
for (y: i32 in Core.Range(140)) {
|
||||
for (a: i32 in Core.Range(2)) {
|
||||
// TODO: Crashes toolchain:
|
||||
// let adj: (i32, i32) = if a == 0 then (x - 1, y) else (x, y - 1);
|
||||
// if (map.At(adj.0, adj.1) == map.At(x, y)) {
|
||||
@@ -109,11 +101,8 @@ fn MakeRegions(map: Map) -> DisjointSetForest {
|
||||
if (map.At(adj_x, adj_y) == map.At(x, y)) {
|
||||
forest.Union(y * 140 + x, adj_y * 140 + adj_x);
|
||||
}
|
||||
++a;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
|
||||
return var;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/12
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day12_common";
|
||||
import library "io_utils";
|
||||
@@ -15,15 +16,13 @@ fn Run() {
|
||||
|
||||
var total: i32 = 0;
|
||||
|
||||
var i: i32 = 0;
|
||||
while (i < 140 * 140) {
|
||||
for (i: i32 in Core.Range(140 * 140)) {
|
||||
if (regions.Lookup(i) == i) {
|
||||
let area: i32 = regions.Weight(i);
|
||||
let internal_edges: i32 = regions.Unions(i);
|
||||
let perimeter: i32 = area * 4 - internal_edges * 2;
|
||||
total += area * perimeter;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
Core.Print(total);
|
||||
|
||||
@@ -5,16 +5,15 @@
|
||||
// https://adventofcode.com/2024/day/12
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day12_common";
|
||||
import library "io_utils";
|
||||
|
||||
fn CountExtensions(map: Map, regions: DisjointSetForest*) -> array(i32, 140 * 140) {
|
||||
returned var extensions: array(i32, 140 * 140);
|
||||
var i: i32 = 0;
|
||||
while (i < 140 * 140) {
|
||||
for (i: i32 in Core.Range(140 * 140)) {
|
||||
extensions[i] = 0;
|
||||
++i;
|
||||
}
|
||||
|
||||
var ext: array({.same: (i32, i32), .adj: (i32, i32)}, 4) = (
|
||||
@@ -24,24 +23,18 @@ fn CountExtensions(map: Map, regions: DisjointSetForest*) -> array(i32, 140 * 14
|
||||
{.same = (0, -1), .adj = (1, 0)},
|
||||
);
|
||||
|
||||
var x: i32 = 0;
|
||||
while (x < 140) {
|
||||
var y: i32 = 0;
|
||||
while (y < 140) {
|
||||
for (x: i32 in Core.Range(140)) {
|
||||
for (y: i32 in Core.Range(140)) {
|
||||
let kind: i32 = map.At(x, y);
|
||||
var e: i32 = 0;
|
||||
while (e < 4) {
|
||||
for (e: i32 in Core.Range(4)) {
|
||||
if (map.At(x + ext[e].same.0, y + ext[e].same.1) == kind and
|
||||
map.At(x + ext[e].adj.0, y + ext[e].adj.1) != kind and
|
||||
map.At(x + ext[e].same.0 + ext[e].adj.0,
|
||||
y + ext[e].same.1 + ext[e].adj.1) != kind) {
|
||||
++extensions[regions->Lookup(y * 140 + x)];
|
||||
}
|
||||
++e;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
@@ -53,8 +46,7 @@ fn Run() {
|
||||
|
||||
var total: i32 = 0;
|
||||
|
||||
var i: i32 = 0;
|
||||
while (i < 140 * 140) {
|
||||
for (i: i32 in Core.Range(140 * 140)) {
|
||||
if (regions.Lookup(i) == i) {
|
||||
let area: i32 = regions.Weight(i);
|
||||
let internal_edges: i32 = regions.Unions(i);
|
||||
@@ -62,7 +54,6 @@ fn Run() {
|
||||
let perimeter: i32 = area * 4 - internal_edges * 2 - extensions;
|
||||
total += area * perimeter;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
Core.Print(total);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/1
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day1_common";
|
||||
import library "sort";
|
||||
@@ -18,11 +19,9 @@ fn Run() {
|
||||
Quicksort(&a, 0, n);
|
||||
Quicksort(&b, 0, n);
|
||||
|
||||
var i: i32 = 0;
|
||||
var difference: i32 = 0;
|
||||
while (i < n) {
|
||||
for (i: i32 in Core.Range(n)) {
|
||||
difference += Abs(a[i] - b[i]);
|
||||
i += 1;
|
||||
}
|
||||
Core.Print(difference);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/4
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day4_common";
|
||||
import library "io_utils";
|
||||
@@ -14,25 +15,16 @@ fn Run() {
|
||||
var xmas: array(i32, 4) = (0x58, 0x4D, 0x41, 0x53);
|
||||
var found: i32 = 0;
|
||||
|
||||
// TODO: Use for loops once they're implemented.
|
||||
var y: i32 = 0;
|
||||
while (y < 140) {
|
||||
var x: i32 = 0;
|
||||
while (x < 140) {
|
||||
var dy: i32 = -1;
|
||||
while (dy <= 1) {
|
||||
var dx: i32 = -1;
|
||||
while (dx <= 1) {
|
||||
for (y: i32 in Core.Range(140)) {
|
||||
for (x: i32 in Core.Range(140)) {
|
||||
for (dy: i32 in Core.InclusiveRange(-1, 1)) {
|
||||
for (dx: i32 in Core.InclusiveRange(-1, 1)) {
|
||||
if (search.Check4(xmas, x, y, dx, dy)) {
|
||||
++found;
|
||||
}
|
||||
++dx;
|
||||
}
|
||||
++dy;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
Core.Print(found);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/4
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day4_common";
|
||||
import library "io_utils";
|
||||
@@ -14,20 +15,15 @@ fn Run() {
|
||||
var mas: array(i32, 3) = (0x4D, 0x41, 0x53);
|
||||
var found: i32 = 0;
|
||||
|
||||
// TODO: Use for loops once they're implemented.
|
||||
var y: i32 = 1;
|
||||
while (y < 139) {
|
||||
var x: i32 = 1;
|
||||
while (x < 139) {
|
||||
for (y: i32 in Core.InclusiveRange(1, 138)) {
|
||||
for (x: i32 in Core.InclusiveRange(1, 138)) {
|
||||
if ((search.Check3(mas, x - 1, y - 1, 1, 1) or
|
||||
search.Check3(mas, x + 1, y + 1, -1, -1)) and
|
||||
(search.Check3(mas, x - 1, y + 1, 1, -1) or
|
||||
search.Check3(mas, x + 1, y - 1, -1, 1))) {
|
||||
++found;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
Core.Print(found);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
library "day5_common";
|
||||
|
||||
import Core library "range";
|
||||
|
||||
import library "io_utils";
|
||||
|
||||
fn PageMask(page: i32) -> Core.UInt(100) {
|
||||
@@ -16,10 +18,8 @@ fn PageMask(page: i32) -> Core.UInt(100) {
|
||||
class Rules {
|
||||
fn Read() -> Rules {
|
||||
returned var rules: Rules;
|
||||
var i: i32 = 0;
|
||||
while (i < 100) {
|
||||
for (i: i32 in Core.Range(100)) {
|
||||
rules.disallowed_before[i] = 0;
|
||||
++i;
|
||||
}
|
||||
|
||||
var a: i32;
|
||||
@@ -68,39 +68,33 @@ class PageList {
|
||||
|
||||
fn FollowsRules[self: Self](rules: Rules) -> bool {
|
||||
var seen: Core.UInt(100) = 0;
|
||||
var i: i32 = 0;
|
||||
while (i < self.num_pages) {
|
||||
for (i: i32 in Core.Range(self.num_pages)) {
|
||||
let page: i32 = self.pages[i];
|
||||
if (seen & rules.disallowed_before[page] != 0) {
|
||||
return false;
|
||||
}
|
||||
seen |= PageMask(page);
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn IsPossibleFirstPage[self: Self](rules: Rules, page: i32) -> bool {
|
||||
var i: i32 = 0;
|
||||
while (i < self.num_pages) {
|
||||
for (i: i32 in Core.Range(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) {
|
||||
for (i: i32 in Core.Range(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;
|
||||
|
||||
@@ -7,20 +7,17 @@
|
||||
library "day8_common";
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
import library "io_utils";
|
||||
|
||||
class Grid {
|
||||
fn Read() -> Grid {
|
||||
returned var me: Grid;
|
||||
var y: i32 = 0;
|
||||
while (y < 50) {
|
||||
var x: i32 = 0;
|
||||
while (x < 50) {
|
||||
for (y: i32 in Core.Range(50)) {
|
||||
for (x: i32 in Core.Range(50)) {
|
||||
me.data[x][y] = ReadChar();
|
||||
++x;
|
||||
}
|
||||
SkipNewline();
|
||||
++y;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -5,17 +5,16 @@
|
||||
// https://adventofcode.com/2024/day/8
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day8_common";
|
||||
import library "io_utils";
|
||||
|
||||
fn IsAntinode(grid: Grid, ox: i32, oy: i32) -> bool {
|
||||
var ay: i32 = 0;
|
||||
while (ay < 50) {
|
||||
for (ay: i32 in Core.Range(50)) {
|
||||
let by: i32 = ay * 2 - oy;
|
||||
if (by >= 0 and by < 50) {
|
||||
var ax: i32 = 0;
|
||||
while (ax < 50) {
|
||||
for (ax: i32 in Core.Range(50)) {
|
||||
let bx: i32 = ax * 2 - ox;
|
||||
if (bx >= 0 and bx < 50 and (ax != bx or ay != by)) {
|
||||
if (grid.data[ax][ay] != 0x2E and
|
||||
@@ -23,26 +22,20 @@ fn IsAntinode(grid: Grid, ox: i32, oy: i32) -> bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
++ax;
|
||||
}
|
||||
}
|
||||
++ay;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn CountAntinodes(grid: Grid) -> i32 {
|
||||
var count: i32 = 0;
|
||||
var y: i32 = 0;
|
||||
while (y < 50) {
|
||||
var x: i32 = 0;
|
||||
while (x < 50) {
|
||||
for (y: i32 in Core.Range(50)) {
|
||||
for (x: i32 in Core.Range(50)) {
|
||||
if (IsAntinode(grid, x, y)) {
|
||||
++count;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// https://adventofcode.com/2024/day/8
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
import library "day8_common";
|
||||
import library "io_utils";
|
||||
@@ -19,14 +20,11 @@ fn MarkAndCount(marks: array(array(bool, 50), 50)*, x: i32, y: i32) -> i32 {
|
||||
|
||||
fn MarkAndCountAntinodesFor(grid: Grid, marks: array(array(bool, 50), 50)*, ax: i32, ay: i32) -> i32 {
|
||||
var count: i32 = 0;
|
||||
var by: i32 = 0;
|
||||
while (by < 50) {
|
||||
var bx: i32 = 0;
|
||||
while (bx < 50) {
|
||||
for (by: i32 in Core.Range(50)) {
|
||||
for (bx: i32 in Core.Range(50)) {
|
||||
let dx: i32 = bx - ax;
|
||||
let dy: i32 = by - ay;
|
||||
if (grid.data[bx][by] != grid.data[ax][ay] or (dx == 0 and dy == 0)) {
|
||||
++bx;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -37,39 +35,29 @@ fn MarkAndCountAntinodesFor(grid: Grid, marks: array(array(bool, 50), 50)*, ax:
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
++bx;
|
||||
}
|
||||
++by;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
fn MarkAndCountAntinodes(grid: Grid, marks: array(array(bool, 50), 50)*) -> i32 {
|
||||
var count: i32 = 0;
|
||||
var y: i32 = 0;
|
||||
while (y < 50) {
|
||||
var x: i32 = 0;
|
||||
while (x < 50) {
|
||||
for (y: i32 in Core.Range(50)) {
|
||||
for (x: i32 in Core.Range(50)) {
|
||||
if (grid.data[x][y] != 0x2E) {
|
||||
count += MarkAndCountAntinodesFor(grid, marks, x, y);
|
||||
}
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
fn Run() {
|
||||
var marks: array(array(bool, 50), 50);
|
||||
var y: i32 = 0;
|
||||
while (y < 50) {
|
||||
var x: i32 = 0;
|
||||
while (x < 50) {
|
||||
for (y: i32 in Core.Range(50)) {
|
||||
for (x: i32 in Core.Range(50)) {
|
||||
marks[x][y] = false;
|
||||
++x;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
|
||||
Core.Print(MarkAndCountAntinodes(Grid.Read(), &marks));
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
library "day9_common";
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
import library "io_utils";
|
||||
|
||||
class SectorList {
|
||||
@@ -19,11 +20,9 @@ class SectorList {
|
||||
var c: i32 = ReadChar();
|
||||
while (c != Core.EOF() and c != 0xA) {
|
||||
let v: i32 = if used then sector else -1;
|
||||
var n: i32 = c - 0x30;
|
||||
while (n > 0) {
|
||||
for (_: i32 in Core.Range(c - 0x30)) {
|
||||
me.data[me.size] = v;
|
||||
++me.size;
|
||||
--n;
|
||||
}
|
||||
if (used) {
|
||||
++sector;
|
||||
@@ -52,21 +51,17 @@ class SectorList {
|
||||
}
|
||||
|
||||
fn HasSpace[addr self: Self*](start: i32, size: i32) -> bool {
|
||||
var i: i32 = start;
|
||||
while (i < start + size) {
|
||||
for (i: i32 in Core.InclusiveRange(start, start + size - 1)) {
|
||||
if (self->data[i] != -1) {
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn Fill[addr self: Self*](start: i32, size: i32, sector: i32) {
|
||||
var i: i32 = start;
|
||||
while (i < start + size) {
|
||||
for (i: i32 in Core.InclusiveRange(start, start + size - 1)) {
|
||||
self->data[i] = sector;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,12 +101,10 @@ class SectorList {
|
||||
|
||||
fn Checksum[self: Self]() -> i64 {
|
||||
var total: i64 = 0;
|
||||
var i: i32 = 0;
|
||||
while (i < self.size) {
|
||||
for (i: i32 in Core.Range(self.size)) {
|
||||
if (self.data[i] != -1) {
|
||||
total = total + ((i * self.data[i]) as i64);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
library "io_utils";
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
// If non-zero, this is the most recently read character plus 2.
|
||||
// The +2 is necessary to distinguish the case of no unread character
|
||||
@@ -114,12 +115,10 @@ fn SkipNewline() -> bool {
|
||||
}
|
||||
|
||||
fn SkipNChars(n: i32) -> bool {
|
||||
var i: i32 = 0;
|
||||
while (i < n) {
|
||||
for (_: i32 in Core.Range(n)) {
|
||||
if (ReadChar() == Core.EOF()) {
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,20 +3,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
import Core library "io";
|
||||
import Core library "range";
|
||||
|
||||
// Compute and return the number of primes less than 1000.
|
||||
|
||||
class Sieve {
|
||||
fn Make() -> Sieve {
|
||||
returned var s: Sieve;
|
||||
|
||||
// TODO: `for` loop.
|
||||
var n: i32 = 0;
|
||||
while (n < 1000) {
|
||||
for (n: i32 in Core.Range(1000)) {
|
||||
s.is_prime[n] = true;
|
||||
++n;
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -35,14 +31,12 @@ fn Run() -> i32 {
|
||||
var s: Sieve = Sieve.Make();
|
||||
|
||||
var number_of_primes: i32 = 0;
|
||||
var n: i32 = 2;
|
||||
while (n < 1000) {
|
||||
for (n: i32 in Core.InclusiveRange(2, 999)) {
|
||||
if (s.is_prime[n]) {
|
||||
++number_of_primes;
|
||||
Core.Print(n);
|
||||
s.MarkMultiplesNotPrime(n);
|
||||
}
|
||||
++n;
|
||||
}
|
||||
|
||||
return number_of_primes;
|
||||
|
||||
Reference in New Issue
Block a user