Perl Weekly Challenge 357.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 357.

Task 1: Kaprekar Constant

Submitted by: Mohammad Sajid Anwar
Write a function that takes a 4-digit integer and returns how many iterations are required to reach Kaprekar’s
constant (6174). For more information about Kaprekar's Constant please follow the wikipedia page.

Example 1
Input: $int = 3524
Output: 3

Iteration 1: 5432 - 2345 = 3087
Iteration 2: 8730 - 0378 = 8352
Iteration 3: 8532 - 2358 = 6174

Example 2
Input: $int = 6174
Output: 0

Example 3
Input: $int = 9998
Output: 5

Iteration 1: 9998 - 8999 = 0999
Iteration 2: 9990 - 0999 = 8991
Iteration 3: 9981 - 1899 = 8082
Iteration 4: 8820 - 0288 = 8532
Iteration 5: 8532 - 2358 = 6174

Example 4
Input: $int = 1001
Output: 4

Iteration 1: 1100 - 0011 = 1089
Iteration 2: 9810 - 0189 = 9621
Iteration 3: 9621 - 1269 = 8352
Iteration 4: 8532 - 2358 = 6174

Example 5
Input: $int = 9000
Output: 4

Iteration 1: 9000 - 0009 = 8991
Iteration 2: 9981 - 1899 = 8082
Iteration 3: 8820 - 0288 = 8532
Iteration 4: 8532 - 2358 = 6174

Example 6
Input: $int = 1111
Output: -1

The sequence does not converge on 6174, so return -1.

Given a four digit number N, I order its digits toproduce two numbers abcd and dcba, subtract them, where a>=b>=c=>d, and repeat until I reach a fixed point, either 0000 or Kaprekar’s constant. I use sprintf with the format “%04d” to add leading zeroes if necessary. I set the special variable $” so that arrays of digits are stringified as numbers. The code takes a two-liner.

perl -E '
$"="";for(@ARGV){$n=0;$x=$_;while(1){@d=sort split"",sprintf"%04d",$y=$x;
$x=reverse(@d)-"@d";last if $x==$y; ++$n}say"$_ -> ",$x?$n:-1}
' 3524 6174 9998 1001 9000 1111

Results:

3524 -> 3
6174 -> 0
9998 -> 5
1001 -> 4
9000 -> 4
1111 -> -1

The full code is:

 1  # Perl weekly challenge 357
 2  # Task 1:  Kaprekar Constant
 3  #
 4  # See https://wlmb.github.io/2026/01/19/PWC357/#task-1-kaprekar-constant
 5  use v5.36;
 6  use English;
 7  use feature qw(try);
 8  die <<~"FIN" unless @ARGV;
 9      Usage: $0 N0 N1...
10      to find how many iterations are required to convert the
11      four digit numbers Nk to Kaprekar's constant 6174.
12      In each iteration the digits of the current number are
13      ordered and the smallest resulting integer is subtracted
14      from the largest;
15      FIN
16  $LIST_SEPARATOR="";
17  for(@ARGV){
18      try {
19          die "Expected four-digit inputs: $_" unless /^\d{4}$/;
20          my $iterations=0;
21          my $next=$_;
22          while(1){
23              my @digits = sort {$a<=>$b} split "", sprintf "%04d", my $current=$next;
24              $next = "".reverse(@digits)-"@digits";
25              last if $current==$next;
26              ++$iterations
27          }
28          say"$_ -> ", $next!=0?$iterations:-1
29      }
30      catch($e){warn $e;}
31  }

Example:

./ch-1.pl 3524 6174 9998 1001 9000 1111

Results:

3524 -> 3
6174 -> 0
9998 -> 5
1001 -> 4
9000 -> 4
1111 -> -1

Task 2: Unique Fraction Generator

Submitted by: Yary
Given a positive integer N, generate all unique fractions you can create using
integers from 1 to N and follow the rules below:

- Use numbers 1 through N only (no zero)
- Create fractions like numerator/denominator
- List them in ascending order (from smallest to largest)
- If two fractions have the same value (like 1/2 and 2/4),
  only show the one with the smallest numerator
Example 1
Input: $int = 3
Output: 1/3, 1/2, 2/3, 1/1, 3/2, 2/1, 3/1
Example 2
Input: $int = 4
Output: 1/4, 1/3, 1/2, 2/3, 3/4, 1/1, 4/3, 3/2, 2/1, 3/1, 4/1

Example 3
Input: $int = 1
Output: 1/1

Example 4
Input: $int = 6
Output: 1/6, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4,
        4/5, 5/6, 1/1, 6/5, 5/4, 4/3, 3/2, 5/3, 2/1,
        5/2, 3/1, 4/1, 5/1, 6/1

Example 5
Input: $int = 5
Output: 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1/1,
        5/4, 4/3, 3/2, 5/3, 2/1, 5/2, 3/1, 4/1, 5/1

I can use variations_with_repetition from Algorithm::Combinatorics to generate all pairs of numbers taken from 1 up to the given number, filter them to keep only relative primes, i.e., pairs that have no common factor, and sort them as rationals (to compare the fractions a/b to c/d, compare the integers a*d to b*c). The result takes a 1.5-liner.

perl -MMath::Prime::Util=gcd -MAlgorithm::Combinatorics=variations_with_repetition -E '
for(@ARGV){say"$_->", map{" $_->[0]/$_->[1]"} sort{$a->[0]*$b->[1]<=>$a->[1]*$b->[0]}
grep{gcd(@$_)==1} variations_with_repetition [1..$_],2 ;
}
' 3 4 1 6 5

Results:

3-> 1/3 1/2 2/3 1/1 3/2 2/1 3/1
4-> 1/4 1/3 1/2 2/3 3/4 1/1 4/3 3/2 2/1 3/1 4/1
1-> 1/1
6-> 1/6 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 5/6 1/1 6/5 5/4 4/3 3/2 5/3 2/1 5/2 3/1 4/1 5/1 6/1
5-> 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1 5/4 4/3 3/2 5/3 2/1 5/2 3/1 4/1 5/1

The full code is almost identical:

 1  # Perl weekly challenge 357
 2  # Task 2:  Unique Fraction Generator
 3  #
 4  # See https://wlmb.github.io/2026/01/19/PWC357/#task-2-unique-fraction-generator
 5  use v5.36;
 6  use feature qw(try);
 7  use Math::Prime::Util qw(gcd);
 8  use Algorithm::Combinatorics qw(variations_with_repetition);
 9  use Text::Wrap;
10  $Text::Wrap::columns=60;
11  die <<~"FIN" unless @ARGV;
12      Usage: $0 N0 N1...
13      to sort and print all proper fractions than can be built
14      with the integers 1..Nn
15      FIN
16  for(@ARGV){
17      try{
18          die "Expected a positive integer: $_" unless /^\+?\d+$/;
19          say wrap("", "    ",
20                   "$_->",
21                   map{"$_->[0]/$_->[1]"}
22                   sort{$a->[0]*$b->[1]<=>$a->[1]*$b->[0]}
23                   grep{gcd(@$_)==1}
24                   variations_with_repetition [1..$_],2
25              );
26      }
27      catch($e){warn $e;}
28  }

Example:

./ch-2.pl 3 4 1 6 5

Results:

3-> 1/3 1/2 2/3 1/1 3/2 2/1 3/1
4-> 1/4 1/3 1/2 2/3 3/4 1/1 4/3 3/2 2/1 3/1 4/1
1-> 1/1
6-> 1/6 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 5/6 1/1 6/5 5/4
    4/3 3/2 5/3 2/1 5/2 3/1 4/1 5/1 6/1
5-> 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1 5/4 4/3 3/2 5/3
    2/1 5/2 3/1 4/1 5/1

/;

Written on January 19, 2026