## DEV Community is a community of 552,441 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Check if the chain has the same amount

Check if a string has the same amount of 'x' and 'o'. The method must return a Boolean value and must not be case-sensitive. The string can contain any char.

## Discussion  Tata Ganesh

Python solution -

``````def equal_x_and_o(input_string):
x_count = 0
o_count = 0
for c in input_string:
if c == "x" or c == "X":
x_count += 1
elif c == "o" or c == "O":
o_count +=1
return x_count == o_count
``````

Thank you @Pierre for pointing out the error. Pierre Bouillon

Hey @ganeshtata !
I think you missed an uppercase in your `elif` :)

``````elif c == "o" or c == "o":
``````

``````elif c == "o" or c == "O":
``````

To dig a little deeper, I suggest you to see some very useful string methods in Python ! Tata Ganesh

Thank you for that! I had not noticed it. Yes, there are some awesome string methods in Python, but I didn't use any of them here because I wanted to finish the count(s) in one pass of the string. Doing a `.lower()` and then counting might involve two passes of the same string. Pierre Bouillon

I suggested it to reduce your conditions, lowering the string before checking would have allowed you to only check for `o` and `x` for example. This way you would have one pass on the string and a more concise condition :) Tata Ganesh

Do you mean lowering the string before the loop or lowering the character in the loop before checking whether it is an 'x' or 'o'?

• Lowering the string before the loop would involve one complete pass of the string. And then you would have to iterate through the string, again, to count the frequencies.
• Lowering just the character inside the loop, is just equivalent to the if condition, right? I am probably saving on a function call by not calling `.lower()` on the character. In Haskell, with what I thought was kind of a neat method:

``````import Data.Char

val 'x' = 1
val 'o' = -1
val other = 0

check str
| (sum \$ map (val . toLower) str) == 0 = True
| otherwise = False
``````

As a javascript one-liner:

``````string.toLowerCase().split('').map(a => a == 'x' ? 1 : a == 'o' ? -1 : 0).reduce((acc, a) => acc+a) == 0 ? true : false
`````` kip

A simple solution with Rust.

``````fn main() {
println!(
"{} the same amount",
if has_same_amount("\$XxkkLLOoox-", "x", "o") {
"Has"
} else {
"Not has"
}
)
}

fn has_same_amount(str: &str, ch1: &str, ch2: &str) -> bool {
let str = str.to_lowercase();

str.matches(ch1).count() == str.matches(ch2).count()
}
``````
``````Has the same amount
`````` Pierre Bouillon

Python to the rescue !

``````def dev(inp: str) -> bool:
return inp.lower().count('x') == inp.lower().count('o')
``````

output

``````>>> dev('xoxo')
True
>>> dev('xaabboccddxeeffo')
True
>>> dev('x')
False
>>> dev('ooooox')
False
`````` Time for a Go kata you say?

``````
func IsBalanced(dic map[rune]int, s string) bool {
b := 0
for _, r := range strings.ToLower(s) {
i, ok := dic[r]
if ok == false {
continue
}
b += i
}
return b == 0
}

func main() {
//because the world is bigger than Latin
var step = map[rune]int{'x': 1, '🗴': 1, 'o': -1, 'ອ': -1}
table := map[string]bool{
"":true, //0x == 0o
"x0x0": true,
"ອXອXອ":  false,
"H🗴H🗴H(╯° °）╯︵ ┻━┻)HoHo":true,
}

for input, exp := range table {
fmt.Printf("'%s', exp: '%v', got: '%v'\n", input, exp, IsBalanced(step, input))
}

}

``````

play.golang.org/p/n8q9BYrsW4a Jay

Rust Solution.

``````fn check_x_o(s: &str) -> bool {
s.to_lowercase()
.chars()
.map(|c| match c {
'x' => 1,
'o' => -1,
_ => 0,
})
.sum::<i32>() == 0
}

// Usage
fn main() {
let st = "xoxABCxo";
println!("{}", check_x_o(&st));    // false
}
`````` Corey Alexander

Ruby Solution!

``````def character_counts(str)
str.chars.each_with_object(Hash.new(0)) { |char, hash| hash[char] += 1 }
end

def check(str)
str.downcase!
char_count = character_counts(str)
char_count['o'] == char_count['x']
end

``````
``````irb(main):003:0> check('xoxo')
=> true
irb(main):004:0> check('xaabboccddxeeffo')
=> true
irb(main):005:0> check('x')
=> false
irb(main):006:0> check('ooooox')
=> false
``````