##
**TASK #1 › Reverse Integer**

Submitted by: Mohammad S Anwar

You are given an integer $N.

Write a script to reverse the given integer and print the result. Print 0 if the result doesn’t fit in 32-bit signed integer.

The number 2,147,483,647 is the maximum positive value for a 32-bit signed binary integer in computing.

```
Example 1:
Input: 1234
Output: 4321
Example 2:
Input: -1234
Output: -4321
Example 3:
Input: 1231230512
Output: 0
```

###
**32 bit in 2020??**

Looks easy for me because *.flip* method... but actually needed more time to get used to *32-bit singed integer*

To express a signed integer in 8 bit, one *precious* bit needs to be sacrificed to express both positive and negative value. and somehow positive-side seems to decide to give their be-loved single bit to negative-team. *(of course there is a reason)*

I'm not a computer scientist.. I don't understand them all, but more interestingly 2³¹ - 1

(2147483647) is also a prime number. Let's listen what Raku is about to say 🎤

```
> is-prime(2³¹ - 1).raku.say
Bool::True
```

Okay Raku told us in formal way but we can simply understand it as "True".

###
**Flip**

```
> 123.flip
321
```

looks like a solution. done. however we need to filter the result.

the number seen as above can be rewritten like below as well.

```
> 1 +< 32 -1 # when positive integer
2147483647
```

*negative don't need to subtract 1 from the number*

So when we have "1231230512", flip the string and compare it with (2³¹ - 1). don't we?

```
> "1231230512".flip
2150321321
> 2150321321 < 2³¹ - 1
False
```

oh... a something have changed my mind.

###
**Overflow**

My laptop is 64bit machine I don't really need to worry about 32 bit but.. maybe this is one more hidden task. writing the solution as if we are using 32 bit machine. so we cannot make a number above (2³¹ - 1) because after that we will get negative value. *What a temper it is.*

So thinking about the limit we can maybe compare the number as a string

###
**String Comparison is Not The Same Thing**

One more problem we have is that string comparison is not acting as like a integer one.

*for example*

```
> 123 <=> 456
Less
> "123" cmp "456"
Less
> 45 <=> 123
Less
> "45" cmp "123"
More # ????
```

So I decided to compare the length of both numbers before string comparison. and I had got another problem.

###
**300**

```
> 300.flip # or "300".flip or 300.Str.flip
003
```

*003* means *3* and the length of the "300" is 3 but length of "3" is now "1" again. So starting all the Persian must be destroyed. (What a racist !!!👿) and I used the regular expression here.

```
> S/^0+// with (300.Str.flip)
3
```

📚 *S//*

###
**Subroutines I Made**

To check limitation, I made a subroutine to get the number(absoulte)

```
sub abslim (Str $n, $bit = 32) {
(1 +< $bit.pred) - ($n.substr(^1) ne "-")
}
```

To reverse(or flip) the string ..

```
sub rev-int ( Int $n --> Str ) {
("","-")[+($n < 0)] ~ $n.abs.flip
}
```

I applied abs before flip to handle negative value as well. and get a side effect of removing any "+" sign mark before proceeding.

and prepend the "-" sign if needed.

To filter the number I used a little twisted syntax by using List or Hash because sometimes I missed the functional programming style declaration of a variable(actually a function).

```
sub filter32bit( Str $nstr ) {
# assume this is 32bit machine
# so this will get a reversed string (with sign prepended)
# and compare it with limit value as strings
my $lstr = abslim($nstr).Str;
my $nstr-abs = S/^0+// # remove zeroes in the beginging. for better cmp.
with $nstr.subst("-",""); # disgard the sign as well.
say "[FLTR] ",($nstr-abs gt $nstr ?? "-" !! ""),$lstr if $d;
# better read bottom up
($nstr.Int but "0",
$nstr.Int)[
( Less => True,
Same => $nstr lt $lstr,
More => False,
).Hash.{$nstr-abs.chars <=> $lstr.chars} ]
}
```

###
**Final Code**

I applied 📚∘ infix for my curiosity. so looks more unusual but it was fun!!!

```
our $d is export = False; # `export' is needed to use globaly
sub rev-int ( Int $n --> Str ) {
("","-")[+($n < 0)] ~ $n.abs.flip
}
# return absoulte value of limitation in 32 bit (without sign)
# with check sign of $n
sub abslim (Str $n, $bit = 32) {
(1 +< $bit.pred)-($n.substr(^1) ne "-")
}
sub filter32bit( Str $nstr ) {
# assume this is 32bit machine
# so this will get a reversed string (with sign prepended)
# and compare it with limit value as strings
my $lstr = abslim($nstr).Str;
my $nstr-abs = S/^0+// # remove zeroes in the beginging. for better cmp.
with $nstr.subst("-",""); # disgard the sign as well.
say "[FLTR] ",($nstr-abs gt $nstr ?? "-" !! ""),$lstr if $d;
# better read bottom up
($nstr.Int but "0",
$nstr.Int)[
( Less => True,
Same => $nstr lt $lstr,
More => False,
).Hash.{$nstr-abs.chars <=> $lstr.chars} ]
}
sub dmsg-tap (Any $a) { say("[DBG",$++,"] $a"); $a;};
multi MAIN (Int:D \N, Bool:D :$v = False) {
# side effect?: when use multi with MAIN (even though has a MAIN declared),
# raku gives a simple help message with invalid args.
my @solution-chain = &filter32bit, &rev-int;
my @speaker = ($v
?? |(&dmsg-tap) xx @solution-chain.elems # say each step
!! &say); # or just result
my @app-chain = (roundrobin @speaker, @solution-chain).flat;
if $v {
$d = True;
"the chain of subroutines looks like ...".say;
for (reverse @app-chain).kv -> $i, $r {
say "$i: {$r.raku}";
}
"and answer is ...\n".say;
}
([∘] @app-chain)(N);
# or we can save it as a variable and execute.
# but it was skipped as single usage.
# i.e.
# my $app = [∘] @app-chain;
# $app(N);
}
```

Thank you for reading~!!

please visit 🐪🦋PWC for more challenge and further update !!!

## Discussion