 ## JavaScript Challenges

By
Published
2022/1/30

Let's work through some common coding challenges using JavaScript.

### FizzBuzz

Fizz Buzz is a word game for children that is played in a group, and teaches them about division. However, the game also made its way into software engineering interviews under the moniker of "FizzBuzz" as a helpful gauge in measuring some fundamental analytical and language-skill metrics.

It goes something like this: given an arbitrary integer ℕ, write logic that sequentially prints the range of numbers in ℕ starting at 1, but prints "Fizz" if ℕ is divisible by 3, "Buzz" if ℕ is divisible by 5, or "FizzBuzz" if ℕ is divisible by both 3 and 5.

There are naturally a myriad of ways in which the FizzBuzz challenge may be approached. I'll touch on two possible approaches here, one using a `for...of` loop, and one using a traditional `for` loop. We'll set the default number range for both solutions to 50.

``````/** @function
* @name fizzBuzz
* @summary Solves FizzBuzz using a 'for..of' loop.
* @param { number } n - Upper limit for the range.
* @returns { (number|string) }
*/
const fizzBuzz = (n = 50) => {
/* Turn input (n) into a range of integers
* that takes the shape of an iterable. */
const iterable = [...Array(n).keys()]
/* Slice out the first element in the new
* Array (0) so that 1 is its first value. */
const range = iterable.slice(1, iterable.length)
// Iterate through the range and play FizzBuzz!
for (const i of range) {
if (i % 15 === 0) {
console.log('FizzBuzz')
continue
}
if (i % 3 === 0) {
console.log('Fizz')
continue
}
if (i % 5 === 0) {
console.log('Buzz')
continue
}
console.log(i)
}
}
``````
``````/** @function
* @name fizzBuzz
* @summary Solves FizzBuzz using a 'for' loop.
* @param { number } n - Upper limit for the range.
* @returns { (number|string) }
*/
const fizzBuzz = (n = 50) => {
for (let i = 1; i < n; i++) {
if (i % 15 === 0) console.log('FizzBuzz')
else if (i % 3 === 0) console.log('Fizz')
else if (i % 5 === 0) console.log('Buzz')
else console.log(i)
}
}
``````

### Palindrome

A palindrome is a symmetrical sequence of letters or digits in a word, sentence, or number that remains unchanged whether read from left to right, or from right to left. Punctuation marks are ignored.

We'll create a function that checks whether a given character set is a palindrome. The first function will use built-in Array methods, in the second function we'll solve the challenge with the help of a `for` loop, and in the third we'll use yet another approach using a `for of` loop.

``````/** @function
* @name palindrome
* @summary Check if string is a palindrome using built-in methods.
* @param { string } str - String to be validated.
* @returns { boolean }
* @example
* palindrome('1881') // true
* palindrome('Is this a palindrome?') // false
*/
function palindrome(str) {
const invalid = /[\W]/g
const normalized = str.toLowerCase().replace(invalid, '')
const reversed = normalized.split('').reverse().join('')
return normalized === reversed
}
``````
``````/** @function
* @name palindrome
* @summary Check if string is a palindrome using a for loop.
* @param { string } str - String to be validated.
* @returns { boolean }
*/
function palindrome(str) {
// declare a placeholder array for our loop to work on
let reversed = []
// define a regex that looks for all non-alphanumeric characters
const invalid = /[\W]/g
// coerce the input string to lowercase and sanitize against our regex
const normalized = str.toLowerCase().replace(invalid, '')
// create a loop to populate the placeholder array
for (let i = 0, j = normalized.length; i < j; i++) {
// traverse the benchmark string from right to left
reversed.push(normalized[j - i - 1])
}
// convert the two proper arrays into strings
reversed = reversed.join('')
// compare the original string with the inverted string
return normalized === reversed
}
``````
``````/** @function
* @name palindrome
* @summary Check if string is a palindrome using a for..of loop.
* @param { string } str - String to be validated.
* @returns { boolean }
*/
function palindrome(str) {
let reversed = [];
const invalid = /[\W]/g
const normalized = str.toLowerCase().replace(invalid, '')
// turn the string into a proper Array
const benchmark = [...normalized]
// use a for..of loop
for (const char of normalized) {
// use Array.pop()
reversed.push(benchmark.pop())
}
reversed = reversed.join('')
return normalized === reversed
}
``````

### Flashcards

Flashcards are a deck of cards with each card containing a question on the one side and the answer on the other side. They are typically used in a gamified fashion where a presenter will show the "question" side of a card to one or more people and they will attempt to provide the correct answer in order to proceed to the next card in the stack. There may naturally be variations on the theme, but this is a sufficient definition for our purposes.

To build a rudimentary flashcard game, we'll need some markup to boot. This is a no-frills solution and certainly one of a plethora of approaches. To keep the answer-vetting logic simple, the flashcards' theme will be basic math. Let's dive in without further ado.

``` ```<!-- the flashcard markup -->

<html>

<script src="./flashcards.js"></script>

<body>
<h1>Flashcards</h1>
<h2>Arithmetic practice.</h2>
<h3 id="card">CARD</h3>
<form>
<div>
</div>
<button>Submit</button>
</form>

</body>

</html>
``````

That's a wrap for the markup. Next, the logic:

``````// data intake is static for this example
const data = [
{ id: 1, question: '3²', answer: 9 },
{ id: 2, question: '3 + 7', answer: 10 },
{ id: 3, question: '12 - 6', answer: 6 },
]

/** @function
* @name flashcards
* @summary Simple, functional flashcard game.
* @param { array } cards - Objectified cards.
* @returns { void }
*/
function flashcards(cards) {

// variable declarations
let currentCard = null,
deck = new Array();

const card = document.getElementById('card'),
form = document.getElementsByTagName('form');

// startup logic
function init() {
// add cards to the deck
cards.forEach(card => deck.push(card))
// draw the first card
displayCard()
}

// card drawing
function displayCard() {
if (deck.length > 0) {
currentCard = deck.shift()
card.textContent = currentCard.question
} else {
confirm('Done!\nWant to start over?') ?
init() :
null
}
}

// manage user interaction
event.preventDefault()
// coerce input value to number
displayCard()
}
else {
}
}

// capture the event that bubbles from button

// start the game
init()
}

// defer game initialization to DOM's ready event