diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2022-04-24 18:22:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-24 18:22:28 +0100 |
| commit | 95b41dbae269fa2736df0761c9e0e17e69f6fd82 (patch) | |
| tree | cf9c1b238de5d70e2301ab37825b6378e36ebe4c | |
| parent | 8bb4823ba25f879db43b583660c1d1c9d8d1adb3 (diff) | |
| parent | ed64563fefab6990e1b720be5532d8262df80bd1 (diff) | |
| download | perlweeklychallenge-club-95b41dbae269fa2736df0761c9e0e17e69f6fd82.tar.gz perlweeklychallenge-club-95b41dbae269fa2736df0761c9e0e17e69f6fd82.tar.bz2 perlweeklychallenge-club-95b41dbae269fa2736df0761c9e0e17e69f6fd82.zip | |
Merge pull request #5990 from PerlMonk-Athanasius/branch-for-challenge-161
Perl & Raku solutions to Tasks 1 & 2, plus blog for Task 2, for Week 161
| -rw-r--r-- | challenge-161/athanasius/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-161/athanasius/perl/ch-1.pl | 100 | ||||
| -rw-r--r-- | challenge-161/athanasius/perl/ch-2.pl | 247 | ||||
| -rw-r--r-- | challenge-161/athanasius/perl/dictionary.txt | 39172 | ||||
| -rw-r--r-- | challenge-161/athanasius/raku/ch-1.raku | 94 | ||||
| -rw-r--r-- | challenge-161/athanasius/raku/ch-2.raku | 232 | ||||
| -rw-r--r-- | challenge-161/athanasius/raku/dictionary.txt | 39172 |
7 files changed, 79018 insertions, 0 deletions
diff --git a/challenge-161/athanasius/blog.txt b/challenge-161/athanasius/blog.txt new file mode 100644 index 0000000000..a29e0377c7 --- /dev/null +++ b/challenge-161/athanasius/blog.txt @@ -0,0 +1 @@ +https://www.perlmonks.com/index.pl?node_id=11143246 diff --git a/challenge-161/athanasius/perl/ch-1.pl b/challenge-161/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..f70f08c6c3 --- /dev/null +++ b/challenge-161/athanasius/perl/ch-1.pl @@ -0,0 +1,100 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 161 +========================= + +TASK #1 +------- +*Abecedarian Words* + +Submitted by: Ryan J Thompson + +An abecedarian word is a word whose letters are arranged in alphabetical order. +For example, "knotty" is an abecedarian word, but "knots" is not. Output or +return a list of all abecedarian words in the [ https://github.com/manwar/ +perlweeklychallenge-club/blob/master/data/dictionary.txt |dictionary], sorted +in decreasing order of length. + +Optionally, using only abecedarian words, leave a short comment in your code to +make your reviewer smile. + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=comment + +Abecedarian comment +------------------- +An abbot in an abbey abhors a bossy boor. + +=cut +#============================================================================== + +use strict; +use warnings; +use autodie; +use Const::Fast; + +const my $COMMENT => 'An abbot in an abbey abhors a bossy boor.'; +const my $DICTIONARY => 'dictionary.txt'; +const my $USAGE => "Usage:\n perl $0\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 161, Task #1: Abecedarian Words (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my $args = scalar @ARGV; + $args and die "ERROR: Expected 0 command line arguments, found $args" . + "\n$USAGE"; + + my @abecedarians; + + open my $fh, '<', $DICTIONARY; + + while (my $line = <$fh>) + { + chomp $line; + push @abecedarians, $line if is_abecedarian( $line ); + } + + close $fh; + + @abecedarians = sort { length $b <=> length $a } @abecedarians; + + printf "The %d abecedarian words in %s, sorted from longest to shortest:" . + "\n\n%s\n\n%s\n", scalar @abecedarians, $DICTIONARY, + join( "\t", @abecedarians ), $COMMENT; +} + +#------------------------------------------------------------------------------ +sub is_abecedarian +#------------------------------------------------------------------------------ +{ + my ($word) = @_; + my @letters = split '', $word; + + for my $i (1 .. $#letters) + { + return 0 if $letters[ $i ] lt $letters[ $i - 1 ]; + } + + return 1; +} + +############################################################################### diff --git a/challenge-161/athanasius/perl/ch-2.pl b/challenge-161/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..53b3d3ebdd --- /dev/null +++ b/challenge-161/athanasius/perl/ch-2.pl @@ -0,0 +1,247 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 161 +========================= + +TASK #2 +------- +*Pangrams* + +Submitted by: Ryan J Thompson + +A pangram is a sentence or phrase that uses every letter in the English +alphabet at least once. For example, perhaps the most well known pangram is: + + the quick brown fox jumps over the lazy dog + +Using the provided [ https://github.com/manwar/perlweeklychallenge-club/ +blob/master/data/dictionary.txt |dictionary], so that you don't need to include +individual copy, generate at least one pangram. + +Your pangram does not have to be a syntactically valid English sentence (doing +so would require far more work, and a dictionary of nouns, verbs, adjectives, +adverbs, and conjunctions). Also note that repeated letters, and even repeated +words, are permitted. + +BONUS: Constrain or optimize for something interesting (completely up to you), +such as: + + Shortest possible pangram (difficult) + Pangram which contains only abecedarian words (see challenge 1) + Pangram such that each word "solves" exactly one new letter. For example, + such a pangram might begin with (newly solved letters in bold): + a ah hi hid die ice tea ... + What is the longest possible pangram generated with this method? (All + solutions will contain 26 words, so focus on the letter count.) + Pangrams that have the weirdest (PG-13) Google image search results + Anything interesting goes! + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=comment + +Bonus Constraint +---------------- +Approximation to the shortest possible pangram using a version of the greedy +algorithm. See my blog at https://www.perlmonks.com/index.pl?node_id=11143246 + +=cut +#============================================================================== + +use strict; +use warnings; +use autodie; +use feature qw( state ); +use Const::Fast; +use Set::Tiny; +use constant TIMER => 1; +use constant VERBOSE => 1; + +const my %ALPHABET => + ( + a => 1, b => 3, c => 3, d => 2, e => 1, + f => 4, g => 2, h => 4, i => 1, j => 8, + k => 5, l => 1, m => 3, n => 1, o => 1, + p => 3, q => 10, r => 1, s => 1, t => 1, + u => 1, v => 4, w => 4, x => 8, y => 4, z => 10 + ); +const my $DUP_WEIGHT => 4; +const my $DICTIONARY => 'dictionary.txt'; +const my $USAGE => "Usage:\n raku ch-2.raku\n"; + +#------------------------------------------------------------------------------ +# Lexical variable with file scope +#------------------------------------------------------------------------------ + +my %Word2letters; # Each hash entry has the form: + # word => [ set-of-unused-letters-in-that-word, weight ] + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 161, Task #2: Pangrams (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + use if TIMER, 'Time::HiRes' => qw( gettimeofday tv_interval ); + + my $t0 = [ gettimeofday ] if TIMER; + my $args = scalar @ARGV; + $args and die "ERROR: Expected 0 command line arguments, found $args" . + "\n$USAGE"; + + read_words( $DICTIONARY ); # Words are read from the dictionary file, fil- + # tered, weighted, then stored in %Word2letters + my @pangram; + my $letter_count = 0; + + while ($letter_count < scalar keys %ALPHABET) + { + my ($new_word, $new_letters) = get_next_word(); + + push @pangram, $new_word; + + $letter_count += record_new_letters( $new_letters ); + } + + my $length = 0; + $length += length $_ for @pangram; + + printf "%sPangram of %d letters using words drawn from %s:\n\n %s\n", + VERBOSE ? "\n" : '', $length, $DICTIONARY, join ' ', @pangram; + + printf "\n%.2f seconds\n", tv_interval( $t0 ), if TIMER; +} + +#------------------------------------------------------------------------------ +sub read_words +#------------------------------------------------------------------------------ +{ + my ($file) = @_; + my %words; + + open my $fh, '<', $file; + + while (my $word = <$fh>) + { + chomp $word; + + my $set = Set::Tiny->new( split '', $word ); + my $key = join '', sort $set->elements; + + push @{ $words{ $key } }, $word; + } + + close $fh; + + # Where words share the same set of letters, keep only the shortest word. + # E.g., "abdicate", "diabetic", and "abdicated" all have the letter set (a, + # b, c, d, e, i, t), so "abdicate" is retained but "diabetic" and "abdicat- + # ed" are filtered out. This reduces the dictionary size from 39,172 to + # 23,610 -- a saving of 15,562 words! + + for my $key (keys %words) + { + my $word = (sort { length $a <=> length $b } @{ $words{ $key } })[ 0 ]; + my $set = Set::Tiny->new( split '', $word ); + + my $weight = 0; + $weight += $ALPHABET{ $_ } for $set->elements; + + $Word2letters{ $word } = [ $set, $weight ]; + } +} + +#------------------------------------------------------------------------------ +sub get_next_word +#------------------------------------------------------------------------------ +{ + state $word_count = 0 if VERBOSE; + my @sorted = sort by_size keys %Word2letters; + scalar @sorted or die 'No words left, stopped'; + + my $best_word = $sorted[ 0 ]; + + $Word2letters{ $best_word }[ 0 ]->is_empty + and die 'The best word has no new letters, stopped'; + + my $best_letters = $Word2letters{ $best_word }[ 0 ]; + state $width = length( $best_word ) + 1 if VERBOSE; + + printf "(%d) %-*s", ++$word_count, $width, "$best_word:" if VERBOSE; + + delete $Word2letters{ $best_word }; + + for my $word (keys %Word2letters) + { + my $letters = $Word2letters{ $word }[ 0 ]->difference( $best_letters ); + my $weight = 0; + $weight += $ALPHABET{ $_ } for $letters->elements; + + for (split '', $word) + { + $weight -= $DUP_WEIGHT unless $letters->contains( $_ ); + } + + $Word2letters{ $word } = [ $letters, $weight ]; + } + + return ($best_word, $best_letters); +} + +#------------------------------------------------------------------------------ +sub by_size +#------------------------------------------------------------------------------ +{ + # - First, prefer words with the greatest weight; + # - then prefer words with the greatest number of unused letters; + # - then prefer shorter words; + # - then sort alphabetically (ascending) + + return $Word2letters{ $b }[ 1 ] <=> $Word2letters{ $a }[ 1 ] + || + $Word2letters{ $b }[ 0 ]->size <=> $Word2letters{ $a }[ 0 ]->size + || + length $a <=> length $b + || + $a cmp $b; +} + +#------------------------------------------------------------------------------ +sub record_new_letters +#------------------------------------------------------------------------------ +{ + state %letters = map { $_ => 0 } keys %ALPHABET; + my ($best_letters) = @_; + my $count = 0; + + for my $letter (sort $best_letters->elements) + { + if ($letters{ $letter } == 0) + { + $letters{ $letter } = 1; + ++$count; + print " $letter" if VERBOSE; + } + } + + print "\n" if VERBOSE; + + return $count; +} + +############################################################################### diff --git a/challenge-161/athanasius/perl/dictionary.txt b/challenge-161/athanasius/perl/dictionary.txt new file mode 100644 index 0000000000..1f915f2975 --- /dev/null +++ b/challenge-161/athanasius/perl/dictionary.txt @@ -0,0 +1,39172 @@ +a +aardvark +aback +abacus +abacuses +abandon +abandoned +abandoning +abandonment +abandons +abate +abated +abates +abating +abbey +abbeys +abbot +abbots +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +abdicate +abdicated +abdicates +abdicating +abdication +abdications +abdomen +abdomens +abdominal +abduct +abducted +abducting +abducts +aberration +aberrations +abet +abets +abetted +abetting +abhor +abhorred +abhorrence +abhorrent +abhorring +abhors +abide +abides +abiding +abilities +ability +abject +ablaze +able +abler +ablest +ably +abnormal +abnormalities +abnormality +abnormally +aboard +abode +abodes +abolish +abolished +abolishes +abolishing +abolition +abominable +abomination +aboriginal +aborigine +aborigines +abort +aborted +aborting +abortion +abortions +abortive +aborts +abound +abounded +abounding +abounds +about +above +aboveboard +abrasive +abrasives +abreast +abridge +abridged +abridges +abridging +abroad +abrupt +abrupter +abruptest +abruptly +abscess +abscessed +abscesses +abscessing +abscond +absconded +absconding +absconds +absence +absences +absent +absented +absentee +absentees +absenting +absents +absolute +absolutely +absolutes +absolutest +absolve +absolved +absolves +absolving +absorb +absorbed +absorbent +absorbents +absorbing +absorbs +absorption +abstain +abstained +abstaining +abstains +abstention +abstentions +abstinence +abstract +abstracted +abstracting +abstraction +abstractions +abstracts +abstruse +absurd +absurder +absurdest +absurdities +absurdity +absurdly +abundance +abundances +abundant +abundantly +abuse +abused +abuser +abusers +abuses +abusing +abusive +abysmal +abyss +abysses +academic +academically +academics +academies +academy +accede +acceded +accedes +acceding +accelerate +accelerated +accelerates +accelerating +acceleration +accelerations +accelerator +accelerators +accent +accented +accenting +accents +accentuate +accentuated +accentuates +accentuating +accept +acceptability +acceptable +acceptably +acceptance +acceptances +accepted +accepting +accepts +access +accessed +accesses +accessibility +accessible +accessing +accessories +accessory +accident +accidental +accidentally +accidentals +accidents +acclaim +acclaimed +acclaiming +acclaims +acclimate +acclimated +acclimates +acclimating +acclimatize +acclimatized +acclimatizes +acclimatizing +accolade +accolades +accommodate +accommodated +accommodates +accommodating +accommodation +accommodations +accompanied +accompanies +accompaniment +accompaniments +accompanist +accompanists +accompany +accompanying +accomplice +accomplices +accomplish +accomplished +accomplishes +accomplishing +accomplishment +accomplishments +accord +accordance +accorded +according +accordingly +accordion +accordions +accords +accost +accosted +accosting +accosts +account +accountability +accountable +accountancy +accountant +accountants +accounted +accounting +accounts +accredit +accredited +accrediting +accredits +accrue +accrued +accrues +accruing +accumulate +accumulated +accumulates +accumulating +accumulation +accumulations +accuracy +accurate +accurately +accusation +accusations +accuse +accused +accuser +accusers +accuses +accusing +accustom +accustomed +accustoming +accustoms +ace +aced +aces +ache +ached +aches +achievable +achieve +achieved +achievement +achievements +achieves +achieving +aching +acid +acidity +acids +acing +acknowledge +acknowledged +acknowledges +acknowledging +acknowledgment +acknowledgments +acne +acorn +acorns +acoustic +acoustics +acquaint +acquaintance +acquaintances +acquainted +acquainting +acquaints +acquiesce +acquiesced +acquiescence +acquiesces +acquiescing +acquire +acquired +acquires +acquiring +acquisition +acquisitions +acquit +acquits +acquittal +acquittals +acquitted +acquitting +acre +acreage +acreages +acres +acrid +acrider +acridest +acrimonious +acrimony +acrobat +acrobatic +acrobatics +acrobats +acronym +acronyms +across +acrylic +acrylics +act +acted +acting +action +actions +activate +activated +activates +activating +active +actively +actives +activist +activists +activities +activity +actor +actors +actress +actresses +acts +actual +actualities +actuality +actually +actuary +acumen +acupuncture +acute +acutely +acuter +acutes +acutest +ad +adage +adages +adamant +adapt +adaptable +adaptation +adaptations +adapted +adapter +adapting +adaptive +adapts +add +added +addendum +addict +addicted +addicting +addiction +addictions +addictive +addicts +adding +addition +additional +additionally +additions +additive +additives +address +addressed +addressee +addressees +addresses +addressing +adds +adept +adepts +adequate +adequately +adhere +adhered +adherence +adherent +adherents +adheres +adhering +adhesion +adhesive +adhesives +adjacent +adjective +adjectives +adjoin +adjoined +adjoining +adjoins +adjourn +adjourned +adjourning +adjournment +adjournments +adjourns +adjunct +adjuncts +adjust +adjustable +adjusted +adjusting +adjustment +adjustments +adjusts +administer +administered +administering +administers +administration +administrations +administrative +administrator +administrators +admirable +admirably +admiral +admirals +admiration +admire +admired +admirer +admirers +admires +admiring +admissible +admission +admissions +admit +admits +admittance +admitted +admittedly +admitting +admonish +admonished +admonishes +admonishing +admonition +admonitions +ado +adobe +adobes +adolescence +adolescences +adolescent +adolescents +adopt +adopted +adopting +adoption +adoptions +adopts +adorable +adoration +adore +adored +adores +adoring +adorn +adorned +adorning +adornment +adornments +adorns +adrift +adroit +adroitly +ads +adulation +adult +adulterate +adulterated +adulterates +adulterating +adulteration +adulteries +adultery +adulthood +adults +advance +advanced +advancement +advancements +advances +advancing +advantage +advantaged +advantageous +advantages +advantaging +advent +adventure +adventured +adventurer +adventurers +adventures +adventuring +adventurous +adverb +adverbial +adverbials +adverbs +adversaries +adversary +adverse +adversely +adverser +adversest +adversities +adversity +advert +advertise +advertised +advertisement +advertisements +advertiser +advertisers +advertises +advertising +adverts +advice +advisable +advise +advised +adviser +advisers +advises +advising +advisories +advisory +advocate +advocated +advocates +advocating +aerial +aerials +aerodynamic +aerodynamics +aerosol +aerosols +aerospace +aesthetic +aesthetically +afar +affable +affably +affair +affairs +affect +affectation +affectations +affected +affecting +affection +affectionate +affectionately +affections +affects +affidavit +affidavits +affiliate +affiliated +affiliates +affiliating +affiliation +affiliations +affinities +affinity +affirm +affirmation +affirmations +affirmative +affirmatives +affirmed +affirming +affirms +affix +affixed +affixes +affixing +afflict +afflicted +afflicting +affliction +afflictions +afflicts +affluence +affluent +afford +affordable +afforded +affording +affords +affront +affronted +affronting +affronts +afield +aflame +afloat +afoot +aforementioned +aforesaid +afraid +afresh +after +aftereffect +aftereffects +afterlife +afterlives +aftermath +aftermaths +afternoon +afternoons +afterthought +afterthoughts +afterward +afterwards +again +against +age +aged +agencies +agency +agenda +agendas +agent +agents +ages +aggravate +aggravated +aggravates +aggravating +aggravation +aggravations +aggregate +aggregated +aggregates +aggregating +aggression +aggressive +aggressively +aggressiveness +aggressor +aggressors +aghast +agile +agiler +agilest +agility +aging +agitate +agitated +agitates +agitating +agitation +agitations +agitator +agitators +aglow +agnostic +agnosticism +agnostics +ago +agonies +agonize +agonized +agonizes +agonizing +agony +agree +agreeable +agreeably +agreed +agreeing +agreement +agreements +agrees +agricultural +agriculture +aground +ah +ahead +ahoy +aid +aide +aided +aides +aiding +aids +ail +ailed +ailing +ailment +ailments +ails +aim +aimed +aiming +aimless +aimlessly +aims +air +airborne +aircraft +aired +airfield +airfields +airier +airiest +airing +airline +airliner +airliners +airlines +airmail +airmailed +airmailing +airmails +airplane +airplanes +airport +airports +airs +airstrip +airstrips +airtight +airy +aisle +aisles +ajar +akin +alarm +alarmed +alarming +alarmingly +alarmist +alarmists +alarms +alas +albeit +albino +albinos +album +albums +alcohol +alcoholic +alcoholics +alcoholism +alcohols +alcove +alcoves +ale +alert +alerted +alerting +alerts +ales +alga +algae +algebra +algebraic +algorithm +algorithms +alias +aliased +aliases +aliasing +alibi +alibied +alibiing +alibis +alien +alienate +alienated +alienates +alienating +alienation +aliened +aliening +aliens +alight +alighted +alighting +alights +align +aligned +aligning +alignment +alignments +aligns +alike +alimony +alive +alkali +alkalies +alkaline +all +allay +allayed +allaying +allays +allegation +allegations +allege +alleged +allegedly +alleges +allegiance +allegiances +alleging +allegorical +allegories +allegory +allergic +allergies +allergy +alleviate +alleviated +alleviates +alleviating +alley +alleys +alliance +alliances +allied +allies +alligator +alligators +allocate +allocated +allocates +allocating +allocation +allocations +allot +allotment +allotments +allots +allotted +allotting +allow +allowable +allowance +allowances +allowed +allowing +allows +alloy +alloyed +alloying +alloys +allude +alluded +alludes +alluding +allure +allured +allures +alluring +allusion +allusions +ally +allying +almanac +almanacs +almighty +almond +almonds +almost +alms +aloft +alone +along +alongside +aloof +aloud +alpha +alphabet +alphabetic +alphabetical +alphabetically +alphabets +alphanumeric +already +also +altar +altars +alter +alterable +alteration +alterations +altered +altering +alternate +alternated +alternately +alternates +alternating +alternation +alternative +alternatively +alternatives +alternator +alters +although +altitude +altitudes +alto +altogether +altos +altruism +altruistic +aluminum +always +am +amalgamate +amalgamated +amalgamates +amalgamating +amalgamation +amalgamations +amass +amassed +amasses +amassing +amateur +amateurish +amateurs +amaze +amazed +amazement +amazes +amazing +amazingly +ambassador +ambassadors +amber +ambiance +ambiances +ambidextrous +ambient +ambiguities +ambiguity +ambiguous +ambiguously +ambition +ambitions +ambitious +ambitiously +ambivalence +ambivalent +amble +ambled +ambles +ambling +ambulance +ambulances +ambush +ambushed +ambushes +ambushing +amen +amenable +amend +amended +amending +amendment +amendments +amends +amenities +amenity +amethyst +amethysts +amiable +amiably +amicable +amicably +amid +amiss +ammonia +ammunition +amnesia +amnestied +amnesties +amnesty +amnestying +amoeba +amoebae +amoebas +amok +among +amoral +amorous +amorphous |
