Skip to content

Commit

Permalink
📝 Advent Of PBT Day 11 (#5508)
Browse files Browse the repository at this point in the history
  • Loading branch information
dubzzz authored Dec 11, 2024
1 parent 24b8417 commit d730af2
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
95 changes: 95 additions & 0 deletions website/blog/2024-12-11-advent-of-pbt-day-11/AdventOfTheDay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import adventBuggy from './buggy.mjs';
import { buildAdventOfTheDay } from '../2024-12-01-advent-of-pbt-day-1/AdventOfTheDayBuilder';

const { AdventPlaygroundOfTheDay, FormOfTheDay } = buildAdventOfTheDay({
day: 11,
buildBuggyAdvent: adventBuggy,
referenceAdvent: findPlaceForSanta,
postAdvent: (answer) => answer !== undefined,
parser,
placeholderForm: '<width>,<height>\n.....\n.....\n.....\n..xx.',
functionName: 'findPlaceForSanta',
signature: 'function findPlaceForSanta(map: MarketMap, requestedArea: RequestedSize): Location | undefined;',
signatureExtras: [
'type MarketMap = boolean[][];',
'type RequestedSize = { width: number; height: number };',
'type Location= { x: number; y: number };',
],
});

export { AdventPlaygroundOfTheDay, FormOfTheDay };

// Reference implementation

function findPlaceForSanta(
map: boolean[][],
requestedArea: { width: number; height: number },
): { x: number; y: number } | undefined {
for (let y = 0; y !== map.length; ++y) {
for (let x = 0; x !== map[0].length; ++x) {
const location = { x, y };
const placeIsValid = isValidPlace(map, location, requestedArea);
if (placeIsValid) {
return location;
}
}
}
return undefined;
}

function isValidPlace(
map: boolean[][],
start: { x: number; y: number },
requestedArea: { width: number; height: number },
): boolean {
for (let dy = 0; dy !== requestedArea.height; ++dy) {
const line = map[start.y + dy];
if (line === undefined) {
return false;
}
for (let dx = 0; dx !== requestedArea.width; ++dx) {
const cell = line[start.x + dx];
if (cell === undefined) {
return false;
}
if (!cell) {
return false;
}
}
}
return true;
}

// Inputs parser

const positionRegex = /^(\d)+,(\d+)$/;
const gridLineRegex = /^[\.x]+$/;

function parser(answer: string): unknown[] | undefined {
const lines = answer.trim().split('\n');
if (lines.length < 1) {
throw new Error(`Your answer should be made of one line`);
}
const mPos = positionRegex.exec(lines[0]);
if (mPos === null) {
throw new Error(
`The first line is supposed to give the size being requested by Santa for the Market with the form: <width>,<height>. Received: ${lines[0]}.`,
);
}
let lineSize = -1;
const grid: boolean[][] = [];
for (let i = 1; i < lines.length; ++i) {
const m = gridLineRegex.exec(lines[i]);
if (m === null) {
throw new Error(
`Each line of the grid declaring the market should be made of only . or x. Received: ${lines[i]}.`,
);
}
const lineOfGrid = lines[i].split('').map((c) => c === '.');
grid.push(lineOfGrid);
if (lineSize !== -1 && lineOfGrid.length !== lineSize) {
throw new Error(`Grid must be rectangular, all the lines of the grids have the same width.`);
}
}
return [grid, { width: Number(mPos[1]), height: Number(mPos[2]) }];
}
56 changes: 56 additions & 0 deletions website/blog/2024-12-11-advent-of-pbt-day-11/buggy.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// @ts-check

export default function advent() {
/**
* For the Christmas market, Santa is looking for a place.
*
* For each market of the world, he has to check if it can land with
* his 8 reindeers and his sleigh. This algorithm check whether there
* is an area of consecutive true that can contain requestedArea and return
* its upper-left corner.
*
* @param {boolean[][]} map - Indexed by map[y][x]
* @param {{ width: number; height: number }} requestedArea
*
* map.length corresponds to the height of the map
* map[0].length corresponds to the width of the map
*
* @returns {{ x: number; y: number } | undefined}
* - the upper-left corner of the area,
* whenever there is one place in the map having with
* rectangular width x height surface with only true
* - undefined if no such area exists
*/
return function findPlaceForSanta(map, requestedArea) {
for (let y = 0; y !== map.length; ++y) {
for (let x = 0; x !== map[0].length; ++x) {
const location = { x, y };
const placeIsValid = isValidPlace(map, location, requestedArea);
if (placeIsValid) {
return location;
}
}
}
return undefined;
};

function isValidPlace(map, start, requestedArea) {
for (let dy = 0; dy !== requestedArea.height; ++dy) {
if (!map[start.y + dy]?.[start.x]) {
return false;
}
if (!map[start.y + dy]?.[start.x + requestedArea.width - 1]) {
return false;
}
}
for (let dx = 0; dx !== requestedArea.width; ++dx) {
if (!map[start.y]?.[start.x + dx]) {
return false;
}
if (!map[start.y + requestedArea.height - 1]?.[start.x + dx]) {
return false;
}
}
return true;
}
}
35 changes: 35 additions & 0 deletions website/blog/2024-12-11-advent-of-pbt-day-11/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: Advent of PBT 2024 · Day 11
authors: [dubzzz]
tags: [advent-of-pbt, advent-of-pbt-2024]
---

import {AdventPlaygroundOfTheDay,FormOfTheDay} from './AdventOfTheDay';

Christmas is at risk! In their rush to meet tight deadlines, Santa’s elves accidentally introduced bugs into critical algorithms. If these issues aren’t discovered in time, Christmas could be delayed for everyone worldwide!

Your mission is to troubleshoot these black-box algorithms using the power of fast-check.

The clock is ticking. Santa’s relying on the elves’ algorithm to find the perfect spot for his sleigh at Christmas markets. Can you ensure it works flawlessly? 🎄🔧

<!--truncate-->

## Perfect market spots

Each year, Santa travels the world with his sleigh, visiting children at Christmas markets. And every year, he faces the same question: where can he land and set up his stand? This year, Santa wants to be fully prepared, so he asked the elves to create an algorithm that can quickly tell him the best spots at any Christmas market.

The task is simple: Santa is given a grid of squares, some of which are grayed out as unavailable, while the others are available spots. Santa needs the algorithm to check if there's enough room for his stand, based on a rectangular area of specific dimensions. If the algorithm finds a suitable space, it will return the location of the upper-left corner of the rectangle; if not, it will let Santa know there's no available space.

## Hands on

The elves have done their part! They replaced the grid with a 2D array of boolean values, where `true` indicates an available spot — _`.` in the input field_ — and `false` means it's not — _`x` in the input field_. Santa provides the width and height of the space he needs — both strictly positive integers, and the elves assure him that if there’s enough room, the algorithm will find it.

However, Santa cannot afford any mistakes — there’s too much at stake this Christmas. He cannot risk missing out on a market or being surprised by a lack of space for his stand. Can you help ensure that the elves' algorithm is flawless?

It’s critical for Santa, for the children, and for Christmas. Act quickly! 🎄🔧

<AdventPlaygroundOfTheDay />

## Your answer

<FormOfTheDay />

0 comments on commit d730af2

Please sign in to comment.