License Key Formatting

🏠 ⬅️ ➡️

You are given a license key represented as a string s that consists of only alphanumeric characters and dashes. The string is separated into n + 1 groups by n dashes. You are also given an integer k.

We want to reformat the string s such that each group contains exactly k characters, except for the first group, which could be shorter than k but still must contain at least one character. Furthermore, there must be a dash inserted between two groups, and you should convert all lowercase letters to uppercase.

Return the reformatted license key.

Example 1:

Input: s = "5F3Z-2e-9-w ", k = 4 Output: "5F3Z-2E9W " Explanation: The string s has been split into two parts, each part has 4 characters. Note that the two extra dashes are not needed and can be removed.

Example 2:

Input: s = "2-5g-3-J ", k = 2 Output: "2-5G-3J " Explanation: The string s has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.

Constraints:

  • 1 <= s.length <= 105
  • s consists of English letters, digits, and dashes '-'.
  • 1 <= k <= 104

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

    character(len=:), allocatable :: s
    integer :: n, k

    call get_command_argument(1, s)
    read (s, *) n
    call get_command_argument(2, s)
    read (s, *) k

    print '(A)', solve(s, n, k)

contains

    function solve(s, n, k) result(res)
        implicit none
        character(len=*), intent(in) :: s
        integer, intent(in) :: n, k
        character(len=:), allocatable :: res
        integer :: i, j, l

        l = len(s)
        allocate(character(l) :: res)

        do i = 1, n
            if (i == 1) then
                j = min(k, l)
            else
                j = k
            end if
            res(i:j) = s(i:j)
            if (i /= n) then
                res(j+1:j+1) = '-'
            end if
        end do

        ! Convert lowercase letters to uppercase
        do i = 1, l
            if (res(i:i) >= 'a' .and. res(i:i) <= 'z') then
                res(i:i) = char(ichar(res(i:i)) - 32)
            end if
        end do

    end function solve

end program main
Compiled
Executed
Correct
module license_key_formatting
    implicit none

contains

    function license_key_formatting(s, k) result(formatted_key)
        implicit none
        character(len=*), intent(in) :: s
        integer, intent(in) :: k
        character(len=:), allocatable :: formatted_key

        ! Split the string into an array of substrings
        character(len=:), allocatable :: substrings(:)
        integer :: n_substrings
        call split_string(s, substrings, n_substrings)

        ! Reformat the substrings
        character(len=:), allocatable :: reformatted_substrings(:)
        call reformat_substrings(substrings, reformatted_substrings, n_substrings)

        ! Join the reformatted substrings into a single string
        character(len=:), allocatable :: formatted_key
        call join_strings(reformatted_substrings, formatted_key)

    contains

        ! Split a string into an array of substrings
        subroutine split_string(s, substrings, n_substrings)
            implicit none
            character(len=*), intent(in) :: s
            character(len=:), allocatable, intent(out) :: substrings(:)
            integer, intent(out) :: n_substrings

            ! Initialize the number of substrings to 0
            n_substrings = 0

            ! Loop over the characters in the string
            integer :: i
            do i = 1, len(s)
                ! If the current character is a dash, increment the number of substrings
                if (s(i:i) == '-') then
                    n_substrings = n_substrings + 1
                end if
            end do

            ! Allocate the array of substrings
            allocate(substrings(n_substrings))

            ! Reset the number of substrings to 0
            n_substrings = 0

            ! Loop over the characters in the string again
            integer :: j
            do j = 1, len(s)
                ! If the current character is not a dash, add it to the current substring
                if (s(j:j) /= '-') then
                    substrings(n_substrings) = substrings(n_substrings) // s(j:j)
                ! If the current character is a dash, increment the number of substrings
                else
                    n_substrings = n_substrings + 1
                end if
            end do
        end subroutine split_string

        ! Reformat an array of substrings
        subroutine reformat_substrings(substrings, reformatted_substrings, n_substrings)
            implicit none
            character(len=:), allocatable, intent(in) :: substrings(:)
            character(len=:), allocatable, intent(out) :: reformatted_substrings(:)
            integer, intent(in) :: n_substrings

            ! Loop over the substrings
            integer :: i
            do i = 1, n_substrings
                ! If the current substring is shorter than k characters, pad it with spaces
                if (len(substrings(i)) < k) then
                    reformatted_substrings(i) = substrings(i) // repeat(' ', k - len(substrings(i)))
                ! Otherwise, use the substring as is
                else
                    reformatted_substrings(i) = substrings(i)
                end if

                ! Convert the current substring to uppercase
                reformatted_substrings(i) = to_upper(reformatted_substrings(i))
            end do
        end subroutine reformat_substrings

        ! Join an array of strings into a single string
        subroutine join_strings(strings, joined_string)
            implicit none
            character(len=:), allocatable, intent(in) :: strings(:)
            character(len=:), allocatable, intent(out) :: joined_string

            ! Initialize the joined string to the first substring
            joined_string = strings(1)

            ! Loop over the remaining substrings
            integer :: i
            do i = 2, size(strings)
                ! Add a dash and the current substring to the joined string
                joined_string = joined_string // '-' // strings
🌐 Data from online sources
def license_key_formatting(s: str, k: int) -> str:
    result = []
    count = 0
    for c in reversed(s):
        if c != '-':
            if count == k:
                result.append('-')
                count = 0
            result.append(c.upper())
            count += 1
    return ''.join(reversed(result))

The algorithm starts by iterating the string s from the end to the beginning, skipping the dashes. During the iteration, we check whether the current group has reached k characters. If so, we append a dash to the result string. We then add the current character, converting it to uppercase, to the result string. After the iteration, we reverse the result string for C++, Java, and Python implementations (for JavaScript, we prepend characters so no need to reverse in the end). This is because we built the reformatted license key in reverse order. Finally, we return the result string.

🌐 Data from online sources
#include <cctype>
#include <string>
using namespace std;

string licenseKeyFormatting(string s, int k) {
    string result = "";
    int count = 0;
    for (int i = s.size() - 1; i >= 0; i--) {
        if (s[i] != '-') {
            if (count == k) {
                result.push_back('-');
                count = 0;
            }
            result.push_back(toupper(s[i]));
            count++;
        }
    }
    reverse(result.begin(), result.end());
    return result;
}

The algorithm starts by iterating the string s from the end to the beginning, skipping the dashes. During the iteration, we check whether the current group has reached k characters. If so, we append a dash to the result string. We then add the current character, converting it to uppercase, to the result string. After the iteration, we reverse the result string for C++, Java, and Python implementations (for JavaScript, we prepend characters so no need to reverse in the end). This is because we built the reformatted license key in reverse order. Finally, we return the result string.