DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #88 - Recursive Ninjas

Ninjas frequently need to signal each other in code. They often employ natural sounds as cover. Our ninja will chirp like a bird, with different amounts of chirps signifying different messages.

 chirp(4);
  //output would be chirp-chirp-chirp-chirp.

Consider String.prototype.repeat,String.prototype.padStart, and String.prototype.padEnd disabled for this challenge, you'll have to think recursively to avoid detection.

Good luck!


This challenge comes from nodesolomon on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Top comments (15)

Collapse
 
dimitrimarion profile image
Dimitri Marion

Javascript

const chirp = (n) => n == 1 ? 'chirp.' : 'chirp-' + chirp(n-1);
Collapse
 
davjvo profile image
Davmi Jose Valdez Ogando

Hot

Collapse
 
pbouillon profile image
Pierre Bouillon • Edited

Small solution in Python 3.X 😄

def recursive_ninjas(nb: int) -> str:
  return 'chirp.' if nb == 1 else f'chirp-{recursive_ninjas(nb - 1)}'
Collapse
 
aminnairi profile image
Amin

Nice one! But you forgot an edge case. I can still call it with a negative value and get a recursion error.

print(recursive_ninjas(-10));
# RecursionError: maximum recursion depth exceeded in comparison

I think you should add another if else branch for when the value is less or equal than zero.

Collapse
 
pbouillon profile image
Pierre Bouillon • Edited

Given some context, which is ninjas talking, I doubt that they can talk negativly or that not talking at all is considered as talking

However, without those information, I fully agree ! 😄

Thread Thread
 
aminnairi profile image
Amin

I was reading the old ninja scroll all wrong... Thanks sensei 😁

Collapse
 
axionbuster profile image
YuJin Kim
#include <sstream>
#include <string>

std::string chirp(size_t n_reps) {
    std::stringstream s;
    for (size_t i = 0; i < n_reps; ++i) {
        s << "chirp-";
    }
    std::string release = s.str();
    release.erase(--release.end());
    return release;
}

My first submission at Dev.To! (Excluding the welcome post). I love computer science.

Collapse
 
edh_developer profile image
edh_developer

Java

        public static void chirp(int i)
        {
                if (i == 1)
                        System.out.println("chirp");
                else if (i > 1) {
                        System.out.print("chirp-");
                        chirp(i - 1);
                }
        }

Note that this assumes a few things:

  • We want a carriage return at the end of the string.
  • The correct response to chirp(i) for i < 1 is silence.
  • The value of i is not going to be large enough for us to be worried about blowing the stack.
Collapse
 
blessedtawanda profile image
Blessed T Mahuni

None recursive javascript solution

function chirp(numberOfSignals){
  let signal = ''
  for(let i = 0; i < numberOfSignals; i ++) {
    if(signal === '') {
      signal += 'chirp'
    } else {
      signal += '-chirp'
    }
  }
  return signal
}

console.log(chirp(4)) //chirp-chirp-chirp-chirp
console.log(chirp(5)) //chirp-chirp-chirp-chirp-chirp


`

Collapse
 
thepeoplesbourgeois profile image
Josh • Edited

As always, there is no need to use any language but Elixir. We'll establish a signature with a guard clause to make sure the user can only pass a natural number, and a private chirp_ signature to do the work of building the list of chirps, with a default empty list as its second argument. We could use List.duplicate, if the point of this exercise wasn't to make a recursive call 😜

defmodule Ninja do
  def chirp(n) when is_integer(n) and n > 0, do: chirp_(n)

  defp chirp_(n, chirps \\ [])
  defp chirp_(0, chirps), do: Enum.join(chirps, "-")
  defp chirp_(n, chirps), do: chirp_(n-1, ["chirp" | chirps])
end
Collapse
 
aminnairi profile image
Amin • Edited

JavaScript

Decided to throw an error if the count is not greater than zero because a ninja won't bother spending energy on calling this secret technique for no purposes.

"use strict";

/**
 * Ninja secret call sound function
 * 
 * @param {number} count The number of times the word "chirp" should be repeated
 * @throws If the argument count is not valid
 * @throws If the first argument is not a number
 * @throws If the first argument is not greater than 0
 * @return {string} The ninja secret call sound
 * @example chirp(15);
 */
function chirp(count) {
    if (arguments.length !== 1) {
        throw new Error("Expected exactly one parameter.");
    }

    if (typeof count !== "number") {
        throw new TypeError("First argument expected to be a number.");
    }

    if (count <= 0) {
        throw new Error("First argument expected to be greater or equal to 1.");
    }

    if (count === 1) {
        return "chirp.";
    }

    const decreasedCount = count - 1;

    return `chirp-${chirp(decreasedCount)}`;
}

console.log(chirp(4));
console.log(chirp(3));
console.log(chirp(2));
console.log(chirp(1));
console.log(chirp(0));

Training dojo available here (say chirp to enter).

Collapse
 
ap13p profile image
Afief S

Reason

let rec chirp = (times: int, ~result: string="", ()) =>
  switch (times) {
  | 0 => result ++ "."
  | _ =>
    switch (result) {
    | "" => chirp(times - 1, ~result=result ++ "chirp", ())
    | __ => chirp(times - 1, ~result=result ++ "-chirp", ())
    }
  };

Elm


chirp : Int -> String
chirp times =
    case times of
        1 ->
            "chirp."
        _ ->
            "chirp-" ++ (chirp <| times - 1)
Collapse
 
craigmc08 profile image
Craig McIlwrath

Haskell:

chirp 1 = "chirp."
chirp n = "chirp-" ++ chirp (n-1)

Also, you never said anything about Haskell standard functions :)

import Data.List (intercalate) 

chirp = (++".") . intercalate '-' . (flip replicate) "chirp" 
Collapse
 
kvharish profile image
K.V.Harish

My solution in js

const chirp = (count = 1) => Array(count).fill('chirp').join('-');