78 lines
2.2 KiB
Sed
78 lines
2.2 KiB
Sed
# Increment base10 number by 1


#


# Copyright (C) 2018 Mike Gerwitz


#


# This program is free software: you can redistribute it and/or modify


# it under the terms of the GNU General Public License as published by


# the Free Software Foundation, either version 3 of the License, or


# (at your option) any later version.


#


# This program is distributed in the hope that it will be useful,


# but WITHOUT ANY WARRANTY; without even the implied warranty of


# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


# GNU General Public License for more details.


#


# You should have received a copy of the GNU General Public License


# along with this program. If not, see <http://www.gnu.org/licenses/>.


#


# This shows how to perform basic arithmetic on numbers using regular


# expressions. The method is outlined below. It's easy to see that, for


# any baseN number of M digits, we need NM regexes. For K such numbers, we


# need NMK regexes. The more M or K we have, the more complex the regexes


# become to handle the offsets. (The use of the `^' and `$' anchors alone


# for replacements are only sufficient for M≤3 when K=1; what do we have to


# do when M>3 to replace only the digits we are interested in?)


#


# It is possible to subtract using the same concept (see `base10mul.sed').


# Further, since we can implement addition and subtraction, we can also


# implement multiplication and division.


#


# TO USE: Provide a 0padded 3digit base10 number. Each time this script


# is run, the number will be incremented by one. Exits with exit code 1 if


# a non3digitnumber is provided; and 2 once we cannot count any higher.


##




# Input must only be numbers


/^[09]\{3\}$/!q1




# Increment 1s (third character). If we overflow, represent the overflow as


# an `A', which is then handled below.


s/9$/A/


s/8$/9/


s/7$/8/


s/6$/7/


s/5$/6/


s/4$/5/


s/3$/4/


s/2$/3/


s/1$/2/


s/0$/1/




# Carry 10s by converting the overflow character `A' to a `0' and


# incrementing the 10s position.


s/9A$/A0/


s/8A$/90/


s/7A$/80/


s/6A$/70/


s/5A$/60/


s/4A$/50/


s/3A$/40/


s/2A$/30/


s/1A$/20/


s/0A$/10/




# Same as above, but for 100s.


s/^9A/A0/


s/^8A/90/


s/^7A/80/


s/^6A/70/


s/^5A/60/


s/^4A/50/


s/^3A/40/


s/^2A/30/


s/^1A/20/


s/^0A/10/




# Any remaining carry flags means we can't count any higher.


/A/!b; q2
