aboutsummaryrefslogtreecommitdiff
path: root/challenge-052/colin-crain/perl/ch-1.pl
blob: b3ec4f0a236c6cc4608cc8cf9847c86b85ca13f7 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#! /opt/local/bin/perl
#
#       stepping.pl
#
#       TASK #1
#         Stepping Numbers
#             Write a script to accept two numbers between 100 and 999. It
#             should then print all Stepping Numbers between them.
#
#             A number is called a stepping number if the adjacent digits have a
#             difference of 1. For example, 456 is a stepping number but 129 is
#             not.
#
#         method: another example of what I have begun to call problems in
#             "Concrete Number Theory"; where the objectives are not merely
#             placed in the relationships between values in the solutions, but
#             in the physical way that these numbers are represented on a page.
#
#             In this example we do not care so much as to what a number
#             represents, but rather whether its adjectant digits differ by 1.
#             It is not restricted that the difference should be either ascending or
#             descending or even consistant, thus we shall conclude not only
#             that 123 fits the bill and also 654 and 656.
#
#             Adjecent digits can be extracted arithmatically using division by
#             10 and integer rounding. Sure, why not? It's not exactly SpaceX
#             stuff. But why go through that trouble when we can apply text
#             processing to the number represented as a string? In Perl all we
#             need do is look at a number like a string, using a string function
#             for example, and a string pointer will be created and stored
#             alongside the integer value with the scalar and be available to do
#             string stuff forever after. Ahh, Perlguts. The good stuff.
#
#             For the record, Perlguts is demonstratively more fun than
#             spongiform encephalopathy, albeit often producing the same
#             effects. It is good to have a basic understanding of what's behind
#             the curtain though. Usually the number contained within a scalar
#             and the string representing that number appear identical. With the
#             interpreter silently switching behind the scenes, it is not
#             unreasonable that the casual user might think of them as being the
#             same physical data, read different ways, but they are not.
#             Normally updating one or another of these values triggers an
#             update of the other, but this is not necesaariy the case.
#
#             The stringified component of a scalar can even be a completely
#             different thing: in the $! scalar, the string component holds a
#             nice descriptive phrase, but the integer component holds a related
#             but structurally very different error number. The two components
#             need not even be related in any way, although getting this to
#             happen requires some pretty gruesome under the hood tinkering. For
#             the adventurous, the Scalar::Util module provides a dualvar()
#             function that will construct such arbitrary scalars. For most
#             users it's good just to understand that a Perl scalar is in fact a
#             rather complicated struct, comprised of many interconnected data
#             fields, keeping track of namespaces, reference counts, reference
#             blessing and many other relevant and changing pieces of information tuned to
#             exactly what that particular scalar happens to be being used for.
#
#             But back to treating numbers as strings. We can do this in Perl,
#             so we should. It's dead simple to dice a string into a list of
#             parts using split //. Once we have divided a number into three
#             separate digits, comparing the first to the second, and the second
#             to the third, will give us our answer. Wrapping this logic in a
#             subroutine comparmentalizes it nicely. Again, we don't care what
#             the digits represent. We only care about the logic of the
#             relationships, so this function only returns 1 for success and 0
#             for failure.
#
#             Feeding this function to grep {} creates a filter. Sorting the
#             commandline inputs allows us to make a range to filter. The valid
#             cases that pass through are printed out, one per line.
#
#       2020 colin crain
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##

use warnings;
use strict;
use feature ":5.26";

## ## ## ## ## MAIN:

my ($low, $high) = sort {$a <=> $b} @ARGV;

my @output = grep { stepping($_) } ($low..$high);

say for @output;


## ## ## ## ## SUBS:

sub stepping {
    my $num = shift;
    my ($a, $b, $c) = split //, $num;
    abs( $a - $b ) == 1 && abs( $b - $c ) == 1 ? 1 : 0;
}