# Perl Weekly Challenge 114

Both of this week’s solutions look remarkably similar, because we were able to utilize the `first` subroutine for each one!

## Task 1: Next Palindrome Number

You are given a positive integer `\$N`.

Write a script to find out the next Palindrome Number higher than the given integer `\$N`.

### Example

``````Input: \$N = 1234
Output: 1331

Input: \$N = 999
Output: 1001
``````

### Solution

See below for explanation and any implementation-specific comments.

``````sub challenge(Int \$N) returns Int {
(\$N^..Inf).first(-> \$num { \$num == \$num.flip }, :v); # 
}

sub MAIN(Int \$N) {
say challenge(\$N);
}
``````

This program runs as such:

``````\$ raku ch-1.raku 1234
1331
``````

### Explanation

This is fairly straightforward; we create an infinite range from `\$N` to infinity. This range will be lazily evaluated, so we don’t have to worry about memory. Then we find the first instance where `\$num` is equal to `\$num.flip`. That’s it!

1. Ranges are lazily evaluated, so it is safe to have these seemingly infinite range constructors.
2. `\$num.flip` technically returns a string, but `==` will coerce it to an integer (since `eq` should be used for string equality). This is convenient, but also kind of scary that conversions are happening without us knowing.
3. `first` returns both the index and value of that index by default. Since we only want the value, we pass in the `:v` flag to specify that.

## Task 2: Higher Integer Set Bits

You are given a positive integer `\$N`.

Write a script to find the next higher integer having the same number of 1 bits in binary representation as `\$N`.

### Example

``````Input: \$N = 3
Output: 5

Binary representation of \$N is 011. There are two 1 bits. So the next higher integer is 5 having the same the number of 1 bits i.e. 101.

Input: \$N = 12
Output: 17

Binary representation of \$N is 1100. There are two 1 bits. So the next higher integer is 17 having the same number of 1 bits i.e. 10001.
``````

### Solution

See below for explanation and any implementation-specific comments.

``````sub bits(Int \$base-ten) returns Int {
\$base-ten.base(2).comb.grep(* eq '1').elems; # 
}

sub challenge(Int \$N where \$N > 0) returns Int {
my \$bits = bits(\$N);
(\$N^..Inf).first(-> \$num { bits(\$num) == \$bits }, :v);
}

sub MAIN(Int \$N) {
say challenge(\$N);
}
``````

This program runs as such:

``````\$ raku ch-2.raku 12
17
``````

### Explanation

The meat of this lies in the `bits` function. It finds the number of `1` bits for a given integer. Given that, we again construct a range from `\$N` to infinity and find the first number that has the same number of bits as `\$N`.

1. `base` is a cool function to convert a number to any other base. So `9.base(3) eq '100'` and `255.base(16) eq 'FF'`. We use it to convert base 10 to base 2.
2. Once we have it in base 2, we need to convert it to a list of digits, so we use `comb`.
3. Once it has been converted to a list of digits, we filter (`grep`) for digits that equal `1`. Since `base` converted to a string, we use string equality (`eq`).
4. Finally, we just count the elements that equal `1` using `elems`.

## Final Thoughts

Lazy evaluation is one of the pillars of functional programming, so it is cool to see it exist in Raku. Always happy when I can break these down into a line or two!

Tags:

Categories:

Updated: