23
\$\begingroup\$

This is a code golf version of a similar question I asked on stack earlier but thought it'd be an interesting puzzle.

Given a string of length 10 which represents a base 36 number, increment it by one and return the resulting string.

This means the strings will only contain digits from 0 to 9 and letters from a to z.

Base 36 works as follows:

The right most digit is incremented, first by using 0 to 9

0000000000 > 9 iterations > 0000000009

and after that a to z is used:

000000000a > 25 iterations > 000000000z

If z needs to be incremented it loops back to zero and the digit to its left is incremented:

000000010

Further rules:

  • You may use upper case or lower case letters.
  • You may not drop leading zeros. Both input and output are strings of length 10.
  • You do not need to handle zzzzzzzzzz as input.

Test Cases:

"0000000000" -> "0000000001"
"0000000009" -> "000000000a"
"000000000z" -> "0000000010"
"123456zzzz" -> "1234570000"
"00codegolf" -> "00codegolg"
\$\endgroup\$
14
  • \$\begingroup\$ @JoKing Code-golf, cool ideas, and efficiency I guess. \$\endgroup\$
    – Jack Hales
    Commented Jul 28, 2018 at 3:08
  • 9
    \$\begingroup\$ I like the idea of implementing just the increment operation because it has the potential for strategies other than base-converting there and back. \$\endgroup\$
    – xnor
    Commented Jul 28, 2018 at 3:16
  • 2
    \$\begingroup\$ Welcome to PPCG! This is a nice challenge idea, however as some comments have pointed out, some parts of the specification are unclear. For the future I recommend using our sandbox where you can get feedback on a challenge before posting it. \$\endgroup\$
    – Laikoni
    Commented Jul 28, 2018 at 10:15
  • 1
    \$\begingroup\$ suggest you add something like "0zzzzzzzzz" (modify the most signficant digit) as a test case. It tripped up my C solution because of an off-by-one-error. \$\endgroup\$ Commented Jul 28, 2018 at 13:11
  • 1
    \$\begingroup\$ added an entry assuming it's ok -- a C entry already does it as well. \$\endgroup\$ Commented Jul 30, 2018 at 9:58

43 Answers 43

1
2
1
\$\begingroup\$

Pyke, 11 bytes

? b!!R+bhbt

Try it here!

? b         - Change default base of `base` command to 36 
            -  This is kind of clever because it modifies the list of characters 
            -  the command uses to exactly the same as it was originally, whilst
            -  forcing an overwrite from the default settings of 10. 
            -  The default setup works for base 36, you just have to specify it
            -  time when using the command.
            -  Literally `b.contents = modify(b.contents, func=lambda: noop)`
   !!       - The previous command returns `0123456789abcdefghijklmnopqrstuvwxyz`
            -  So we convert it into a 1 with (not not ^) for the following command:
     R+     -     "1"+input
       b    -    base(^, 36)
        h   -   ^ + 1
         b  -  base(^, 36)
          t - ^[1:]

Could be 2 bytes shorter with the following language change: If hex mode is used, change all base_36 and base_10 usages to base_92 (which isn't really base 92 in that context anyway)

\$\endgroup\$
1
\$\begingroup\$

Perl 5 -F, 47 bytes

($_=/z/?0:/9/?a:++$_)&&last for reverse@F;say@F

Try it online!

\$\endgroup\$
1
\$\begingroup\$

sed, 94 bytes

s/$/#:0123456789abcdefghijklmnopqrstuvwxyz#0/
:l
s/\(.\)#\(.*:.*\1\)\(#*.\)/\3\2\3/
tl
s/:.*//

Try it online!

Sed suffers a lot for having to change the characters by lookup.

\$\endgroup\$
0
1
\$\begingroup\$

Powershell, 79 78 82 bytes

+4 bytes: z and 9 inside an argument string fixed

$i=1
"$args"[9..0]|%{$r=([char]($i+$_)+'0a')[2*($i*$_-eq57)+($i*=$_-eq'z')]+$r};$r

Less golfed test script:

$f = {

$i=1                    # increment = 1
"$args"[9..0]|%{        # for chars in positions 0..9 in the argument string (in reverse order)
    $c=[char]($i+$_)    # Important! A Powershell calculates from left to right
                        # Therefore the subexpression ($i+$_) gets a value before the subexpression ($i=$_-eq122)
    $j=2*($i*$_-eq57)+  # j = 2 if the current char is '9' and previous i is 1
        ($i*=$_-eq122)  # j = 1 if the current char is 'z' and previous i is 1
                        # j = 0 othewise
                        # side effect is: i = 1 if the current char is 'z' and previous i is 1, i = 0 othewise
    $c=($c+'0a')[$j]    # get element with index j from the array
    $r=$c+$r            # accumulate the result string
}
$r                      # push the result to a pipe

}

@(
    ,("09fizzbuzz" , "09fizzbv00")
    ,("0000000000" , "0000000001")
    ,("0000000009" , "000000000a")
    ,("000000000z" , "0000000010")
    ,("123456zzzz" , "1234570000")
    ,("00codegolf" , "00codegolg")
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result"
}

Output:

True: 09fizzBv00
True: 0000000001
True: 000000000a
True: 0000000010
True: 1234570000
True: 00codegolg
\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 125 bytes

a=>{var x="";for(int i=9;;i--){var y=a[i]==90?'0':a[i]==57?'A':(char)(a[i]+1);x=y+x;a=a.Remove(i);if(y>48)break;}return a+x;}

Try it online!

Ungolfed:

a => {
    var x = "";                 // initialize x
    for (int i = 9; ; i--)      // starting at 9 (length of string minus one) and decrementing i indefinitely
    {
        var y = a[i] == 90 ?        // if the last character of a is 'Z'
            '0' :                       // y = '0'
            a[i] == 57 ?                // if the last character of a is '9'
                'A':                        // y = 'A'
                (char)(a[i] + 1);           // y = the ascii value of last character plus 1
        x = y + x;                  // prepend y to x
        a = a.Remove(i);            // remove the last character of a
        if (y > 48)                 // if y is a character other than '0',
            break;                      // break from the loop
    }
    return a + x;               // return the remainder of a, with x appended
}
\$\endgroup\$
1
\$\begingroup\$

Vyxal r, 61 bitsv1, 7.625 bytes

36~β›R↳›

Try it Online!

TIL a) 36β uses the alphabet 0-9a-z, b) β is type aware and c) pads one string to the length of another.

Explained

36~β›R↳›
36~β      # Convert input from base 36, leaving the 36 on the stack
    ›     # Increment
     R    # and convert to base 36 using the alphabet `0-9A-Z`
      ↳   # pad left to length of input string
       ›  # and replace spaces with 0s
\$\endgroup\$
1
\$\begingroup\$

Japt, 9 bytes

n36ÈÄÃùUA

Try it (includes all test cases)

n36ÈÄÃùTA     :Implicit input of string U
n36           :Convert from base 36
   È          :Pass through the following function and convert back
    Ä         :  Add 1
     Ã        :End function
      ùU      :Left pad with original U
        A     :  To length 10
\$\endgroup\$
1
  • \$\begingroup\$ Interesting that in this case, it's shorter to define a function than use the automatic function calling. \$\endgroup\$ Commented Jun 19, 2023 at 10:38
1
\$\begingroup\$

Python 3.8 (pre-release), 96 93 84 bytes

-9 bytes thanx to xnor

lambda a:''.join(chr((n:=-~int(a,36)//36**i%36)+48+39*(n>9))for i in range(9,-1,-1))

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ It looks like you don't need to walrus b since you're only referring to it once: TIO \$\endgroup\$
    – xnor
    Commented Mar 3 at 9:06
  • \$\begingroup\$ You're absolutely right! Outgolfed the Python 2 answer by 4 bytes now :) \$\endgroup\$
    – movatica
    Commented Mar 3 at 9:46
1
\$\begingroup\$

Uiua, 74 44 37 34 32 characters

-2 thanks to noodle man

i←|1⊂⟨++1×39=@9.|@0i◌⟩=@z.°⊂
⍜⇌i

Try it here!

Give input by putting it after the code. The part ⍜⇌i is basically indiscernible from a function in Uiua so I think this counts.

Uiua, 74 characters

a←"0123456789abcdefghijklmnopqrstuvwxyz0"
i←|1⊂⟨∘|⊙i⟩=@0.⊡:a+1⊗:a⊢:↘1.
⍜⇌i

For this one, i didn't know you could add 1 to characters yet. Other changes were the discovery of un join, and using one switch and some math instead of three switches.

\$\endgroup\$
3
  • \$\begingroup\$ Wish I knew about un join, that's cool \$\endgroup\$ Commented Mar 3 at 14:39
  • 1
    \$\begingroup\$ You can save 2 characters by changing ⟨+1|@a◌⟩=@9. to ++1×39=@9. (adding 40 to @9 gives @a) \$\endgroup\$ Commented Mar 3 at 14:56
  • \$\begingroup\$ 35 character version, which fits on one line, using do instead of recursion: ⊂⇌⊂++1×39=@9.⍢(⊙(⊂@0)◌)(=@z.°⊂):""⇌ \$\endgroup\$ Commented Mar 3 at 15:20
0
\$\begingroup\$

Jelly, 21 bytes

ØBḊiⱮḅ‘bɗ36Ż9¡ṫ-9‘ịØB

Try it online!

Uses uppercase. TIO link allows for lower/mixed case too.

\$\endgroup\$
0
\$\begingroup\$

Elixir, 70 bytes

fn x->"1"<>x=Integer.to_string 1+String.to_integer("1"<>x,36),36;x end

Explanation:

Prepends 1 to the input, converts it to an integer in base 36, increments it, converts it to a string in base 36, and matches it to "1" <> x (reverse concatenation), then returns x.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Mascarpone, 190 bytes

-13: followed DRY

['[/''/']v*v{/'a<v}^]v*v/'A<^[Av{*v{/a<v}^]v*v/'D<^[v'/>[]v*]'nD[A1/a</>v{{'r>/:!v{/'r<v}^$]'CD[[An/aCar]'rDA[0zyxwvutsrqponmlkjihgfedcba9876543210]$ar$A[]/$v*$a]'+D[[A'znaCra+]'rD$r[]/$]'fD

My editing version was formatted like this:

['[/''/']v*v{/'a<v}^]v*v/'A<^
[Av{*v{/a<v}^]v*v/'D<^
[v'/>[]v*]'nD
[A1/a</>v{{'r>/:!v{/'r<v}^$]'CD
[
[An/aCar]'rD
A[0zyxwvutsrqponmlkjihgfedcba9876543210]$ar$A[]/$v*$a
]'+D
[
[A'znaCra+]'rD
$r[]/$
]'fD
[squid09fzz]
f

Try it here! (doesn't support Link-embedded code)

I like Mascarpone, because it is so extensible and self-modifying that it could in theory become a terse language given enough setup, but also isn't actually terse at all. This feels like it makes golfing interesting. I define these operations:

  • A pops a symbol and installs an operation that pushes it at a.
  • D pops a symbol and a string, turns the string into an operation and installs it at the symbol.
  • n pushes the swap and then no-op operations.
  • C pops a symbol, two operations, and another symbol. It expects the operations to be swap and no-op. If the symbols are equal, it keeps the bottom operation, otherwise, the top one. It installs a no-op at r if it is no-op or it installs the parent interpreters r operation at r if it is swap. This mess is because I fused the equality testing with the recursion orchestration code, which used to be two operations.
  • + pops a symbol and increments it in base 36.
  • f takes a string, accomplishes the task, and returns a string.
\$\endgroup\$
0
\$\begingroup\$

Julia, 48 bytes

!x=string(parse(Int,x;base=36)+1;base=36,pad=10)

Attempt This Online!

a straight-forward solution by parsing and printing in base 36. I tried with regexes and character manipulations but couldn't get it shorter than this one

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.