http://qs321.pair.com?node_id=11145745


in reply to Challenge: sort weekdays in week-order (elegantly and efficiently)

G'day bliako,

Here's another way: enum for the order; and, an Orcish Manoeuvre for efficiency.

#!/usr/bin/env perl use 5.010; use strict; use warnings; use enum qw{sun mon tue wed thu fri sat}; say '*** Check Orcish Manoeuvre is working ***'; say _canon_day_test($_) for qw{Mon mon Monday monday} x2; say '*** Your sort example ***'; my @weekdays = qw/Monday Saturday Thursday/; say for sort { _canon_day($a) <=> _canon_day($b) } @weekdays; say '*** More complex example ***'; my @many_form_weekdays = qw{ thurs tue Thu Tues Thursday tuesday Fri Sun sat Fri Sun sat SATURDAY FRIDAY SUNDAY Wednesday Mon wed monday sun Sat friday Friday Sunday }; say for sort { _canon_day($a) <=> _canon_day($b) } @many_form_weekdays +; sub _canon_day { my ($day) = @_; state $day_for = {}; return $day_for->{$day} ||= eval lc substr $day, 0, 3; } sub _canon_day_test { my ($day) = @_; state $day_for = {}; say "'$day' needs Orc" unless exists $day_for->{$day}; return $day_for->{$day} ||= eval lc substr $day, 0, 3; }

_canon_day_test() is identical to _canon_day() except for the say statement: it's just for testing.

You may want to add some validation code, but that wasn't part of your question.

Output:

*** Check Orcish Manoeuvre is working *** 'Mon' needs Orc 1 'mon' needs Orc 1 'Monday' needs Orc 1 'monday' needs Orc 1 1 1 1 1 *** Your sort example *** Monday Thursday Saturday *** More complex example *** Sun Sun SUNDAY sun Sunday Mon monday tue Tues tuesday Wednesday wed thurs Thu Thursday Fri Fri FRIDAY friday Friday sat sat SATURDAY Sat

— Ken

Replies are listed 'Best First'.
Re^2: Challenge: sort weekdays in week-order (elegantly and efficiently)
by LanX (Saint) on Jul 26, 2022 at 16:06 UTC
    I have trouble finding a canonical explanation of Orcish Manoeuvre, but isn't Memoize faster in this case?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      G'day Rolf,

      "I have trouble finding a canonical explanation of Orcish Manoeuvre, ..."

      "A Fresh Look at Efficient Perl Sorting" describes many sorting techniques. The section on OM points to a footnote with details of a book by the inventor of this algorithm. I don't own, nor have I read, this book, so I can't comment further.

      "... but isn't Memoize faster in this case?"

      Try Benchmark to answer that. Please post your results: I, and no doubt others, would be interested.

      — Ken

        Thanks.

        From my perspective: "Orcish" is just the inner workings of a sort based on a key-function, like in Sort::Key °

        AFAIK is sorting by key functions the default in Python.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        °) Tho Salva wasn't explict if the result of a key-function is cached in his implementation.

      OM is basically ST, but where the sort is provided the default comparison function ($a cmp $b).

      Technically, any of the four builtin compare functions would work equally fast.

      • $a cmp $b
      • $b cmp $a
      • $a <=> $b
      • $b <=> $a