Pathologically Eclectic Rubbish Lister PerlMonks

Re: (tye)Re2: (Golf) Let's go bowling (98!)

by petral (Curate)
 on Aug 14, 2001 at 01:59 UTC ( #104606=note: print w/replies, xml ) Need Help??

in reply to (tye)Re2: (Golf) Let's go bowling (98!)
in thread (Golf) Let's go bowling

Same thing that caught me:
```print bowl(join'', qw(0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 X 3 4));
53!
should be 60.
(but you can save a few strokes using /./g for split//)

p

Replies are listed 'Best First'.
(tye)Re3: (Golf) Let's go bowling (113)
by tye (Sage) on Aug 14, 2001 at 03:29 UTC

Darn. I noticed elsewhere in the thread about being sure to not count the bonus balls twice but missed the stuff about there being no good trick to tell whether X\d\d\$ is a final frame with bonus balls or just the two final frames (other than counting frames). ):

I really didn't want to hard-code the number of frames because sometimes I'll bowl a "short game" when we run out of time. So here is an entry at 113 strokes that optionally lets you specify how many frames you shortened your game (you can even pass in a negative value for "extra long games"):

```sub bowl {
(\$_,\$n)=@_;
s#(\d)(\d|/(?=(.)))|X(?=(..))|.#
(\$3.\$4?"X\$3\$4":\$1.\$2,"")[9<\$n++]#ge;
s#./#X#g;
map{(y.X.a.)x hex}split//
}

chomp( @ARGV=<DATA> ) if ! @ARGV;
for my \$line ( @ARGV ) {
print "\$line = ", 0+bowl(\$line), "\n   ";
for(  0..9  ) {
print " ",0+bowl(\$line,9-\$_);
}
print \$/;
}
__END__
81633470434/72813/62
81633470434/72813/X18
X00X00X00X00X00
00X00X00X00X00X00
X11X11X11X11X11
11X11X11X11X11X11
5/63XX7043X4/813/6
This even allowed me to add a test suite that shows the score at each frame.

- tye (but my friends call me "Tye")
Awesome. But, um, you can combine the last 2 lines (and return a scalar):  s#./|X#9#g+eval join'+',/./g
(and I still don't understand how that `|.' guard is working.)

Thanks! Those are much shorter ways of splitting and dealing with the 10s. My method of summing is a bit shorter, so that gets me to 105:

```sub bowl {
(\$_,\$n)=@_;
s#(\d)(\d|/(?=(.)))|X(?=(..))|.#
(\$3.\$4?"X\$3\$4":\$1.\$2,"")[9<\$n++]#ge;
s#./|X#9#g+map{(3)x\$_}/./g
}

chomp( @ARGV=<DATA> ) if ! @ARGV;
for my \$line ( @ARGV ) {
print "\$line = ", bowl(\$line), "\n   ";
for(  0..9  ) {
print " ",bowl(\$line,9-\$_);
}
print \$/;
}
__END__
81633470434/72813/62
81633470434/72813/X18
X00X00X00X00X00
00X00X00X00X00X00
X11X11X11X11X11
11X11X11X11X11X11
5/63XX7043X4/813/6

The |. on the end of the first regex is required so that the regex matches the entire string. Take a 5-frame game as an example:

```6/ 45 X  7/ X3/
14  9 20 20 20
14 23 43 63 83
"6/45X7/X3/"
"6/" matches; \$1="6", \$2="/", \$3="4"; change to "X4"
"45" matches; \$1="4", \$2="5"; change to "45"
"X" matches; \$4="7/"; change to "X7/"
"7/" matches; \$1="7", \$2="/", \$3="X"; change to "XX"
"X" matches; \$4="3/"; change to "X3/"
"3" matches; change to "\$1\$2" eq ""
"/" matches; change to "\$1\$2" eq ""
(result: "X445X7/XXX3/")
Those last two substitutions wouldn't happen without the "|." on the end of the regex. The zero-width lookahead assertions, (?=...), aren't part of the "match" and so don't get "consumed" during replacement.

If we required that unused bonus frames be recorded as "-", for example, we could get even shorter. For example, this 86-stroke version:

```sub bowl {
\$_=pop;
s#(\d\d|.(/))(?=(.))|X(?=(..))|.#\$2.\$4?"X\$3\$4":\$1#ge;
s#./|X#9#g+map{(7)x\$_}/./g
}

chomp( @ARGV=<DATA> ) if ! @ARGV;
for my \$line ( @ARGV ) {
print "\$line = ", bowl(\$line), \$/;
}
__END__
81633470434/72813/62--
81633470434/72813/X18
X00X00X00X00X00--
00X00X00X00X00X00
X11X11X11X11X11--
11X11X11X11X11X11
5/63XX7043X4/813/6

- tye (but my friends call me "Tye")

Create A New User
Node Status?
node history
Node Type: note [id://104606]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2017-10-18 06:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
My fridge is mostly full of:

Results (242 votes). Check out past polls.

Notices?