The weekly challenge 286 - Task 1: Self Spammer
1 #!/usr/bin/env perl 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-286/#TASK1 3 # 4 # Task 1: Self Spammer 5 # ==================== 6 # 7 # Write a program which outputs one word of its own script / source code at 8 # random. A word is anything between whitespace, including symbols. 9 # 10 ## Example 1 11 ## 12 ## If the source code contains a line such as: 'open my $fh, "<", "ch-1.pl" or die;' 13 ## then the program would output each of the words { open, my, $fh,, "<",, "ch-1.pl", or, die; } 14 ## (along with other words in the source) with some positive probability. 15 # 16 ## Example 2 17 ## 18 ## Technically 'print(" hello ");' is *not* an example program, because it does not 19 ## assign positive probability to the other two words in the script. 20 ## It will never display print(" or "); 21 # 22 ## Example 3 23 ## 24 ## An empty script is one trivial solution, and here is another: 25 ## echo "42" > ch-1.pl && perl -p -e '' ch-1.pl 26 # 27 ############################################################ 28 ## 29 ## discussion 30 ## 31 ############################################################ 32 # 33 # We read the program code by opening $0 for reading, then reading everything 34 # line by line. We randomly select one line, which we then split into tokens 35 # at whitespace. Then we randomly select one token and print it. 36 # Obviously, this also contains comments, which we could exclude by grepping the 37 # program for lines that don't start in '#'. 38 39 use strict; 40 use warnings; 41 42 self_spammer($0); 43 44 sub self_spammer { 45 my $program = shift; 46 my @lines = (); 47 open(my $IN, "<", $program) or die "Can't open $program for reading: $!"; 48 while(my $line = <$IN>) { 49 chomp($line); 50 push @lines, $line; 51 } 52 my $l = $lines[int(rand(1+$#lines))]; 53 my @tokens = split /\s+/, $l; 54 my $t = $tokens[int(rand(1+$#tokens))]; 55 print "$t\n"; 56 } 57