DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #29 - Xs and Os

Can you check to see if a string has the same amount of 'x's and 'o's?

Examples input/output:

XO("ooxx") => true
XO("xooxx") => false
XO("ooxXm") => true
XO("zpzpzpp") => true // when no 'x' and 'o' is present should return true
XO("zzoo") => false

Note: The method must return a boolean and be case insensitive. The string can contain any character


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

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

Latest comments (56)

Collapse
 
pmkroeker profile image
Peter

Rust

pub fn xo (value: &str) -> bool {
    let value = value.to_lowercase();
    let count_x = value.matches("x").count();
    let count_o = value.matches("o").count();
    count_x == count_o
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_1() {
        assert_eq!(xo("ooxx"), true);
    }
    #[test]
    fn test_2() {
        assert_eq!(xo("xooxx"), false);
    }
    #[test]
    fn test_3() {
        assert_eq!(xo("ooxXm"), true);
    }
    #[test]
    fn test_4() {
        assert_eq!(xo("zzoo"), false);
    }
    #[test]
    fn test_5() {
        assert_eq!(xo("zpzpzpp"), true);
    }

}

Rust Playground
GitHub Gist

Collapse
 
matrossuch profile image
Mat-R-Such

Python:

def xo(txt):
    return  True if txt.lower().count('x') == txt.lower().count('o') else False
Collapse
 
kvharish profile image
K.V.Harish

My solution in js


const XO = (str) => {
  const countX = (`${str}`.match(/x/gi) || '').length,
    countO = (`${str}`.match(/o/gi) || '').length;
  return countX === countO;
};

Collapse
 
craigmc08 profile image
Craig McIlwrath

Haskell:

import Data.Char (toLower)

xo :: String -> Bool
xo xs = let o's = count 'o' str
            x's = count 'x' str
            str = map toLower xs
            count c = foldl (\sum char -> if c == char then sum + 1 else sum) 0
        in o's == x's
Collapse
 
brightone profile image
Oleksii Filonenko

Elixir:

defmodule XO do
  def same(string),
    do: count(string, "x") == count(string, "o")

  defp count(string, letter) do
    string
    |> String.graphemes()
    |> Enum.filter(&(&1 == letter))
    |> Enum.count()
  end
end
Collapse
 
jacobmgevans profile image
Jacob Evans • Edited

I broke out the work a little more, I tried to be a tad clever and utilize switch but wasn't able to get it to work quite the way I wanted.

Hopefully, the slightly more vanilla JS will be useful in some way.

function XO(s) {
  const arr = [...s];
  let countX = 0;
  let countO = 0;
  arr.map((ele, i) => {
    if (ele === `x`) {
      countX++;
      delete arr[i];
    }
    if (ele === `X`) {
      countX++;
      delete arr[i];
    }
    if (ele === `o`) {
      countO++;
      delete arr[i];
    }
    if (ele === `O`) {
      countO++;
      delete arr[i];
    } else {
      delete arr[i];
    }
  });
  const compare = countO === countX;
  return compare;
}

console.log(XO(`xxxoooxxxoooxxxoooxoxoppppppppppppxoooxx`)); // true
// console.log(XO(`ooxx`)); // true
// console.log(XO(`xooxx`)); // false
// console.log(XO(`zpzpzpp`)); // true
// console.log(XO(`zzoo`)); // false
// console.log(XO(`zzoOOOoo`));
Collapse
 
jacobmgevans profile image
Jacob Evans

I was removing elements with plans of creating two for loops going in opposite directions to speed up the process... but that was for fun and it lost interest in it.

Collapse
 
mohamedelidrissi_98 profile image
Mohamed ELIDRISSI

This is my solution, I'm still learning javascript so nothing fancy

function XO(string) {
  const strArr = string.toLowerCase().split('');
  let os = 0, xs = 0;
  strArr.forEach(word => {
    switch (word) {
      case 'o': 
        os++;
        break;
      case 'x': 
        xs++;
        break;
    }
  });
  return os === xs;
}
Collapse
 
raistlinhess profile image
raistlin-hess

Javascript with no loops:

function XO(str) {
    let str_arr = str.toLowerCase()
        .replace(/[^xo]/g, '')
        .split('')    //Convert String into an Array to allow using Array.sort()
        .sort();

    //All of the o's will be placed before the x's thanks to Array.sort()
    //Add 1 to account for 0-indexing and to turn -1 into 0 when there are no o's
    let oCount = str_arr.lastIndexOf('o') + 1;
    let xCount = str_arr.length - oCount;

    return !(xCount - oCount);
}

//Run the test cases
const testCases = [
        "ooxx",
        "xooxx",
        "ooxXm",
        "zpzpzpp",
        "zzoo"
    ];
for(str of testCases) {
    let result = XO(str);
    console.log(`"${str}" => ${result}`);
}
Collapse
 
hectorpascual profile image

Python goes there :

def XO(input):
    x_count = 0
    o_count = 0
    for c in input:
        if c.lower() == 'x':
            x_count += 1
        elif c.lower() == 'o':
            o_count += 1
    return bool(x_count == o_count)

[V2] - One liner :

XO = lambda input : bool(input.lower().count('x') == input.lower().count('o'))

Some comments may only be visible to logged-in visitors. Sign in to view all comments.