Decrypt String from Alphabet to Integer Mapping

🏠 ⬅️ ➑️

You are given a string s formed by digits and '#'. We want to map s to English lowercase characters as follows:

  • Characters ('a' to 'i') are represented by ('1' to '9') respectively.
  • Characters ('j' to 'z') are represented by ('10#' to '26#') respectively.

Return the string formed after mapping.

The test cases are generated so that a unique mapping will always exist.

Example 1:

Input: s = "10#11#12 " Output: "jkab " Explanation: "j " -> "10# " , "k " -> "11# " , "a " -> "1 " , "b " -> "2 ".

Example 2:

Input: s = "1326# " Output: "acz "

Constraints:

  • 1 <= s.length <= 1000
  • s consists of digits and the '#' letter.
  • s will be a valid string such that mapping is always possible.

Note: This problem is from LeetCode.
❌ Compiled
❌ Executed
❌ Correct
program main
    implicit none

    character(len=:), allocatable :: s, result

    s = "10#11#12"
    print "(A)", solve_problem(s)

    s = "1326#"
    print "(A)", solve_problem(s)

contains

    function solve_problem(s) result(result)
        implicit none
        character(len=*), intent(in) :: s
        integer :: i, j, k
        character(len=1) :: c
        character(len=:), allocatable :: result

        allocate(character(len=size(s)) :: result)

        do i = 1, size(s)
            c = s(i:i)
            if (c >= 'a' .and. c <= 'i') then
                result(i:i) = char(ichar('1') + ichar(c) - ichar('a'))
            else if (c >= 'j' .and. c <= 'z') then
                result(i:i) = char(ichar('10#') + ichar(c) - ichar('j'))
            end if
        end do

    end function solve_problem

end program main
βœ… Compiled
βœ… Executed
❌ Correct
module letter_mapping

implicit none

contains

function map_letters(s) result(output)

character(len=*), intent(in) :: s
character(len=len(s)) :: output

integer :: i, j, num

output = ""

do i = 1, len(s)

    if (s(i:i) == "#") then

        num = 10

    else

        read(s(i:i), '(i1)') num

    end if

    if (num >= 1 .and. num <= 9) then

        output(i:i) = char(iachar('a') + num - 1)

    else if (num >= 10 .and. num <= 26) then

        output(i:i) = char(iachar('j') + num - 10)

    end if

end do

end function map_letters

end module letter_mapping

program test_letter_mapping

use letter_mapping

implicit none

character(len=1000) :: s, output

s = "10#11#12 "
output = map_letters(s)
write (*,*) output

s = "1326# "
output = map_letters(s)
write (*,*) output

end program test_letter_mapping
🌐 Data from online sources
from collections import defaultdict, deque

def sortItems(n, m, group, beforeItems):
    def topological_sort(outdegree, edges):
        res = []
        q = deque([i for i in range(len(outdegree)) if outdegree[i] == 0])
        while q:
            u = q.pop()
            res.append(u)
            for v in edges[u]:
                outdegree[v] -= 1
                if outdegree[v] == 0:
                    q.append(v)
        return res

    # Calculate outdegrees and dependencies for groups and items
    group_outdegree = [0] * m
    group_edges = defaultdict(list)

    item_outdegree = [0] * n
    item_edges = defaultdict(list)

    for i in range(n):
        for dep in beforeItems[i]:
            a, b = group[i], group[dep]
            if a != -1 and a != b and not (group_edges[b] and group_edges[b][-1] == a):
                group_edges[b].append(a)
                group_outdegree[a] += 1
            if a != b:
                item_edges[dep].append(i)
                item_outdegree[i] += 1

    group_order = topological_sort(group_outdegree, group_edges)
    if len(group_order) < m:
        return []

    item_order = topological_sort(item_outdegree, item_edges)
    if len(item_order) < n:
        return []

    # Combine orders
    res = [0] * n
    idx = 0
    for gi in group_order:
        for item_idx in item_order:
            if group[item_idx] == gi:
                res[idx] = item_idx
                idx += 1

    return res
The algorithm consists of the following steps:
  1. Calculate the outdegrees and edges for both the groups and the items based on their dependencies.
  2. Perform a topological sort on group dependencies and item dependencies separately. If the topological order of groups or items is not complete, return an empty list because we cannot find a valid solution.
  3. Combine the orders based on grouping. For each group in the order of groups, find the items belonging to that group from itemOrder and add it to the final result.
  4. Return the combined order as the final result.
🌐 Data from online sources
#include <vector>
#include <algorithm>

std::vector<int> sortItems(int n, int m, std::vector<int>& group, std::vector<std::vector<int>>& beforeItems) {
    // Calculate outdegrees and dependencies for groups and items
    std::vector<int> groupOutdegree(m, 0);
    std::vector<std::vector<int>> groupEdges(m);
    std::vector<int> itemOutdegree(n, 0);
    std::vector<std::vector<int>> itemEdges(n);

    for (int i = 0; i < group.size(); ++i) {
        for (const int dep : beforeItems[i]) {
            int a = group[i], b = group[dep];
            if (a != -1 && a != b && !groupEdges[b].empty() && groupEdges[b].back() == a) {
                groupEdges[b].push_back(a);
                ++groupOutdegree[a];
            }
            if (a != b) {
                itemEdges[dep].push_back(i);
                ++itemOutdegree[i];
            }
        }
    }

    // Topological sort
    auto topologicalSort = [](const std::vector<int>& outdegree, const std::vector<std::vector<int>>& edges) {
        std::vector<int> res, q;
        for (int i = 0; i < outdegree.size(); ++i)
            if (outdegree[i] == 0)
                q.push_back(i);

        while (!q.empty()) {
            int u = q.back();
            q.pop_back();
            res.push_back(u);

            for (const int v : edges[u])
                if (--const_cast<int&>(outdegree[v]) == 0)
                    q.push_back(v);
        }
        return res;
    };

    std::vector<int> groupOrder = topologicalSort(groupOutdegree, groupEdges);
    if (groupOrder.size() < m)
        return {};

    std::vector<int> itemOrder = topologicalSort(itemOutdegree, itemEdges);
    if (itemOrder.size() < n)
        return {};

    // Combine orders
    std::vector<int> res;
    for (const int gi : groupOrder)
        for (const int idx : itemOrder)
            if (group[idx] == gi)
                res.push_back(idx);

    return res;
}
The algorithm consists of the following steps:
  1. Calculate the outdegrees and edges for both the groups and the items based on their dependencies.
  2. Perform a topological sort on group dependencies and item dependencies separately. If the topological order of groups or items is not complete, return an empty list because we cannot find a valid solution.
  3. Combine the orders based on grouping. For each group in the order of groups, find the items belonging to that group from itemOrder and add it to the final result.
  4. Return the combined order as the final result.