user
Definition

For the purposes of this task, a **qualifying number** is a non-negative integer, k, whose last letter is the same as the first letter of k+1 when written in English.

For example, 18 (i.e 'eighteen' in English) is a qualifying number because its last letter 'n' is the same as the first letter of 'nineteen'.

Take the English equivalent of 0 to be 'zero' and not 'nought' or similar words.

For numbers such as 100 or 1000, the equivalent English should be taken as 'one hundred' or 'one thousand' and not 'a hundred' or 'a thousand'.

Task

1. Find and show here the first 50 qualifying numbers.

2. What are the 1,000th and 10,000th qualifying numbers?

3. For the first 1,000 and 10,000 qualifying numbers, show their breakdown by final digit. This can be shown numerically, graphically or both.

If it is difficult for your language to meet all of these requirements, then just do what you reasonably can.

Stretch

4. What are the 100,000th and millionth qualifying numbers?

5. For the first 100,000 and million qualifying numbers, show their breakdown by final digit.

References

* OEIS sequence A363659:Numbers k such that the last letter of k is the same as the first letter of k+1 when written in English.

* GCHQ, The GCHQ Puzzle Book, Penguin, 2016. See Puzzle 31, page 37 (referred to in OEIS link).

* Number names
assistant
**Translation of**: Wren

```
# 20230713 Raku programming solution

###### https://rosettacode.org/wiki/Number_names#Raku

constant @I = <zero one    two    three    four     five    six     seven     eight    nine
               ten  eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen>;
constant @X = <0    X      twenty thirty   forty    fifty   sixty   seventy   eighty   ninety>;
constant @C = @I X~ ' hundred';
constant @M = (<0 thousand>,
    ((<m b tr quadr quint sext sept oct non>,
    (map { ('', <un duo tre quattuor quin sex septen octo novem>).flat X~ $_ },
    <dec vigint trigint quadragint quinquagint sexagint septuagint octogint nonagint>),
    'cent').flat X~ 'illion')).flat;

sub int-name ($num) {
    if $num.substr(0,1) eq '-' { return "negative {int-name($num.substr(1))}" }
    if $num eq '0' { return @I[0] }
    my $m = 0;
    return join ', ', reverse gather for $num.flip.comb(/\d ** 1..3/) {
        my ($i,$x,$c) = .comb».Int;
        if $i or $x or $c {
            take join ' ', gather {
                if $c { take @C[$c] }
                if $x and $x == 1 { take @I[$i+10] }
                else {
                    if $x { take @X[$x] }
                    if $i { take @I[$i] }
                }
                take @M[$m] // die "WOW! ZILLIONS!\n" if $m;
            }
        }
        $m++;
    }
}
######

my ($i, $c, $limit, $prev, @nums, @lastDigs) = 0, 0, 1000, int-name(0);

while $limit <= 1e4 {
   my $next = int-name $i+1;
   if $prev.substr(*-1) eq $next.substr(0,1) {
      if ($c < 50) { @nums.append: $i };
      @lastDigs[$i % 10] += 1;
      $c++;
      if $c == 50 {
         say "First 50 numbers:";
         say [~] $_>>.fmt('%4s') for @nums.rotor(10);
         say(); 
      } elsif $c == $limit {
         print "The {$c}th number is $i.\n";
         say "Breakdown by last digit of first {$c}th numbers";
         say 'N Freq';
         for 0..9 -> $d { 
            say "$d {@lastDigs[$d].fmt('%4s')} ",
                '█' x (@lastDigs[$d]/@lastDigs.max*72).Int;
         }
         say(); 
         $limit *= 10
      }
   }
   $prev = $next;
   $i++;
}

```

You may Attempt This Online!