loading...

Daily Challenge #124 - Middle Me

thepracticaldev profile image dev.to staff ・1 min read

Challenge
Write a function that will take a key of X and place it in the middle of Y repeated N times.

Rules:
If X cannot be placed in the middle, return X.
N will always be > 0.

Example:

X = 'A';
Y = '*';
N = 10;
Y repeated N times = '**********';
X in the middle of Y repeated N times = '*****A*****';

Good luck!


This challenge comes from Capocaccia 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!

Posted on by:

thepracticaldev profile

dev.to staff

@thepracticaldev

The hardworking team behind dev.to ❤️

Discussion

pic
Editor guide
 

My solution in Python:

def middle_me(x, y, n):
        if(n % 2 != 0):
                return x
        else:
                return ( y * (n / 2) ) + x + ( y * (n / 2) )

Which can be abbreviated to:

def middle_me(x, y, n):
        return x if n % 2 != 0 else ( y * (n / 2) ) + x + ( y * (n / 2) )

Hoped you liked this solution, definitely not the most efficient or clean, but I have been working on my Python skills as I am mainly a web developer working with JS and ES6.

— Gabriel

 

Nice! just a hint, if you have a return inside the first if you don't need the else ;)

Here's my solution:

def middle_me(middle: str, repeat: str, repeat_quantity: int) -> str:
  if repeat_quantity % 2 != 0:
    return middle

  half = repeat_quantity // 2
  content = repeat * repeat_quantity
  return content[:half] + middle + content[half:]
 

The string slicing seems to be extra effort, how about something like this?

padding = repeat * (repeat_quantity // 2)
return padding + middle + padding

I was looking for a even better solutions and look what i found;

fill_char = (repeat_quantity // 2) + 1
return middle.center(repeat, fill_char)
 

TypeScript

Assuming we only accept one character for the middle and the surrounding.

"use strict"

/**
 * Surround a character with some more character N times
 * 
 * @param {string} middleCharacter The character to insert in the middle of the string
 * @param {string} surroundingCharacters The character that will surround the middle one
 * @param {number} repeatCount The number of times the surrounding character will be repeated
 * @throws {Error} If the argument count is not three
 * @throws {TypeError} If the first argument is not a string
 * @throws {TypeError} If the second argument is not a string
 * @throws {TypeError} If the third argument is not a number
 * @throws {TypeError} If the first argument has a length different than one
 * @throws {TypeError} If the second argument has a length different than one
 * @throws {TypeError} If the third argument is lower than one
 * @return {string} The middle character with its surrounding characters
 */
function middleMe(middleCharacter: string, surroundingCharacters: string, repeatCount: number): string {
    if (arguments.length !== 3) {
        throw new Error("Three arguments expected")
    }

    if (typeof middleCharacter !== "string") {
        throw new TypeError("First argument expected to be a string")
    }

    if (typeof surroundingCharacters !== "string") {
        throw new TypeError("Second argument expected to be a string")
    }

    if (typeof repeatCount !== "number") {
        throw new TypeError("Third argument expected to be a string")
    }

    if (middleCharacter.length !== 1) {
        throw new Error("First argument must have a length of one")
    }

    if (surroundingCharacters.length !== 1) {
        throw new Error("Second argument must have a length of one")
    }

    if (repeatCount < 1) {
        throw new Error("Third argument must be greater or equal to one")
    }

    if (repeatCount % 2 !== 0) {
        return middleCharacter
    }

    const computedSurroundingCharacters: string = surroundingCharacters.repeat(repeatCount / 2)

    return `${computedSurroundingCharacters}${middleCharacter}${computedSurroundingCharacters}`
}

Playground

Repl.it.

 

Swift solution :

func middleMe(x: Character, y: Character, n: Int) -> String {
    (n % 2 == 0 && n > 1) ? "\(String.init(repeating: y, count: n / 2 ))\(x)\(String.init(repeating: y, count: n / 2 ))" : String(x)
}
 

F# solution:

module DailyChallenge

let middleMe x y n =
    if n % 2 = 0 && n > 0 then
        let ys = String.replicate (n / 2) y
        sprintf "%s%s%s" ys x ys
    else
        x

Tests:

module DailyChallengeTests

open FsUnit.Xunit
open Xunit
open DailyChallenge

[<Fact>]
let ``places a character in the middle``() =
    middleMe "A" "*" 10 |> should equal "*****A*****"

[<Fact>]
let ``returns the character if it cannot be placed in the middle``() =
    middleMe "A" "*" 9 |> should equal "A"

[<Fact>]
let ``returns the character if n is <= 0``() =
    middleMe "A" "*" -2 |> should equal "A"
 

I'm currently learning Clojure - I am sure there is a better solution, but this seems to work.

(ns test.core
  (:gen-class))

(defn string-side [y n]
  (reduce str (repeat (/ n 2) y)))

(defn middle-me [x y n]
  (if (not= (mod n 2) 0)
    x
    (let [side (string-side y n)]
      (str side x side))))



(defn -main []
  (println (middle-me "*" "T" 4)))
 

If X cannot be placed in the middle, return X.

I interpret that this means if it can't be placed in the exact middle position, i.e., N is odd. Otherwise, I don't know how to understand this statement.

const middleMe = (x, y, n) => n % 2 != 0
   ? x
   : `${y.repeat(n/2)}${x}${y.repeat(n/2)}`
 

Haskell solution!

middleMe :: Int -> [a] -> a -> [a]
middleMe n x y
  | isOdd n   = x
  | otherwise = let ys = replicate (n `div` 2) y
                in  ys ++ x ++ ys 
 

In JavaScript

const middleMe = (x, y, n) => {
  if (n % 2 !== 0) return x;
  const centerIndex = (n / 2);
  const arr = Array(n).fill(y);

  arr[centerIndex] = x;

  return arr.join('');
}