5
\$\begingroup\$

Given a string, find the first non-repeated character in it.

E.g. "yellow" should return "y"

There are several solutions for this in other languages but I haven't seen one written in Perl.

My main question is: can this be done in a more Perl-ish way or generally in an even shorter way?

use strict;
use warnings "all";

while (<DATA>)
{
    while (m,(.),g)
    {
        my $c = $1;
        if (s,$1,,g < 2)
        {
            print "$c\n";
            last;
        }
    }
}

__DATA__
yellow
tooth
\$\endgroup\$
  • \$\begingroup\$ What should be output for string aaabbc? \$\endgroup\$ – Tushar May 24 '17 at 10:08
  • 1
    \$\begingroup\$ @Tushar the output would be "c". \$\endgroup\$ – yuri May 24 '17 at 10:33
  • \$\begingroup\$ One way is to replace all repeating characters using regex (.)\1* and get the first character of the resulting string. \$\endgroup\$ – Tushar May 24 '17 at 11:01
  • 1
    \$\begingroup\$ @yuri: \1 must be used in the regex part, but in the replacement part you have to use $1. \$\endgroup\$ – Toto May 25 '17 at 9:58
  • 1
    \$\begingroup\$ perl -E '$_ = "aabbbcd"; s/(.)\1+//g; /(.)/ && say $1' \$\endgroup\$ – Håkon Hægland May 25 '17 at 11:11
2
\$\begingroup\$

Don't reinvent the wheel, there is a function (ie. singleton) in the package MoreUtils that does the job:

#!/usr/bin/perl
use Modern::Perl;
use List::MoreUtils qw(singleton);

while (<DATA>) {
    chomp;    # don't forget it, it removes the linebreak.
    # split explodes the string in character
    # singleton keeps characters that appear only once
    # ($first) contains the first character that appears only once.
    my ($first) = singleton split//, $_;
    say $first;
}

__DATA__
yellow
tooth

Output:

y
h
\$\endgroup\$
  • \$\begingroup\$ This is a nice solution but what if you work in an environment where you can't install extra dependencies? \$\endgroup\$ – yuri May 24 '17 at 10:31
  • 1
    \$\begingroup\$ @yuri: Inspect the module and copy the code of the function. \$\endgroup\$ – Toto May 24 '17 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.