24
('1' * N) !~ /^1?$|^(11+?)\1+$/

On the net, I found this piece of Ruby code that works for N >= 0 that determines whether or not N is a prime. From what I can tell, it looks like play with regex but I have no idea how it works. Could someone tell me how it works?

  • Is this really an indictment of Ruby's obscure syntax? If so, I totally agree - wow is that obscure! – S.Lott Sep 29 '08 at 01:50
  • 2
    What do you mean by "Ruby's obscure syntax"? Regexps look pretty much the same in all languages, don't they? – Jörg W Mittag Sep 29 '08 at 01:54
  • 5
    This is just an obscure regex, it's not actually anything to do with ruby – Orion Edwards Sep 29 '08 at 01:56
  • wow! I'm impressed, really. but this will work because this is POSIX regex. Normally we cannot build deterministic finite state machine that will accept/reject primary number and as I know DFA <=> regex. So this is not property of regular expression but of the posix regular expression – dfens Aug 23 '10 at 14:11
  • What is the O-notation run time of this? Anyone know? – Automatico Apr 29 '13 at 19:50

7 Answers7

25

You can find a lengthy explanation of this code here: http://www.noulakaz.net/weblog/2007/03/18/a-regular-expression-to-check-for-prime-numbers/

Jay
  • 41,768
  • 14
  • 66
  • 83
21

This is probably rather off-topic, but in Ruby 1.9, you can do this:

 require 'mathn'
 38749711234868463.prime?
 => false
Trevoke
  • 4,115
  • 1
  • 27
  • 48
4
require 'prime'

Prime.prime?(4)
# => false

Prime.prime?(5)
# => true

Or:

require 'prime'

Prime.instance.prime?(4)
# => false

Prime.instance.prime?(5)
# => true
toro2k
  • 19,020
  • 7
  • 64
  • 71
rajagopal
  • 49
  • 4
2

See also What is the most brilliant regex you’ve ever used? (and yes, I can confirm that this regexp was originally written by Abigail. I've even heard her explain how it works :)

Community
  • 1
  • 1
dland
  • 4,319
  • 6
  • 36
  • 60
2

If the length of a string of 1's is composite, then the string can be decomposed into multiple identical substrings, like 111111 -> 11 11 11

For example, 1111111111, has 10 1's, and it matches (11){5} or (11111){2}, where {2} means repeated 2 times. 111111111, has 9 1's, and it matches (111){3}.

By generalizing the count of 1's and the number in {}, the regexp is /(1{2,}){2,}/. However, 1{2,} can also be written as 11+, and (...){2,} can be rewritten as (...)\1+, with backreferences.

The ^1?$ part in the first alternation checks for 0 and 1-cases.

Ming-Tang
  • 17,410
  • 8
  • 38
  • 76
1

Greatest Common Divisor (gcd):

/^(1+)\1*=\1+$/.match('1' * x + '=' + '1' * y)[1].length

Both this and the is_prime one works in about the same way. It tries all combinations before giving up.

This one will try to split the first number in even parts, and match the second number with one or more of those parts. If it finds a match it returns the length of the selected part.

Markus Jarderot
  • 86,735
  • 21
  • 136
  • 138
1

Yet another blog with a pretty good explanation: Famous Perl One-Liners Explained (part III)

MAK
  • 26,140
  • 11
  • 55
  • 86