I’ve been doing the Weekly
Challenges. The
latest
involved string splitting and data sorting. (Note that this is open
until 11 September 2022.)
Task 1: Sentence Order
You are given a paragraph.
Write a script to order each sentence alphanumerically and print the
whole paragraph.
I felt a strong lack of enthusiasm about this one – there's a certain
amount of "why would anyone ever want to do this" – but I wrote it in
Perl and Raku anyway. It ended up falling into multiple stages:
wrapping the paragraph into a single string, splitting sentences,
splitting words (and stripping punctuation at ends of words but not in
mid-word), sorting, composing the output and then wrapping it.
Perl:
saywrap(reorder("
All he could think about was how it would all end. There was
still a bit of uncertainty in the equation, but the basics
were there for anyone to see. No matter how much he tried to
see the positive, it wasn't anywhere to be seen. The end was
coming and it wasn't going to be pretty.
"));
sub reorder($para0) {
Trim leading and trailing spaces.
(my $para = $para0) =~ s/^\s*(.*?)\s*$/$1/;
Make single line.
$para =~ s/\n/ /g;
Remove any multiple spaces
$para =~ s/\s{2,}/ /g;
my @o;
Split sentences by terminal . ! ?
foreach my $s0 (split /[.?!] /, $para) {
if ($s0) {
my $s = $s0;
Remove trailing punctuation.
$s =~ s/[^a-z]\s/ /gi;
And . at end of sentence.
$s =~ s/\.$//g;
Trim leading/trailing spaces.
$s =~ s/^\s*(.*?)\s*$/$1/;
Compress multiple spaces.
$s =~ s/\s{2,}/ /g;
Split and sort.
my @w = sort {lc($a) cmp lc($b)} split ' ',$s;
Reassemble.
push @o,join(' ',@w) . '.';
}
}
return join(' ',@o);
}
For the wrapper I'd normally use Text::Wrap
but I had to write the
algorithm anyway for the Raku version. Basically, scan backwards from
the line length looking for a space.
sub saywrap($p0) {
my $p = $p0;
my $ll = 72;
while (length($p) >= $ll) {
my $c = $ll;
while ($c > 0) {
if (substr($p, $c, 1) eq ' ') {
print substr($p, 0, $c),"\n";
$p = substr($p, $c+1);
$c = -1;
last;
}
$c--;
}
if ($c == 0) {
print substr($p, 0, $ll-1),"-\n";
$p = substr($p, $ll);
}
}
if (length($p) > 0) {
print $p,"\n";
}
}
Task 2: Hot Day
You are given file with daily temperature record in random order.
Write a script to find out days hotter than previous day.
Most languages make some sort of CSV parser available which I'd use
for a real problem. But basically this is a matter of sorting items
into order, then processing the series.
Python:
t = dict()
Read the file, store a hash of (date-string, temperature)
fh = open('temperature.txt','r')
for ll in fh:
line = ll.rstrip()
l = line.split(",")
t[l[0].strip()] = int(l[1].strip())
Then go through the sorted date-strings and print the ones for which
temperature is higher than the previous entry.
lt = 999
for k in sorted(t.keys()):
if t[k] > lt:
print(k)
lt = t[k]
Full code on
github.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.