Created
January 19, 2018 23:55
-
-
Save wisq/199b4f984c2c69235c5f6dbf63c396bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule StrNext do | |
@character_ranges [ | |
{'A', 'Z'}, | |
{'a', 'z'}, | |
{'0', '9'} | |
] | |
@characters Enum.map(@character_ranges, fn {a, z} -> | |
hd(a)..hd(z) | |
|> Enum.to_list() | |
end) | |
|> List.flatten() | |
def next(str) do | |
String.reverse(str) | |
|> next_string() | |
|> String.reverse() | |
end | |
def next_string(""), do: <<hd(@characters)>> | |
def next_string(<<byte, rest::bitstring>>) do | |
case next_character(byte) do | |
{c, true} -> <<c>> <> next_string(rest) | |
{c, false} -> <<c>> <> rest | |
end | |
end | |
def next_character(c) when c in @characters do | |
if (c + 1) in @characters do | |
{c + 1, false} | |
else | |
index = Enum.find_index(@characters, &(&1 == c)) | |
if c = Enum.at(@characters, index + 1) do | |
{c, false} | |
else | |
{hd(@characters), true} | |
end | |
end | |
end | |
def next_character(c) do | |
{c, true} | |
end | |
end | |
# Passes these Ruby `String#succ` cases: | |
"abce" = StrNext.next("abcd") | |
"THX1139" = StrNext.next("THX1138") | |
"<<koalb>>" = StrNext.next("<<koala>>") | |
# Fails these Ruby `String#succ` cases: | |
# We don't restrict letters to letters and numbers to numbers. | |
# "2000aaa" = StrNext.next("1999zzz") | |
"1999zz0" = StrNext.next("1999zzz") | |
# Ditto. | |
# "AAAA0000" = StrNext.next("ZZZ9999") | |
"ZZaAAAA" = StrNext.next("ZZZ9999") | |
# We don't do punctuation. | |
# "**+" = StrNext.next("***") | |
"A***" = StrNext.next("***") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment