## DEV Community is a community of 879,630 amazing developers

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

# Daily Challenge #244 - Search for Letters

Create a function which accepts one arbitrary string as an argument, and return a string of length 26. The objective is to set each of the 26 characters of the output string to either '1' or '0' based on the fact whether the Nth letter of the alphabet is present in the input (independent of its case).

So if an 'a' or an 'A' appears anywhere in the input string (any number of times), set the first character of the output string to '1', otherwise to '0'. if 'b' or 'B' appears in the string, set the second character to '1', and so on for the rest of the alphabet.

For instance:
`"a **& cZ"` => `"10100000000000000000000001"`
`'Abc e \$\$ z'` => `"11101000000000000000000001"`

#### Tests

`change("!!a\$%&RgTT")`
`change("")`
`change("abcdefghijklmnopqrstuvwxyz")`
`change("aaaaaaaaaaa")`

Good luck!

This challenge comes from Roy Gardiner 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 (12) Hrithik Raj • Edited on

## C++17

``````
#include<bits/stdc++.h>
using namespace std;
int main() {
string str;
vector<int>vec(26, 0);
getline(cin, str);
transform(str.begin(), str.end(), str.begin(), ::tolower);
for (auto i = str.begin(); i != str.end(); ++i) {
if (isalpha(*i)) {
vec[*i - 'a'] = 1;
}
}
for (auto i = vec.begin(); i != vec.end(); ++i) {
cout << *i;
}

}
`````` Mike Talbot • Edited on

This is a one statement in JS that works:

``````    (input)=>input.match(/[a-zA-Z]/g)
.reduce((c,a)=>(c[(a.charCodeAt(0) & 31) -1]='1',c),
Array.from('0'.repeat(26)))
.join('')
`````` Vidit Sarkar • Edited on

Here is a C++ solution,

``````string change(string s){
string st(26, '0');

for(char c : s)
if(islower(c) || isupper(c))
st[tolower(c)-'a'] = '1';

return st;
}
`````` # Rust

yay fun with bitsets

``````fn change(hay: &str) -> String {
let mut output = 0u32;
for c in hay.chars() {
match c {
'a'..='z' => output |= 1u32 << (b'z' - c as u8),
'A'..='Z' => output |= 1u32 << (b'Z' - c as u8),
_ => {}
}
}
format!("{:026b}", output)
}
``````

### // "Test"

``````fn main() {
assert_eq!(change("a **& cZ"), "10100000000000000000000001");
assert_eq!(change("Abc e \$\$ z"), "11101000000000000000000001");

let c = |x| println!(r#"{} <= "{}""#, change(x), x);
// "Tests"
c("!!a\$%&RgTT");
c("");
c("abcdefghijklmnopqrstuvwxyz");
c("aaaaaaaaaaa");
}
``````

On infinitely long strings it would be good to:

1. Shrink the range when high or low characters already matched
2. Return early if we achieve `0b11111111111111111111111111`

but on such short strings these would both be slower

## Edit:

I have stolen the ascii case sensitivity bit from @miketalbot and will now proceed to pleasure myself with this fish

``````fn change(hay: &str) -> String {
let mut output = 0u32;
for c in hay.chars() {
if let c @ b'A'..=b'Z' = c as u8 & 0b11011111 {
output |= 1u32 << (b'Z' - c)
}
}
format!("{:026b}", output)
}
``````

Is this actually faster?
No idea.
Alternatively

``````if let c @ b'A'..=b'Z' | c @ b'a'..=b'z' = c as u8 {
output |= 1u32 << (b'Z' - (c & 0b11011111))
}
``````

or even just

``````if matches!(c, 'A'..='Z' | 'a'..='z') {
output |= 1u32 << (b'Z' - (c as u8 & 0b11011111))
}
``````

🤷 agtoever • Edited on

Python 3.7

``````# solution
import string
change = lambda s: "".join(['1' if c in s.lower() else '0' for c in string.ascii_lowercase])

# testcases
for case in ["!!a\$%&RgTT", "", "abcdefghijklmnopqrstuvwxyz", "aaaaaaaaaaa"]:
print(f"change({case}) = {change(case)}")
``````

Try it online!

(Sorry. I didn’t manage for format the code in markdown properly on my iphone) Dan Keefe

I had roughly the same idea:

``````def isin(text):
text = text.lower()
return "".join([str(1)
if letter in text
else str(0)
for letter in "abcdefghhijklmnopqrstuvwxyz"])
`````` Michael Kohl

Ruby can also multiply strings by numbers, which is a bit easier than joining an array:

``````'0' * 26
#=> "00000000000000000000000000"
`````` peter279k

Here is the Python solution:

``````def change(st):
'0','0','0','0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0','0','0','0','0','0',
]

upper_alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

for char in st:
upper_index = 0
for upper_alphabet in upper_alphabets:
if upper_alphabet == char or upper_alphabet.lower() == char:
upper_index += 1

`````` ``````const countEm = (str) => {
str = str.toLowerCase();
return 'abcdefghijklmnopqrstuvwxyz'.split('').map((letter) => {
return str.indexOf(letter) === -1 ? '0' : '1';
}).join('')
};
``````

Thanks for the challenge! There's also `String.prototype.includes`

``````const letters = "abcdefghijklmnopqrstuvwxyz".split("")
const countEm = str => {
str = str.toLowerCase()
return letters.map(letter => str.includes(letter) ? "0" : "1").join("")
}
``````