Y Translate? The weekly challenge 329 task 1

Task 1: Counter Integers:

You are given a string containing only lower case English letters and digits.

 
Write a script to replace every non-digit character with a space and then return all the distinct integers left.

The first part is easy. In Python:[1]

new_string = string.translate({ c:' ' for c in range(ord('a'),ord('z')+1) })

In Perl:[2]

my $new_string = $string =~ y/a-z/ /r;

And the second part is...also easy. In Python:

unique_integers = sorted(set(new_string.split()))

In Perl:[3]

my @unique_integers = List::Util::uniq split ' ', $new_string;

The problem with that is our task is to return distinct integers, and this gets strings, and will return e.g. both 01 and 1. We could just convert to int after splitting and before deduping, but I'd rather more explicitly deal with extra leading 0's by using a regex instead of split:

unique_integers = [int(i) for i in sorted(set(re.findall(r'0*(\d+)', string)))]

my @unique_integers = map int, List::Util::uniq $string =~ /0*(\d+)/g;

But now the translate step, explicitly called for in the problem, isn't actually necessary at all.

full script, Python
full script, Perl

On to task 2...


  1. Not EBCDIC-friendly, since that has non-letters amongst the letters. There (assuming the possibly mythical python 3 on an EBCDIC system doesn't just use utf8 internally and only translate to EBCDIC for I/O), do:

    string.translate(str.maketrans('abcdefghijklmnopqrstuvwxyz',' '*26))
    
    ↩︎
  2. Perl's translate operator (confusingly called the transliteration operator) can be used either as y (as in sed) or tr (from tr). ↩︎

  3. Perl's split ' ' is a special form that splits on whitespace (\s+) but also ignores leading whitespace, just like Python's split() with no argument does, and shouldn't be confused with split / /, which splits on every space character. ↩︎