Quick actions

cmd+k|ctrl+k

Navigation

Languages

Lab2 test

Snippet info

Language

Raku

Visibility

public

Author

lingbe

Created

2024-10-20T06:50:22.621305Z

Updated

2024-10-20T20:54:42.894881Z

# my @arr = ("abc", "def", "g");
# my $str = @arr.join("-");
# say $str;
# exit;

# my $counter = 0;
# repeat {
#     say "Counter is $counter";
#     $counter++;
# } until $counter >= 5;
# $counter = 0;
# repeat {
#     say "Counter is $counter";
#     $counter++;
# } while $counter < 5;
# exit;

# my $string = "This_is_a_test _string";
# if $string !~~ /<[\s\n]>+/ {
#     say "String does not contain any whitespace or newlines.";
# } else {
#     say "String contains whitespace or newlines.";
# }
# exit;
# my $string = "";#"   \n ";
# if $string !~~ /^ <[\s\n]>+ $/ {
#     say "String contains other characters.";
# } else {
#     say "String is only whitespace or newline.";
# }
# exit;
# my $string = "";
# # Using inequality check
# if $string ne "" {
#     say "String is not empty.";
# } else {
#     say "String is empty";
# }
# exit;

# my %val;
# say %val;
# %val{'test'} = 5;
# say %val;
# # %val := {}; # Bind %val to an empty object (https://docs.raku.org/routine/:=)
# %val = ();
# say %val;
# exit;

# say split(";", "a;b;c").raku;  
# say "abc.de".split(".").raku;   
# my %capitals = 'Spain' => {'Madrid' => 3}, 'United States' => {'Washington DC' => 4};
# my %cts;
# if (not %capitals{'Zimbabwe'}:exists) {
#     say "not exists";
#     %capitals{'Zimbabwe'} = 'Harare' => 5;
# } else {
#     say "exists";
# }

# if (not %capitals{'United States'}{'Sacramento'}:exists) {
#     say "not exists 2";
#     %capitals{'United States'}{'Sacramento'} = 8;
# } else {
#     say "exists 2";
# }
# %capitals{'United States'}{'Sacramento'} += 1;
# if (not %capitals{'United States'}{'Sacramento'}:exists) {
#     say "not exists 3";
#     %capitals{'United States'}{'Sacramento'} = 8;
# } else {
#     say "exists 3";
#     %capitals{'United States'}{'Sacramento'} += 1;
# }
# if (not %capitals{'Canada'}:exists) {
#     say "not exists 4";
#     %capitals{'Canada'} = {'Quebec' => 15};
# } elsif (not %capitals{'Canada'}{'Quebec'}:exists) {
#     say "not exists 5";
#     %capitals{'Canada'}{'Quebec'} = 15;
# } else {
#     say "exists 5";
#     %capitals{'Canada'}{'Quebec'} += 1;
# }
# if (not %capitals{'Canada'}:exists) {
#     say "not exists 4";
#     %capitals{'Canada'} = {'Quebec' => 15};
# } elsif (not %capitals{'Canada'}{'Quebec'}:exists) {
#     say "not exists 5";
#     %capitals{'Canada'}{'Quebec'} = 15;
# } else {
#     say "exists 5";
#     %capitals{'Canada'}{'Quebec'} += 1;
# }

# say %capitals{'Spain'};
# say %capitals{'Spain'}{'Madrid'};
# say %capitals{'United States'};
# say %capitals{'United States'}{'Washington DC'};
# say %capitals{'United States'}{'Sacramento'};
# say %capitals{'Zimbabwe'};
# say %capitals{'Zimbabwe'}{'Harare'};
# say %capitals;
# %capitals = %capitals.sort: *.kv.reverse;
# say %capitals;

# for %capitals.sort -> (:$key, :$value) {
#     say "Pair: $key:$value";
# }
# exit;

my $SEQUENCE_LENGTH = 10;	  # length of song title, suggested default 10
# hash of hashes for bigram counts
my %counts = ();
# hash of words already used in current sequence, reset for new sequence
my %word_history = ();

# build_bigram
# This splits the tracks into words and builds the bi-gram model
sub build_bigrams {
    my @tracks = (
        "foggy    mountain         breakdown",
        "all same blood",
        "when you're sick blues",
        "all sick mountain",
        "foggy  mess",
        "foggy",
        "mess all same buff",
        "man all same stuff",
        "all good",
        "all good dude",
        "dude all good",
        "i'm all sick",
        "all bad",
        "foggy mountain"
    );
    # foreach title in tracks array
    #   split title into individual words
    #     if there is more than one word
    #       while there are adjacent word pairs
    #         update count for word pair by 1
    #       end while
    #     end if
    # end foreach
    for @tracks -> $title {
        say $title;
        # Split title using one or more whitespaces as delimiter
        my @word_array = $title.split(/\s+/);
        say @word_array;
        say @word_array.raku;
        say @word_array.elems;
        if (@word_array.elems > 1) {
            say "more than 1 elems found."
        } else {
            say "1 or less elems found"
        }
        # Add each word pair to %counts hash map.
        # The last word is ignored since no words follow it.
        loop (my $i = 0; $i < @word_array.elems - 1; $i++) {
            say $i ~ ":" ~ @word_array[$i] ~ "," ~ @word_array[$i+1];
            if (not %counts{@word_array[$i]}:exists) { # Add new word pair for a new word key hash
                say "key1 not exists";
                %counts{@word_array[$i]} = {@word_array[$i+1] => 1};
            } elsif (not %counts{@word_array[$i]}{@word_array[$i+1]}:exists) { # Add new word pair to an existing word key
                say "key2 not exists" ~ ":" ~ %counts{@word_array[$i]};
                %counts{@word_array[$i]}{@word_array[$i+1]} = 1;
            } else { # Increment existing word pair
                say "both keys exist";
                %counts{@word_array[$i]}{@word_array[$i+1]} += 1;
            }
            say %counts;
        }
        
        say "\n";
    }
    say "FINAL";
    say %counts;
}
##############################################################################################################################
# mcw
# This finds the most-common-word (mcw) to follow the given word
sub mcw {
	# Seed word (arg) for which we find the next word
	my $word = @_[0];
	# Store the most common next word in this variable and return it.
	my $best_word = '';
	
	##########################
	# LAB 2 TASK 2: MCW
	##########################
	##
	## Find all available "next" words for $word
	## Sort them (there is a function for that)
	##   so your results are deterministic and match the tests
	##
	## Iterate through all the available words
	##   that follow $word in the %counts
	##
	## Remember to check the %word_history	
	##   and skip that word if used before
	##
	## Find the candidate word with highest count,
	##   update $best_word (it gets returned)
    ## 
	## In case of ties, stick with first one found
	##    (i.e. use strictly > in your count comparison if)
	##    that way you make the same choice the tests do
	##
	## This comment is longer than your code will be for this task. 
	##########################
	
	
	##########################
# 	my %word_pair_counts = %counts{$word};
    my $highest_count = 0;  # track highest pair count

    if (%counts{$word}:exists) {
        say "\%counts{$word}.sort:\n" ~ %counts{$word}.sort;
        # Check each word pair in key-sorted order
        for %counts{$word}.sort -> (:$key, :$value) {
            say "Pair: $key:$value";
            # Update best_word if current count is greater than highest_count
            # and only if current word is not already in word_history
            if ($value > $highest_count && not %word_history{$key}:exists) {
                $highest_count = $value;
                $best_word = $key;
            }
        }
    }
	##########################


	########################## End Task MCW
	

# 	if ($DEBUG) {say "  <mcw for \'$word\' is \'$best_word'\>\n";}
	
	# return the most common word to follow word
	return $best_word
}

##############################################################################################################################
# sequence
# This builds a song title based on mcw
sub sequence {
# 	if ($DEBUG) {say "<sequence for \'@_[0]\'>\n";}
	
	# clear word history for new sequence
	%word_history = ();
		
	##########################
	# LAB 2 TASK 3: Build Song Title
	##########################
	## Use the seed word to build a sequence.
	## For each word, look up the mcw
	## Add to sequence.
	## Repeat until next word is empty or newline
	## Mind the max $SEQUENCE_LENGTH
	## Remember to track word history using %word_history
	## My solution is about 12 lines (and could have been less)
	##########################
	
	
	##########################
	my $word = @_[0];   # Seed word (arg) for building a sequence
	say "word:" ~ $word;
	my $seq_length = 0; # track current sequent length
	my @seq;    # contains the sequence of words for output
	
	# Push current word to sequence, add to word history, update sequence length, and fetch next word from mcw.
	# Stop when next word is empty string, only whitespace/newline, or when maximum sequence length has been reached.
	repeat {
	    @seq.push: $word;
	    %word_history{$word} = 1;
	    $seq_length++;
	    $word = mcw($word);
	    say "next word:" ~ $word;
	} while ($word ne "" && $word !~~ /^ <[\s\n]>+ $/ && $seq_length < $SEQUENCE_LENGTH);
	##########################


		
	# return the sequence you created instead of this measely string
# 	return "ERROR: SEQUENCE 404";
    say @seq;
    return @seq.join(" ");  # Join the sequence words together separated by a space.
	########################## End Task Song Title
}

build_bigrams();
%word_history{'good'} = 1;
# %word_history{'same'} = 1;
# %word_history{'sick'} = 1;
# %word_history{'bad'} = 1;
say mcw("all");
say sequence("foggy");
say "\n";
say sequence("all")
INFO