mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:30:14 +01:00
As discussed in the 2026-06-14 toolchain open meeting, `Range` is a better fit for the prelude than as a general library in `Core`. This PR moves `Range` into the prelude, and updates the build infrastructure and various tests to reflect that change.
116 lines
2.6 KiB
Plaintext
116 lines
2.6 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 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) {
|
|
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, 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, start: i32, size: i32, sector: i32) {
|
|
for (i: i32 in Core.InclusiveRange(start, start + size - 1)) {
|
|
self.data[i] = sector;
|
|
}
|
|
}
|
|
|
|
fn DefragFiles(ref 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) -> 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;
|
|
}
|