Mike Gerwitz

Free Software Hacker+Activist

aboutsummaryrefslogtreecommitdiffstats
blob: c924d975349826c6874f7a36b1f9e3b8810edb92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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 (see `base10-mul.sed').
# 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