base10-inc.sed: New script demonstrating regex-based addition

It might be easy to guess where I'm heading with the concepts that I'm
demonstrating with these scripts.  It's just fun to do, and I've never
had an excuse to actually do it.  ("It" referring to something for future
commits.)

You can try this out like this:

  $ ./animate base10-inc.sed <( echo 000 ) 0.01

* regex/base10-inc.sed: New file.
master
Mike Gerwitz 2018-11-22 22:09:44 -05:00
parent cc583c6cb7
commit 107d090a04
Signed by: mikegerwitz
GPG Key ID: 8C917B7F5DC51BA2
1 changed files with 77 additions and 0 deletions

View File

@ -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 <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 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