ninjo
ninjo

Reputation: 21

Occurrence in two array

If i have

@array1 =(c,a,d,f,t,e,w,e,f,i,s,b,h);

and

@array2 = (king,blue,beach,sky);

how can I check if every word of array2 is valid (is valid when all the letters are in @array1, using only once for each letter of @array1) ?

Upvotes: 0

Views: 78

Answers (4)

ysth
ysth

Reputation: 98388

use strict;
use warnings;

my @array1 = qw/c a d f t e w e f i s b h/;
my @array2 = qw/king blue beach sky/;

my $check_word = join '', map "\Q$_\E?", sort @array1;
$check_word = qr/\A(?:$check_word)\z/;

print "checking words with regex: ", $check_word, "\n";

for my $word (@array2) {
    my $dorw = join '', sort split //, $word;
    print "checking $word, transformed to $dorw\n";
    if ( $dorw =~ $check_word ) {
        print "$word is ok\n";
    }
    else {
        print "$word is not ok\n";
    }
}

Upvotes: 2

DavidRR
DavidRR

Reputation: 19397

Here's an approach that uses a pair of hashes.

#!/usr/bin/env perl

use strict;
use warnings;

my @array1 = qw(c a d f t e w e f i s b);
my @array2 = qw(cat catt few king blue beach sky);

# Build a hash of unique letters in @array1.
my %letters1 = map {$_ => 1} @array1;

my %letters2;
foreach (@array2) {
    # Build a hash of unique letters of a word in @array2.
    %letters2 = map { $_ => 1 } split //;

    my $status = "OK";

    if (scalar keys %letters2 == length($_)) {
        # No duplicate letters in the word.
        foreach (keys %letters2) {
            $status = "Not OK" if (!exists $letters1{$_});
        }
    } else {
        $status = "Not OK";
    }

    print "$_ => $status\n";
}

Expected Output:

cat => OK
catt => Not OK
few => OK
king => Not OK
blue => Not OK
beach => Not OK
sky => Not OK

Upvotes: 0

Tim Pierce
Tim Pierce

Reputation: 5664

I'd approach this by using the elements in @array1 to build a regular expression:

$regex = '^[' . join('', @array1) . ']+$'

will generate this regex from your @array1:

^[cadftewefisb]+$

Then match each element of @array2 against this regex:

for (@array2) {
    print if /$regex/;
}

EDIT: I wrote this before the question was edited to clarify that each letter in @array1 may be used only as many times as they appear, i.e. if t appears only once in @array1 then a word in @array2 may use only one t. This answer doesn't satisfy that condition.

Upvotes: 2

ikegami
ikegami

Reputation: 385556

This shows the elements of @array2 that are composed from an arrangement of the letters in @array1.

my $array1 = join '', sort @array1;

for (@array2) {
   my $pat = join '.*', map quotemeta, sort split //;
   my $re = qr/^.*$pat.*\z/s;
   say if $array1 =~ /$re/;
}

Tested with:

use strict;
use warnings;
use feature qw( say );

my @array1 = qw( c a d f t e w e f i s b h );
my @array2 = qw( king blue beach sky );

Upvotes: 2

Related Questions