loading...

Daily Challenge #88 - Recursive Ninjas

thepracticaldev profile image dev.to staff ・1 min read

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!

Discussion

pic
Editor guide
Collapse
dimitrimarion profile image
Dimitri Marion

Javascript

const chirp = (n) => n == 1 ? 'chirp.' : 'chirp-' + chirp(n-1);
Collapse
davjvo profile image
Collapse
pbouillon profile image
Pierre Bouillon

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

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
citizen428 profile image
Michael Kohl

F#, used an uint8 so you can't call chirp with an argument < 0.

module DailyChallenge

let chirp (n : uint8) : string =
    "chirp"
    |> Seq.replicate (int n)
    |> String.concat "-"

This assumes that the . in the example belongs to the comment, not the actual chirp output. In case the . is necessary, the following step can be added at the end of the pipeline:

    |> sprintf "%s."

Tests:

module DailyChallengeTests

open FsUnit.Xunit
open Xunit
open DailyChallenge

[<Fact>]
let ``single chirp``() = 
    chirp 1uy |> should equal "chirp"

[<Fact>]
let ``4 chirps``() = 
    chirp 4uy |> should equal "chirp-chirp-chirp-chirp"

[<Fact>]
let ``0 chirps``() = 
    chirp 0uy |> should equal ""
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

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

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
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
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('-');
Collapse
gk profile image
Gaurav Kamath

Python

chirp = lambda n : '-'.join(['chirp']*n) + '.'

how do i syntax highlight? :(