-
-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
website/blog/2024-12-03-advent-of-pbt-day-3/AdventOfTheDay.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import adventBuggy from './buggy.mjs'; | ||
import { buildAdventOfTheDay } from '../2024-12-01-advent-of-pbt-day-1/AdventOfTheDayBuilder'; | ||
|
||
const { AdventPlaygroundOfTheDay, FormOfTheDay } = buildAdventOfTheDay({ | ||
day: 3, | ||
buildBuggyAdvent: adventBuggy, | ||
referenceAdvent: isWordIncludedInLetter, | ||
parser, | ||
placeholderForm: '"content of the letter"\n"word"', | ||
functionName: 'isWordIncludedInLetter', | ||
signature: 'function isWordIncludedInLetter(letterContent: string, word: string): boolean;', | ||
signatureExtras: [], | ||
}); | ||
|
||
export { AdventPlaygroundOfTheDay, FormOfTheDay }; | ||
|
||
// Reference implementation | ||
|
||
function isWordIncludedInLetter(letterContent: string, word: string): boolean { | ||
return letterContent.includes(word); | ||
} | ||
|
||
// Inputs parser | ||
|
||
function parser(answer: string): unknown[] | undefined { | ||
const lines = answer.trim().split('\n'); | ||
if (lines.length !== 2) { | ||
throw new Error( | ||
`Your answer should be made of two distinct lines: one for the content of the letter and the other for the word being looked for`, | ||
); | ||
} | ||
const parsedLetterContent = JSON.parse(lines[0]); | ||
if (typeof parsedLetterContent !== 'string') { | ||
throw new Error('The content of the letter should follow the pattern: "quoted-string"'); | ||
} | ||
const parsedWord = JSON.parse(lines[1]); | ||
if (typeof parsedWord !== 'string') { | ||
throw new Error('The word should follow the pattern: "quoted-string"'); | ||
} | ||
return [parsedLetterContent, parsedWord]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// @ts-check | ||
|
||
export default function advent() { | ||
// Implementation copied from https://github.com/trekhleb/javascript-algorithms/pull/110/ | ||
const PRIME = 97; | ||
|
||
/** | ||
* @param {string} letterContent | ||
* @param {string} word | ||
* @return {boolean} | ||
*/ | ||
return function isWordIncludedInLetter(letterContent, word) { | ||
const wordHash = hashWord(word); | ||
let prevSegment = null; | ||
let currentSegmentHash = null; | ||
for (let charIndex = 0; charIndex <= letterContent.length - word.length; charIndex += 1) { | ||
const currentSegment = letterContent.substring(charIndex, charIndex + word.length); | ||
if (currentSegmentHash === null) { | ||
currentSegmentHash = hashWord(currentSegment); | ||
} else { | ||
currentSegmentHash = reHashWord(currentSegmentHash, prevSegment, currentSegment); | ||
} | ||
prevSegment = currentSegment; | ||
if (wordHash === currentSegmentHash) { | ||
let numberOfMatches = 0; | ||
for (let deepCharIndex = 0; deepCharIndex < word.length; deepCharIndex += 1) { | ||
if (word[deepCharIndex] === letterContent[charIndex + deepCharIndex]) { | ||
numberOfMatches += 1; | ||
} | ||
} | ||
if (numberOfMatches === word.length) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
}; | ||
|
||
/** | ||
* @param {string} word | ||
* @return {number} | ||
*/ | ||
function hashWord(word) { | ||
let hash = 0; | ||
for (let charIndex = 0; charIndex < word.length; charIndex += 1) { | ||
hash += word[charIndex].charCodeAt(0) * PRIME ** charIndex; | ||
} | ||
return hash; | ||
} | ||
|
||
/** | ||
* @param {number} prevHash | ||
* @param {string} prevWord | ||
* @param {string} newWord | ||
* @return {number} | ||
*/ | ||
function reHashWord(prevHash, prevWord, newWord) { | ||
const newWordLastIndex = newWord.length - 1; | ||
let newHash = prevHash - prevWord[0].charCodeAt(0); | ||
newHash /= PRIME; | ||
newHash += newWord[newWordLastIndex].charCodeAt(0) * PRIME ** newWordLastIndex; | ||
return newHash; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
title: Advent of PBT 2024 · Day 3 | ||
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 just pinged you with your next challenge: he needs you to investigate whether the fresh new word lookup system is working as expected. Can you ensure it’s accurate, so everyone gets exactly what they deserve? 🎄🔧 | ||
|
||
<!--truncate--> | ||
|
||
## Word Lookup in Santa's Letters | ||
|
||
Counting the number of presents of type A, then B, by scanning all letters one after the other is a tremendous amount of work for Santa. This year, everything should be automated. So, he asked his elves to provide a quick algorithm to check if a given string is found within a letter. | ||
|
||
The algorithm was required to take two strings: | ||
|
||
1. The first string is the content of the letter. | ||
2. The second string is the word Santa is looking for. | ||
|
||
Based on these two inputs, the algorithm should return true if and only if the word can be found within the letter. If the word isn’t found, it should return false. | ||
|
||
## Hands on | ||
|
||
The elves implemented it quickly, but they were in a rush, and the one assigned to this task didn’t have much time. Santa isn’t confident in the result. He needs you to verify if it works, and since he knows it might be buggy, he’s asking you to report any issues. | ||
|
||
Using the property-based testing features of fast-check, your task is to find a set of inputs (content and word) that break the elves’ implementation. | ||
|
||
You are Santa’s last hope to ensure Christmas happens this year — don’t let him down! 🎄🔧 | ||
|
||
<AdventPlaygroundOfTheDay /> | ||
|
||
## Your answer | ||
|
||
<FormOfTheDay /> |