# Daily Challenge #47 - Alphabets

In today's challenge, you are asked to replace every letter with its position in the alphabet for a given string where 'a' = 1, 'b'= 2, etc.

For example:

`alphabet_position("The sunset sets at twelve o' clock.")` should return `20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11` as a string.

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

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

### Discussion ## JavaScript

My take at the challenge in JavaScript.

## Source-Code

``````"use strict";

function lettersOnly(letterOrElse) {
return letterOrElse.toUpperCase() !== letterOrElse.toLowerCase();
}

function toAlphabetPosition(letter) {
return letter.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0) + 1;
}

function alphabet_position(input) {
return Array
.from(input)
.filter(lettersOnly)
.map(toAlphabetPosition)
.join(" ");
}

const result = alphabet_position("The sunset sets at twelve o' clock.");
const expectations = "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11";

assert(result === expectations); // undefined (meaning OK)
``````

## Test it yourself

Available online here.

Thank you sir!

``````const alphaPosition = str => [...str]
.filter(letter => letter.toLowerCase().charCodeAt(0) - 96 > 0)
.map(letter => letter.toLowerCase().charCodeAt(0) - 96)
.reduce((s, pos) => s += `\${pos} `, '')
.trim();
``````

classic map filter reduce problem loved it.

x86_64 assembly (System V ABI, GNU assembler), as usual. Not really correct, since there will be an extra `' '` at the end which I was too lazy to remove, but it'll do.

alphabetic_position.S

``````    .global alphabetic_position

.text
alphabetic_position:
#using these registers to avoid sprintf breaking them
push %rbx
push %rbp

mov %rdi, %rbx
mov %rdi, %r12
mov %rsi, %rbp

xor %eax, %eax
xor %edx, %edx
loop:
mov (%rbp), %dl

cmp \$65, %dl # 'A'
jl skip

cmp \$91, %dl # 'Z' + 1
jl print

cmp \$97, %dl # 'a'
jl skip

cmp \$123, %dl # 'z' + 1
ja skip

printl:
sub \$32, %dl # 'a' -> 'A'
print:
sub \$64, %dl # 'A' -> 1

push %rdx

mov %rbx, %rdi
mov \$format, %rsi
call sprintf

pop %rdx
skip:
inc %rbp
cmp \$0, %dl
jne loop

mov %r12, %rax

pop %rbp
pop %rbx
ret

.section .rodata
format:
.asciz "%d "
``````

alphabetic_position.h:

``````char *alphabetic_position(char *dst, const char *src);
``````

Edit: the function name now conforms to the specification, as well as with the "returns the string" requirement (by returning a copy of dst).

that's crazy

In C++

``````#include <string>
#include <iostream>

void alphabet_position(std::string s) {
for (int i = 0; i < s.size(); i++)
{
int pos = (int)((char)s[i] - 'a');
pos = pos < 0 ? pos + ('a' - 'A') : pos;
if (pos >= 0 && pos <= 'z' - 'a') {
std::cout << pos+1 << " ";
}
}
}

int main (int argc, char *argv[])
{
alphabet_position("<The quick brown fox jumps over the lazy dog!>");
//print 20 8 5 17 21 9 3 11 2 18 15 23 14 6 15 24 10 21 13 16 19 15 22 5 18 20 8 5 12 1 26 25 4 15 7
return 0;
}
``````

Edited: there was a bug :D

Python one liner to the rescue 🙂

`print(*[ord(x.lower())-96 for x in input() if x.isalpha()])`

Rust:

``````pub fn alphabet_position(text: &str) -> String {
text.to_lowercase()
.chars()
.filter(|c| c.is_alphabetic())
.map(|char| (char as usize - 96).to_string())
.collect::<Vec<String>>()
.join(" ")
}

#[test]
fn test_alphabet_position() {
assert_eq!(
alphabet_position("The sunset sets at twelve o' clock."),
String::from("20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11")
);
}
``````

this has shown me how similar rust syntax can be to JavaScript syntax wow

JavaScript

``````const code = s => [...s].reduce((a, v) => v.match(/[a-z]{1}/i)
? a+(v.toLowerCase().charCodeAt(0)-96)+' '
: a
, '')
.trim();
``````

And as an extra, the decoder:

``````const decode = s => String.fromCharCode(...s.split(' ').map(val=>parseInt(val) + 96));
``````

Although the decoding process is not perfect, because all the spaces and symbols are lost during the coding process. For example, the sentence "The sunset sets at twelve o' clock" will be coded into:

"20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11"

Which will be decoded into:

"thesunsetsetsattwelveoclock"

``````import Data.Maybe (catMaybes)
import Data.List (find)
import Data.Functor (fmap)
import Data.Char (toLower)

alpha = ['a'..'z']

isAlpha :: Char -> Bool
isAlpha = (`elem` alpha)

(>.<) :: (a -> b -> d) -> (c -> b) -> (a -> c -> d)
a >.< b = flip \$ flip a . b

toNumber :: Char -> Maybe Int
toNumber = fmap snd . (flip find) alphaNum . ((==) >.< fst)
where alphaNum = zip alpha [1..]

encodeMsg :: String -> String
encodeMsg = unwords . map show . catMaybes . map toNumber . filter isAlpha . map toLower
``````

I wanted to try to write this function completely using point-free style. It led to me having to write that `>.<` operator, which you can see from the type definition exactly what it does. It was a good mental exercise in types for me, a Haskell beginner.

You don't need your `filter isAlpha` and `isAlpha` functions, since `toNumber` already returns `None` when the character isn't a letter, which chops off a nice bit of the solution!

You can also use `findIndex` from `Data.List` instead of find-with-zip (though that solution is cool! 😋

``````toNumber = (fmap (+1)) . (flip findIndex alpha) . (==)
``````

Python

``````import string
def alphabet_position(text):
text = [i for i in text.replace(' ','').lower() if i.isalpha() ]
position = [str(string.ascii_lowercase.find(i)+1) for i in text ]
return ' '.join(position)
``````

Here is the simple solution with PHP:

``````function alphabet_position(string \$s): string {
\$s = strtoupper(\$s);
\$alphabetNums = range(65, 90);
\$alphabets = [];

foreach (\$alphabetNums as \$chr) {
\$aphabets[] = chr(\$chr);
}

\$result = "";

\$index = 0;
for (; \$index < strlen(\$s); \$index++) {
if (in_array(\$s[\$index], \$aphabets) === false) {
continue;
}

\$result .= (string)(ord(\$s[\$index]) - 64) . " ";
}

return substr(\$result, 0, -1);
}
``````

Some function composition sorcery in Haskell.

``````import Data.Char (isLetter, toUpper, ord)

alphabet_position :: String -> String
alphabet_position = unwords . map (show . (flip (-)) 64 . ord . toUpper) . filter isLetter
``````

## Explanation

The `.` operator composes functions, so they will be applied from right to left.

1. `filter isLetter` will remove all characters that are not letters from the string.
2. `map (show . (flip (-)) 64 . ord . toUpper)` Transforms each character to its position in the alphabet.
1. `toUpper` transforms the character to uppercase, so that we can substract 64 from it's code to know the position.
2. `ord` maps a character to its ASCII code.
3. `(flip (-) 64)` subtracts 64 from the character code. Since the code for `'A'` is 65, this will give us the position in the alphabet starting at index 1. The way it works is it partially applies the second argument of the subtract operator to 64, i.e., this is equivalent to `(\x -> x - 64)` but fancier.
4. `show` maps any type deriving from `Show` (`Int` in this case) to `String`.
3. `unwords` joins a list of strings using space as a separator.

a bit late but here's the answer anyway... in PHP

``````function alphabet_position(\$text){
\$alphabet = range('a', 'z');
\$strippedText = str_split(strtolower(preg_replace("/[^a-zA-Z]/", "", \$text)));
\$result = "";
foreach(\$strippedText as \$letter){
\$result .= array_search(\$letter, \$alphabet)+1 . " ";
}
return \$result;
}
echo alphabet_position("The sunset sets at twelve o' clock.");
``````

Lua, just as a series of string operations:

``````local function solution(text)
return text:lower()
:gsub("%A+", "")
:gsub("%a", function(n) return " " .. 1 + n:byte() - string.byte("a") end)
:sub(2)
end
``````

Lua, written with a loop and so a bit less wasteful:

``````local function solution(text)
local ns = {}
for a in text:gmatch("%a") do
table.insert(ns, 1 + a:lower():byte() - string.byte("a"))
end
return table.concat(ns, " ")
end
``````

JavaScript

``````let position = (str) => {
const upper = str.trim().toUpperCase().split('');
let arr = [];
upper.map(l => (/^[a-z]+\$/i.test(l)) && arr.push(l.charCodeAt(0)-64).toString())
return arr.join(" ");
}

position("The sunset sets at twelve o' clock.");
``````

A JS one-liner

``````alphaPosition = s => [...s.toLowerCase().replace(/[^a-z]/g, '')].map(c => c.charCodeAt(0) + 1 - 'a'.charCodeAt(0)).join(' ');
``````

Output:

``````> alphaPosition("The sunset sets at twelve o' clock.")
< "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11"
``````

In PHP using Laravel's Collection pipeline...

``````function alphabetPositions(\$string)
{
return collect(str_split(\$string))
->map(function (\$letter) {
return collect(range('a', 'z'))->flip()->get(strtolower(\$letter));
})
->filter()
->map(function (\$key) {
return \$key + 1;
})
->implode(' ');
}

echo alphabetPositions("The sunset sets at twelve o' clock.");
``````

Will be cleaner when PHP gets shorthand arrow functions, which I believe are coming in 7.4 😍 ...

``````function alphabetPositions(\$string)
{
return collect(str_split(\$string))
->map(fn(\$letter) => collect(range('a', 'z'))->flip()->get(strtolower(\$letter)))
->filter()
->map(fn(\$key) => \$key + 1)
->implode(' ');
}

echo alphabetPositions("The sunset sets at twelve o' clock.");
``````

solved in rust made with tests first :)

``````pub fn alphabet_position(s: &str) -> String {
s.to_lowercase()
.chars()
.filter(|x| x.is_alphabetic())
.map(|x| -> u8 { x as u8 - 'a' as u8 + 1 })
.map(|x| -> String { x.to_string() })
.collect::<Vec<String>>()
.join(" ")
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn it_should_relace_the_a_with_1() {
let replaced = alphabet_position("a");
assert_eq!(replaced, "1");
}

#[test]
fn it_should_relace_the_capital_a_with_1() {
let replaced = alphabet_position("A");
assert_eq!(replaced, "1");
}

#[test]
fn it_should_ignore_non_characters() {
let replaced = alphabet_position("'a a. 2");
assert_eq!(replaced, "1 1");
}

#[test]
fn it_should_relace_the_sentence() {
let replaced = alphabet_position("The sunset sets at twelve o' clock.");
assert_eq!(
replaced,
"20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11"
);
}
}
``````

Perl solution:

``````#!/usr/bin/perl
use warnings;
use strict;

sub alphabet_position {
join ' ', map ord() - 96, grep /[a-z]/, split //, lc shift
}

use Test::More tests => 1;

is alphabet_position("The sunset sets at twelve o' clock."),
'20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11';
``````

Reading from the right: `shift` gets the argument, `lc` lower-cases it, `split` using an empty regex splits it into characters, `grep` removes all non-letters, `ord` returns the ASCII ordinal number of each letter, 97 corresponds to `a`; `map` replaces the characters by the numbers, `join` connects the numbers back to a string.

See join, map, ord, grep, split, lc, shift.

Perl6:

``````sub alphabet-position(Str \$text) {
\$text.lc().split("").comb(/<:Ll>/).map({.ord() - 96}).join(" ")
}
``````

Or alternatively with the feed operator (and no type annotation, TIMTOWTDI):

``````sub alphabet-position(\$text) {
\$text
==> lc()
==> split("")
==> comb(/<:Ll>/)
==> map({.ord() - 96})
==> join(" ")
}

alphabet-position("The sunset sets at twelve o' clock.").say
# 20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11

``````

My take on this challenge, with Javascript

``````const encode = str => [...str.toLowerCase().replace(/[^a-z]/g, '')]
.map(ch => ch.charCodeAt() - 96)
.join(' ');

``````

so simple love it

"One-liner" (kind of) Ruby:

``````def alphabet_position(str)
str.downcase.split('').select { |c| c =~ /[a-z]/ }.map { |c| c.ord - 96 }.join(' ')
end
``````

``````def alphabet_position(str)
str.downcase.gsub(/[^a-z]/, '').split('').map{|c| c.ord - 96}.join(' ')
end
``````

ruby <3

``````def alphabet_position(s)
pos = (?a..?z |> zip 1..26 |> to_h)
s |> downcase |> scan /[a-z]/ |> map &pos |> join ' '
end
``````

C#

``````public static string AlphabetPosition(string text)
{
return string.Join(" ", text
.ToLower()
.Where(c => char.IsLetter(c))
.Select(c => (c - 'a') + 1)
.ToList());
}
``````

A tiny python solutiuon:

``````def alphabet_position(text):
converted = [str(ord(c) - ord('a') + 1) for c in text.lower() if c >= 'a']
return " ".join(converted)
``````

One line Javascript

``````const alphaPosition = str => [...str]
.filter(letter => /[a-zA-Z]/.test(letter))
.map(letter => letter.toLowerCase().charCodeAt(0) - 96)
.join(' ')
``````

``````function alphabetPosition(text) {
return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, str => str.charCodeAt() - 64 + ' ').trim();
}
``````

Python :

``````lambda s : ' '.join([str(ord(c)-ord('a')+1) for c in s.lower() if re.search('[a-z]',c)])
``````  