USING: kernel combinators.short-circuit sequences ; IN: successor ! Throughout, ?? reads as follows: f means not in range, 0 for in ! range and 1 for at end of range. : in-range? ( elt min max -- ? ) [ over ] dip [ >= ] [ <= ] 2bi* and ; : where-in-range? ( elt min max -- ?? ) [ nip = 1 and ] [ in-range? 0 and ] 3bi or ; : inc-able? ( elt -- ?? ) { [ CHAR: a CHAR: z where-in-range? ] [ CHAR: A CHAR: Z where-in-range? ] [ CHAR: 0 CHAR: 9 where-in-range? ] } 1|| ; : carry ( elt -- elt' ) { { CHAR: z [ CHAR: a ] } { CHAR: Z [ CHAR: A ] } { CHAR: 9 [ CHAR: 0 ] } [ "Aargh." throw ] } case ; : map-carry ( seq -- seq' ) [ dup inc-able? [ carry ] when ] map ; : split-carry ( seq -- before elt/f after ) dup [ inc-able? 0 = ] find-last dup [ [ cut-slice rest-slice ] dip swap ] [ 2drop [ f f ] dip ] if ; : successor ( seq -- seq' ) split-carry [ [ 1 + suffix ] when* ] dip map-carry append >string ;