Find the frequency of triplets in a phrase
Perl 6, 67 57 bytes
*.words.map({[~] .lc.comb(/\w/)}).rotor(3=>-2)».join(' ').Bag.perl
Try it
*.words.rotor(3=>-2).map({lc S:g/<-:L-:N-:Z>//}).Bag.perl
Try it
Expanded:
*\ # WhateverCode lambda (this is the parameter)
.words # get a list of words
.rotor( 3 => -2 ) # grab 3, back up 2, repeat
.map({ # take those list of 3 elements
lc # lower case the following
S # remove
:global # globally
/
<- :L # not a letter
- :N # not a number
- :Z # not a space (inserted when the current list is stringified)
>
//
})
.Bag # turn it into a Bag
.perl # return the structure as an `EVAL`able Str
returns something like
("bb a cc"=>1,"aa bb a"=>1,"a cc a"=>1,"a bb a"=>3,"bb a bb"=>2,"cc a bb"=>1).Bag
Retina, 50 bytes
T`lLd p`lld _
M!&`(\b\w+ ??){3}
O`
$
¶
D`
¶+
:$.&¶
Try it online!
Explanation
T`lLd p`lld _
Replace all uppercase letters with lowercase ones, keep other letters, digits and spaces unchanged and delete other characters.
M!&`(\b\w+ ??){3}
Find all possible matches of three words in a row.
O`
Sort the matches, so equal triplets end next to each other.
$
¶
Add a newline at the end.
D`
Remove duplicate lines (this will keep the newlines at the end of them).
¶+
:$.&¶
Sequences of newlines are now the counts we need, replace them with a delimiter (:
) followed by the count and a newline.
Jelly, 18 13 bytes
ŒlḲf€ØBṡ3ṢŒr'
A monadic link (function) that returns a list, each entry contains a list of 3 lists of characters (the words) and a count.
Try it online! - the footer formats the results (as a full program everything just gets smushed together by the implicit print).
How?
ŒlḲf€ØBṡ3ṢŒr' - Main link: s
Œl - convert s to lowercase
Ḳ - split on spaces
ØB - base digit yield "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
f€ - filter keep for €ach
ṡ3 - all overlapping slices of length 3
Ṣ - sort
' - call the previous monadic link without vectorising
Œr - run length encode