Ways to Solve: FizzBuzz and RoboNumbers

Writing a Basic Controller (Warning: Do not write code like this)

FizzBuzz

Given a number n, print out all the numbers from 1 to n. If n is divisible by 3, print out "fizz" instead. If n is divisible by 5, print out "buzz" instead. If n is divisible by both 3 and 5, print out "fizzbuzz".

The Problem

  1. Looping

  2. Output
    Whether it's printing or returning an array, there is returning each value and then there is returning a set of values. For printing, it is an additional line of code to print each number with each iteration of the loop, when printing the finished array or string is sufficient.

  3. Scalable
    In other words, do we need to consider if future conditions are added, such as divisibly by 4, print out "bop"?

  4. Pattern
    If the rule divisibly by 4 is added, then would a number divisible by 3, 4, and 5 result in printing "fizzbuzzbop"?

Assumptions:

  1. Looping: Any

  2. Output: String or String[]

  3. Scalable: Adding conditions of the type n % k == 0, ans += "{word}" should be possible

  4. Pattern: Each condition met appends to phrase, if divisible by none return n

Solution 1: For Loop using If-Else and Print on Iteration

  1. Looping: For

  2. Output: Print on iteration

  3. Scalable: No

  4. Pattern: None

function fizzbuzz(n) {
    for (let i = 1; i <= n; i++)
        if (i % 3 == 0 && i % 5 == 0)
            console.log("fizzbuzz")
        else if (i % 3 == 0)
            console.log("fizz")
        else if (i % 5 == 0)
            console.log("buzz")
        else
            console.log(i);
}

Solution 2: For Loop using Object and Print Array

  1. Looping: For

  2. Output: Print after loop

  3. Scalable: Yes

  4. Pattern: Yes

const prints = {
    3: "fizz",
    5: "buzz"
}

function fizzbuzz(n) {
    let arr = []
    for (let i = 1; i <=n; i++)
        let print = ""
        for (const k in prints.Keys())
            if (i % k == 0)
                print += prints[k]
        if (!print)
            print = String(i)
        arr.push(print)
    console.log(arr)
}

Solution 3: While Loop using Print String

  1. Looping: While

  2. Output: Print after loop (string)

  3. Scalable: Yes

  4. Pattern: Yes

const prints = {
    3: "fizz",
    5: "buzz"
}

function fizzbuzz(n) {
    let str = ""
    while (n > 0)
        let print = ""
        for (const k in prints.Keys())
            if (i % k == 0)
                print += prints[k]
        if (!print)
            print = String(n)
        str += print
        n--
    console.log(arr)
}

Solution 4: Recursion with Reverse-Cascade Switch

  1. Looping: Implicit

  2. Output: Print after loop (string)

  3. Scalable: Yes

  4. Pattern: Yes

const prints = n => {
    let p = ""
    switch (0)
        case n % 3:
            p += "fizz"
        case n % 5:
            p += "buzz"
    return !p ? n : p 
}

const rec = n => n < 1 ? "" : prints(n) + rec(n - 1)

function fizzbuzz(n) {
    console.log(rec(n))
}

RoboNumbers

Given a number n, return an array of all numbers from 1 to n. If n contains a 1, replace it with "beep", if n contains a 2, replace it with "boop", and if n contains a 3, replace it with "robo". A number should be replaced by the highest number it contains.

The Problem

  1. Looping

  2. Output:
    Does it have to be an array, or can it be a list (as in a linked list)?

  3. Scalable
    Should it be possible to add future conditions, such as n containing a 4, replace with "init"?

  4. Pattern
    The containing number increments by 1. Will future rules increment the containing number by 1?

Assumptions:

  1. Looping: Any

  2. Output: List<object> or Object[]

  3. Scalable: Adding conditions of type n contains i, ans = word should be possible

  4. Pattern:
    - Future rules increment by 1
    - Future rules do not increment by 1

Solution 1: For Loop using If

  1. Looping: For

  2. Output: Array

  3. Scalable: No

  4. Pattern: No future rules

function robonumbers(n) {
    const num = []
    for (let i = 0; i <= n; i++)
        const nStr = String(i)
        const iStr = nStr
        if (nStr.contains('1'))
            iStr = "beep"
        if (nStr.contains('2'))
            iStr = "boop"
        if (nStr.contains('3'))
            iStr = "robo"
        num.add(iStr)
    return num
}

Solution 2: For Loop using Rules Array

  1. Looping: For

  2. Output: Array

  3. Scalable: Yes

  4. Pattern: Future rules increment by 1

const rules = ["beep", "boop", "robo"]

function robonumbers(n) {
    const num = []
    for (let i = 0; i <= n; i++)
        let iStr = String(i)
        for (let j = i + 1; j < rules; j++)
            if (String(i).contains(String(j))
                iStr = rules[j - 1]
        num.add(iStr)
    return num
}

Solution 3: While Loop using Object and LinkedList

  1. Looping: While

  2. Output: LinkedList

  3. Scalable: Yes

  4. Pattern: Future rules do not increment by 1

const rules = {
    1: "beep",
    2: "boop",
    3: "robo"
}

function robonumbers(n) {
    const root = {}
    while (n > 0)
        let iStr = String(n)
        for (const k in rules.Keys())
            if (String(n).contains(k))
                iStr = rules[k]
        root = {
            val: iStr,
            next: root
        }
        n--
    return root
}

Solution 4: Recursion using Reverse Switch

  1. Looping: Implicit

  2. Output: LinkedList

  3. Scalable: Yes

  4. Pattern: Future rules do not increment by 1

const prints = n => {
    const nStr = String(n)
    switch (true)
        case nStr.contains('3'):
            return "robo"
        case nStr.contains('2'):
            return "boop"
        case nStr.contains('1'):
            return "beep"
        default
            return nStr
}

const rec = (root, n) => n <= 0 ? null : ({ 
    val: prints(n), 
    next: rec(this, n - 1) 
})

function robonumbers(n) {
    return rec({}, n)
}

Note: Untested