Fencepost bug. for($|=1;@g>1;) in the first line should be for($|=1;@g>=1;) or for($|=1;@g>0;).
Sorry, that change causes an infinite loop. Of course you could always control-C out of it...
Update:
If the player is honest (or at least consistent), for($|=1;$&<40;) works at the expense of an additional character. Or you could combine this condition with one of the struck-out conditions above for a total of 248 or 247 characters.
Another fix that seems more natural to me involves using one of the struck-out conditions in combination with splice for a total of 250 or 249 characters.
It seems more natural to format this in four lines, though (take your pick):
@g=map{$_=sprintf"%04o",$_;$_=~y@0-7@A-H@;$_}0..4095;for($|=
1;@g>0;){print$f=splice(@g,@g*rand,1),$";($S=<>)=~/^[0-4]{2}$
/?(@g=grep{$d=4-($a=($f^($e=$_))=~y@\0@@);$d-=($c=index$e,$_)<
0||(substr($e,$c,1)="")for(split'',$f);$&eq$a.$d}@g):print"\7"}
or
@g=map{$_=sprintf"%04o",$_;$_=~y@0-7@A-H@;$_}0..4095;for($|=1;@
g>0;){print$f=splice(@g,@g*rand,1),$";($S=<>)=~/^[0-4]{2}$/?(@
g=grep{$d=4-($a=($f^($e=$_))=~y@\0@@);$d-=($c=index$e,$_)<0||
(substr($e,$c,1)="")for(split'',$f);$&eq$a.$d}@g):print"\7"}
|