http://www.perlmonks.org?node_id=433409


in reply to Golf: Buying with exact change

As the other monks observed, the most concise solutions will probably use regular expressions. When looking only at the length of strings, the set of amounts you can represent using $6, $9, and $20 bills is /^(.{6})*(.{9})*(.{20})*$/, or equivalently for our purposes, /^(.{6}|.{9}|.{20})*$/. Now, to get the function arguments into such a regex and find the longest string that doesn't match is the creative part...

Here are my two 48-character solutions:

$"="}|1{";$_=1x999;chop while/^(1{@_})*$/;length

$"="}|1{";(grep{(1x$_)!~/^(1{@_})*$/}1..999)[-1]

And if it weren't for a bug I just found in alternations within negative lookaheads, I'm pretty sure this would be equivalent, giving me 46 characters:

$"="}|1{";1x999=~/(1*?)(?!(1{@_})*$)/;length$'

They all use basically the same idea, can you think of a different approach? As I mentioned in the original post, these work for all instances where (a) the solution is 999 or less, and also (b) the arguments are each less than 32k (because they are used in regex quantifiers).

blokhead