diff --git a/regex/base10-inc.sed b/regex/base10-inc.sed new file mode 100644 index 0000000..d1f32b6 --- /dev/null +++ b/regex/base10-inc.sed @@ -0,0 +1,77 @@ +# Increment base-10 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 . +# +# 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 base-N 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. Further, since we can +# implement addition and subtraction, we can also implement multiplication +# and division. +# +# TO USE: Provide a 0-padded 3-digit base-10 number. Each time this script +# is run, the number will be incremented by one. Exits with exit code 1 if +# a non-3-digit-number is provided; and 2 once we cannot count any higher. +## + +# Input must only be numbers +/^[0-9]\{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