Files
carbon-lang/examples/advent2024/day9_common.carbon
T
Richard SmithandGeoff Romer ce50f181f1 Add an interface for initialization of vars without an explicit initializer (#6934)
When a `var` is not explicitly given an initializer, initialize it in
one of two ways:

* If its type implements the new interface `Core.Default`, call
`Core.Default.Op` to initialize it.
* Otherwise, if its type implements `UnformedInit`, leave it in an
unformed state. For now, this is always an uninitialized state, but that
will change in the future.
* If neither of those apply, the `var` declaration is ill-formed.

This is a step towards implementing leads decision #6739 and proposals
#257 and #5913.

Assisted-by: Gemini 3.1 Pro via Antigravity

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-03-19 23:46:06 +00:00

117 lines
2.7 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/9
library "day9_common";
import Core library "io";
import Core library "range";
import library "io_utils";
class SectorList {
impl as Core.UnformedInit {}
fn Read() -> SectorList {
returned var me: SectorList;
me.size = 0;
var sector: i32 = 0;
var used: bool = true;
// TODO: An assignment expression would be useful here.
var c: CharOrEOF = ReadChar();
while (c != CharOrEOF.EOF() and c != '\n') {
let v: i32 = if used then sector else -1;
for (_: i32 in Core.Range(c - '0')) {
me.data[me.size] = v;
++me.size;
}
if (used) {
++sector;
}
used = not used;
c = ReadChar();
}
return var;
}
fn DefragBlocks[ref self: Self]() {
var i: i32 = 0;
var j: i32 = self.size - 1;
while (j > i) {
if (self.data[i] != -1) {
++i;
} else if (self.data[j] == -1) {
--j;
} else {
self.data[i] = self.data[j];
++i;
--j;
}
}
self.size = j;
}
fn HasSpace[ref self: Self](start: i32, size: i32) -> bool {
for (i: i32 in Core.InclusiveRange(start, start + size - 1)) {
if (self.data[i] != -1) {
return false;
}
}
return true;
}
fn Fill[ref self: Self](start: i32, size: i32, sector: i32) {
for (i: i32 in Core.InclusiveRange(start, start + size - 1)) {
self.data[i] = sector;
}
}
fn DefragFiles[ref self: Self]() {
var j: i32 = self.size - 1;
while (j >= 0) {
// Skip empty sectors.
while (j >= 0 and self.data[j] == -1) {
--j;
}
// Find the file size and sector and delete the file.
let last: i32 = j;
let sector: i32 = self.data[last];
while (j >= 0 and self.data[j] == sector) {
self.data[j] = -1;
--j;
}
let first: i32 = j + 1;
let size: i32 = last - first + 1;
// Find the first available space for the file.
var i: i32 = 0;
while (not self.HasSpace(i, size)) {
++i;
if (i + size > first) {
// If it doesn't fit to the left of its old position, put it back
// where it was.
i = first;
}
}
// Insert it.
self.Fill(i, size, sector);
}
}
fn Checksum[self: Self]() -> i64 {
var total: i64 = 0;
for (i: i32 in Core.Range(self.size)) {
if (self.data[i] != -1) {
total = total + ((i * self.data[i]) as i64);
}
}
return total;
}
var data: array(i32, 200000);
var size: i32;
}