Skip to content

Commit

Permalink
Day 3 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
e00dan committed Jan 19, 2024
1 parent 9043a2b commit e877205
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
107 changes: 107 additions & 0 deletions src/Day03_02.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {LibString} from "solady/src/utils/LibString.sol";
import {LibBytesUint} from "./LibBytesUint.sol";

struct Point {
uint256 x;
uint256 y;
}

struct Rectangle {
Point start;
Point end;
uint256 value;
bool valueSet;
}

function intersects(Rectangle memory a, Rectangle memory b) pure returns (bool) {
if (a.start.x > b.end.x || b.start.x > a.end.x) {
return false;
}

if (a.end.y < b.start.y || b.end.y < a.start.y) {
return false;
}

return true;
}

contract Day03_02 {
Rectangle[] numberRectangles;
Rectangle[] symbolImpactAreas;

uint256 lineIndex;

bytes1 constant CHAR_ASTERISK = 0x2a;
bytes1 constant CHAR_DOT = 0x2e;
uint256 constant ASTERISK_VALUE_INDICATOR = 7777777777777777;

function parseLine(string calldata line) public virtual {
bytes memory lineBytes = bytes(line);
uint256 numberVectorLength;
uint256 totalNumber;

for (uint256 i; i < lineBytes.length; i++) {
bool isDigit = LibBytesUint.isDigit(lineBytes[i]);
if (isDigit) {
uint256 digit = uint256(uint8(bytes1(lineBytes[i]))) - 48;
totalNumber = totalNumber * 10 + digit;
numberVectorLength++;
}

if (totalNumber != 0 && (!isDigit || i == lineBytes.length - 1)) {
numberRectangles.push(
Rectangle({
start: Point(i - numberVectorLength, lineIndex),
end: Point(i - 1, lineIndex),
value: totalNumber,
valueSet: true
})
);
delete numberVectorLength;
delete totalNumber;
}

if (lineBytes[i] != CHAR_DOT && !isDigit) {
symbolImpactAreas.push(
Rectangle({
start: Point(i == 0 ? 0 : i - 1, lineIndex == 0 ? 0 : lineIndex - 1),
end: Point(i + 1, lineIndex + 1),
value: lineBytes[i] == CHAR_ASTERISK ? ASTERISK_VALUE_INDICATOR : 0,
valueSet: false
})
);
}
}

lineIndex++;
}

function computeResult() public view returns (uint256) {
uint256 result;

for (uint256 j; j < symbolImpactAreas.length; j++) {
if (symbolImpactAreas[j].value != ASTERISK_VALUE_INDICATOR) {
continue;
}

uint256 intersections_value = 1;
uint256 intersections_count = 0;
for (uint256 i; i < numberRectangles.length; i++) {
if (intersects(numberRectangles[i], symbolImpactAreas[j])) {
intersections_value *= numberRectangles[i].value;
intersections_count++;

if (intersections_count == 2) {
result += intersections_value;
break;
}
}
}
}

return result;
}
}
33 changes: 33 additions & 0 deletions test/Day03.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ pragma solidity ^0.8.13;

import {Test, console2} from "forge-std/Test.sol";
import {Day03_01} from "../src/Day03_01.sol";
import {Day03_02} from "../src/Day03_02.sol";

contract Day03Test is Test {
Day03_01 public day03_01;
Day03_02 public day03_02;

function setUp() public {
day03_01 = new Day03_01();
day03_02 = new Day03_02();
}

function test_day03_01_demo() public {
Expand Down Expand Up @@ -40,4 +43,34 @@ contract Day03Test is Test {
console2.log("Day 3_1: ", result);
assertEq(result, 522726);
}

function test_day03_02_demo() public {
while (true) {
string memory line = vm.readLine("./inputs/03_demo.txt");
if (bytes(line).length == 0) {
break;
}

day03_02.parseLine(line);
}

uint256 result = day03_02.computeResult();
console2.log("Day 3_2 (demo): ", result);
assertEq(result, 467835);
}

function test_day03_02() public {
while (true) {
string memory line = vm.readLine("./inputs/03.txt");
if (bytes(line).length == 0) {
break;
}

day03_02.parseLine(line);
}

uint256 result = day03_02.computeResult();
console2.log("Day 3_2: ", result);
assertEq(result, 81721933);
}
}

0 comments on commit e877205

Please sign in to comment.