Files

mon@razerRamon:~/tmp/haskell/rhythm_counting$ ll
total 24K
-rwxrwxr-x 1 mon mon  960 Jul 10 21:31 Example.hs*
-rw-rw-r-- 1 mon mon 1.4K Jul 10 21:03 Rhythm.hs
mon@razerRamon:~/tmp/haskell/rhythm_counting$ 

Haskell Code Snippet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module Rhythm (nextBin,nextDec,nextHex,nextVar) where

import qualified Numeric   as Num
import qualified Data.Char as Char

{- The Rhythm of Counting -}

count :: Int -> Int -> Int -> [Int] -> [Int]
count up low val =
  let
    f [    ] = [val]
    f (x:xs) =
      case x == up of
        True  -> low : f xs
        False -> x + 1 : xs
  in
    f

hlp ::  Int -> Int -> Int -> [Int] -> Maybe [Int]
hlp up low val xs =
  case all (\x -> x >= low && x <= up) xs of
    True  -> Just (count up low val xs)
    False -> Nothing

nextHlp :: ([Int] -> Maybe [Int]) -> [Char] -> Maybe [Char]
nextHlp f xs =
  let
    ys = reverse xs
    ds = map Char.digitToInt ys
  in
    case f ds of
      Just vs -> Just (reverse (map Char.intToDigit vs))
      Nothing -> Nothing

nextBin :: [Char] -> Maybe [Char]
nextBin =
  nextHlp (hlp 1 0 1)

nextDec :: [Char] -> Maybe [Char]
nextDec =
  nextHlp (hlp 9 0 1)

nextHex :: [Char] -> Maybe [Char]
nextHex xs =
  let
    ys = reverse xs
    ds = map Char.digitToInt ys
  in
    case hlp 0xf 0x0 0x1 ds of
      Just vs -> Just (reverse (foldl (\a v -> a ++ Num.showHex v "") "" vs))
      Nothing -> Nothing

nextVar :: [Char] -> Maybe [Char]
nextVar xs =
  let
    ys = reverse xs
    cs = map Char.ord ys
  in
    case hlp 122 97 97 cs of
      Just vs -> Just (reverse (map Char.chr vs))
      Nothing -> Nothing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env stack
{- stack
   --resolver lts-8.21
   --install-ghc
   runghc
   --
   -Wall -Werror
-}

module Main (main) where

import qualified Data.List as List
import qualified Rhythm    as Rhythm

main :: IO ()
main =
  let
    {- Infinity many unique (and optimal shortest?) variables -}
    vs x = List.unfoldr(\(Just v) -> Just (v, Rhythm.nextVar v)) (Just x)
  in
    do
      {- The next binary after 3 is 4: -}
      putStrLn (show (Just "1000" == Rhythm.nextBin "111"))
    
      {- The next number after 999 is 1000: -}
      putStrLn (show (Just "1000" == Rhythm.nextDec "999"))

      {- The next number after "fff" is 1000: -}
      putStrLn (show (Just "1000" == Rhythm.nextHex "fff"))

      {- The next variable after "zzz" is "aaaa": -}
      putStrLn (show (Just "aaaa" == Rhythm.nextVar "zzz"))

      {- We retrieve a 10 unique of the shortest variables, starting from "z" -}
      let ten = take 10 (vs "z") in putStrLn (show ten)

Haskell Code output:

mon@razerRamon:~/tmp/haskell/rhythm_counting$ ./Example.hs 
True
True
True
True
["z","aa","ab","ac","ad","ae","af","ag","ah","ai"]
mon@razerRamon:~/tmp/haskell/rhythm_counting$

References: