Perl: the Markov chain saw PerlMonks

by xmath (Hermit)
 on Jul 21, 2004 at 19:38 UTC Need Help??

After the success of last year's edition, #perlhelp (EFnet) is proud to present... insaner than ever... the second round of How's your Perl? ! :-)

There are thirteen exercises this year. Each exercise consists of a predicate to be made true by a short snippet of code preceding the test. (For example, a simple way of checking your solution for an exercise is: perl -e '<solution>; <exercise> and print "ok!\n"')

1. Don't reuse the method of solution of one exercise for any other.
2. Don't make use of any external files (including modules).
3. No tie() and no bless().

All exercises have been tested with perl 5.8.*, and solutions do not necessarily have to work with any other version. Don't hesitate to use deprecated or experimental features, or depend on implementation details or even bugs, but avoid platform dependencies.

When posting comments, please protect spoilers and solutions from accidental viewing, for example using a black-box (<table bgcolor="#000000"><tr><td><font color="#000000">Text goes here</font></table>)

Have fun!

(not in order of difficulty)

Exercise 1:    \$foo =~ /^[A-G]/ Exercise 2: \$foo =~ /^[H-N]/

Exercise 3:    \$foo =~ /^\0/ Exercise 4: \$foo =~ /IO::Handle/

Exercise 5:    \$foo =~ /IO::/ &&$foo

Exercise 6:    \$foo[$[] == \$foo[$[+1]
[download]
Exercise 6 Update: \$foo[0] == \$foo[1] && !$[ Exercise 7: !eval { ($foo) = $foo } Exercise 8: !eval { [ @foo ] } Exercise 9:$foo && $foo =~ /^0\z/ Exercise 10:$foo =~ /^0\z/ && $foo Exercise 11: "$|" == 2 && $| == 0 Exercise 12: ($| = 1) == 2

Exercise 13:   undef
[download]

Special thanks to mauke and woggle.

UPDATE: Apparently the notion of taking advantage of a yet-to-be-fixed bug is controversial. I therefore note that only 8, 11, and 12 are fishy in this regard, the other exercises are definitely solvable without exploiting bugs.

UPDATE: Minor rephrase of instructions for clarity.

UPDATE: Cool! ambrus and wog found an innovative way of solving 8 without exploiting a bug! :-D

UPDATE: Official solutions will be posted on monday. Until then there are hints below.

UPDATE: Official solutions have been posted.

Replies are listed 'Best First'.
by tilly (Archbishop) on Jul 21, 2004 at 22:59 UTC
I have a magic solution that solves ALL of these at once according to your simple test!  print "ok!\n"; #
;-)

I thought that, by convention, such solutions were expected to be too long to fit in the margins of one's post.

--
F o x t r o t U n i f o r m
Found a typo in this node? /msg me
% man 3 strfry

So call me unconventional. It wouldn't be the first time. :-)
Yes, that would solve any one of the problems, but not all, as the rules explicitly forbid you from using the same solution on more than one problem.

##### Believe nothing, no matter where you read it, or who said it - even if I have said it - unless it agrees with your own reason and your own common sense. -- Buddha
Since the simple test doesn't test for "using the same solution on more than one problem", what I said remains entirely true. ;-)
by ccn (Vicar) on Jul 21, 2004 at 21:42 UTC

13-th (xmath says that this is a cheat)  use subs 'and';sub and :lvalue {$_}; 9-th $foo="\n0";$*++; 7-th  *foo = \1; 6-th  sub f{\@_}; *foo = f($_,$_); 2-d  *foo=\pos; 1-st $foo = *_;

Update: 10-th REMOVED, because it use the same method as 9-th

13-th: Heh, clever, but it doesn't actually make the predicate true, it just makes the example method of checking your solution work.

Update: and subs.pm is a module ;-)

by BrowserUk (Pope) on Jul 22, 2004 at 04:14 UTC

2 & 7  *foo = \substr '...', 1, 1;

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
by itub (Priest) on Jul 22, 2004 at 00:32 UTC
1:  $foo=*a; Re: How's your Perl? (II) by Errto (Vicar) on Jul 22, 2004 at 03:59 UTC Update:modified slightly. 6:  my @foo = (0);$[ = -1;

That doesn't seem to work here.

___________
Eric Hodges
I modified it slightly. I'm running: This is perl, v5.8.3 built for i386-linux-thread-multi

Confirmed on 5.6.1, 5.8.0, 5.8.1, 5.8.3. Doesn't work on 5.8.4 and 5.8.5.
And I think it should not work, because $foo[$[] is the first element and $foo[$[+1] is the second; I don't see how $[ and$[+1 can refer to the same element.

All exercises have been tested with perl 5.8.*, and solutions do not necessarily have to work with any other version.

I take this to imply that solutions should work with all 5.8.* perls.

Hm, strange.. I actually wrote $foo[$[] in the assuption this would prevent any $[-fiddling and force the real solution, but it seems$[ really doesn't work properly in perl: perl -le '$[ = -1; @x = (42);$y = 0; print $x[$y]' prints 42 for me on 5.8.3 and 5.8.4...

I'll add a note to the exercise that the intention is to solve it without diddling $[ Fair enough. My only excuse is that 5.8.3 is the only version I have, and that the other way seemed too similar to one of the solutions from last time around so I wanted to try something different :) I was trying to use the fact that$foo[-1] is the last element in the array, so if the array only has one element ...
by ambrus (Abbot) on Jul 22, 2004 at 13:55 UTC
You don't need any switches!

 BEGIN{$^P=0x22;sub DB::DB{++$foo==2 and die}} [download]

(I am pretty sure that is not the official solution, by the way, and it means that 8 does not need to exploit actual bugs.)

updated: Oops, copied a wrong version initially. One character difference.

by xmath (Hermit) on Jul 22, 2004 at 14:14 UTC

## Official hints:

 [all] There are two "wildcard solutions" that each can be used to solve nearly all of the exercises. Due to the no-reuse rule you can use each of them only once, and they're officially used for exercises 3 and 13. [1-5] Just explore all kind of scalar references. If you're really desperate you can plow through Perl_sv_2pv_flags() in sv.c in the perl source code to see exactly how references get stringified. [3] Good candidate for wildcard one: Find a way to override the meaning of the regex. [4,8] The pattern of exercise 4 is misleading, but the search down this incorrect path may reveal the solution to exercise 8. Exercise 4 is actually simpler than you'd think. [5] A fairly recent and unknown class of built-in objects. [6] Alias. (Last year there was a similar one which could be solved by manipulating $[. I tried to prevent that this year, though initially without success) [7] Make modification fail. [8] Find something that fails to get assigned anywhere. See also hint about 4 and 8 above. The ability to acquire this thing at all is most likely a bug. [9] Subtly perturb the meaning of the regex. [10] Have$foo change as a result of the first part of the predicate test. [11] Find a way to scribble onto $| so rudely it never gets properly turned into 0 or 1. This mechanism is most likely a bug. [12] Find a variable that ignores being assigned to. This behaviour is most likely a bug. [13] The best spot for wildcard two: A feature was added in 5.8 with which you can modify constants. Re: How's your Perl? (II) by diotalevi (Canon) on Jul 22, 2004 at 17:25 UTC $foo = *_; *foo = \ substr "", 0, 1; BEGIN { $^H = 0x30000;$^H{"qr"} = sub{""}; } sub { *foo = \@_ }->( $foo,$foo ) *foo = \ "constant" I didn't know this one until I saw ccp's answer and I don't know of a second way. *foo = *`; $* = 1; "true\n0"=~/\z/; *| = \$foo; 2 =~ /(2)/; *| = *^N; xmath gave this one to me because it contradicted the documentation and it isn't supposed to be possible. There is a loophole but it requires reading an obscure bit from Changes5.8.
by xmath (Hermit) on Jul 26, 2004 at 13:26 UTC

## Solutions:

Note that for a few exercises multiple solutions are given.

 [1] $foo = *x; [2] *foo = \substr$x, 0; *foo = \vec $x, 0, 8; [3] BEGIN {$^H |= 0x30000; $^H{qr} = sub{""} } [4] *foo = qr/IO::Handle/; [5] *foo = find PerlIO::Layer "raw"; [6] *foo = sub{\@_}->($x, $x); [7] *foo = \42; [8] *foo = sub{\@_}->(${*STDIN{IO}}); sub DB::DB { die if ++$x==2 } BEGIN {$^P |= 0x22 } [9] $foo = "\n0";$* = 1; [10] //; *foo = \$+[0]; [11] *@ = *|; eval { die "2" }; [12] 2 =~ /(2)/; *| = \local$1; 2 =~ /(2)/; *| = *^N; $[ = 2; *| = *[; [13] &Internals::SvREADONLY(\undef, 0); undef = 42; Re: How's your Perl? (II) by roju (Friar) on Jul 22, 2004 at 15:54 UTC 1. $foo=*STDOUT

Create A New User
Node Status?
node history
Node Type: perlmeditation [id://376362]
Approved by ysth
Front-paged by ysth
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (14)
As of 2016-10-21 17:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How many different varieties (color, size, etc) of socks do you have in your sock drawer?

Results (289 votes). Check out past polls.