These have the same regex as in my regex answer. I felt it was worth posting a standalone answer showing its use in languages that don't require an import to access regex functions (resulting in very effective golf). In order of how favorably it compares against the current best non-regex answer:
JavaScript ES6, 37 bytes
a=>/(.*([A-Z])(?!.*\2)){26}/i.test(a)
(37 bytes, always slow) - Try it online!
a=>/(.*?([A-Z])(?!.*\2)){26}/i.test(a)
(38 bytes, slow for non-matches) - Try it online!
a=>/((?=(.*?([A-Z])(?!.*\3)))\2){26}/i.test(a)
(46 bytes, fairly reasonable speed) - Try it online!
a=>/^((?=(.*?([A-Z])(?!.*\3)))\2){26}/i.test(a)
(47 bytes, very reasonable speed) - Try it online!
When looping this set of test cases, it can be seen that the 47 byte version is about 12 times as fast as the 46 byte version (in SpiderMonkey's regex engine).
PHP, 49 or 51 bytes
PHP imposes a strict backtracking limit (or time limit?) on its regexes, so the version that would be 48 bytes doesn't work at all; it always returns an empty result (except for very short non-pangram strings, for which it prints 0
).
<?=preg_match('/(.*?(\pL)(?!.*\2)){26}/i',$argn);
(49 bytes) - Try it online!
The 49 byte version, however, actually runs fast; it prints an empty result or 0
for false, and prints 1
for true. However, with sufficiently long pangram strings having a long separation between occurrences of new letters, it returns a false negative, due to taking too long to process the string.
<?=preg_match('/(?>.*?(\pL)(?!.*\1)){26}/i',$argn);
(51 bytes) - Try it online!
<?=preg_match('/^(?>.*?(\pL)(?!.*\1)){26}/i',$argn);
(52 bytes) - Try it online!
These versions print 0
for false and 1
for true.
Perl 5 -p
, 27 bytes
$_=/(.*(\pL)(?!.*\2)){26}/i
(27 bytes, always slow) - Try it online!
$_=/(.*?(\pL)(?!.*\2)){26}/i
(28 bytes, slow for non-matches) - Try it online!
$_=/(?>.*?(\pL)(?!.*\1)){26}/i
(30 bytes, fairly reasonable speed) - Try it online!
$_=/^(?>.*?(\pL)(?!.*\1)){26}/i
(31 bytes, very reasonable speed) - Try it online!
Perl 5, 33 bytes
Ties with the non-regex answer.
say<>=~/(.*(\pL)(?!.*\2)){26}/i+0
(33 bytes, always slow) - Try it online!
say<>=~/(.*?(\pL)(?!.*\2)){26}/i+0
(34 bytes, slow for non-matches) - Try it online!
say<>=~/(?>.*?(\pL)(?!.*\1)){26}/i+0
(36 bytes, fairly reasonable speed) - Try it online!
say<>=~/^(?>.*?(\pL)(?!.*\1)){26}/i+0
(37 bytes, very reasonable speed) - Try it online!
Ruby -n
, 29 bytes
Prints nil
for false and 0
for true. If printing 0
or 1
is desired, replace ~
with !!
(+1 byte).
p ~/(.*([A-Z])(?!.*\2)){26}/i
(29 bytes, always slow) - Try it online!
p ~/(.*?([A-Z])(?!.*\2)){26}/i
(30 bytes, slow for non-matches) - Try it online!
p ~/(?>.*?([A-Z])(?!.*\1)){26}/i
(32 bytes, fairly reasonable speed) - Try it online!
p ~/^(?>.*?([A-Z])(?!.*\1)){26}/i
(33 bytes, very reasonable speed) - Try it online!
For comparison, the 33 byte Ruby answer turns into a 28 byte answer when using -n
instead of a lambda (and prints false
or true
):
p (?a..?z).all?{|c|~/#{c}/i}
- Try it online!
Ruby, 34 bytes
Curiously, this is only 1 byte longer than the mixed code/regex answer:
->s{s[/(.*([A-Z])(?!.*\2)){26}/i]}
(34 bytes) - Try it online!
->s{s[/(.*?([A-Z])(?!.*\2)){26}/i]}
(35 bytes) - Try it online!
->s{s[/(?>.*?([A-Z])(?!.*\1)){26}/i]}
(37 bytes) - Try it online!
->s{s[/^(?>.*?([A-Z])(?!.*\1)){26}/i]}
(38 bytes) - Try it online!
When looping this set of test cases, the same result is seen: the 38 byte version is 12 times as fast as the 37 byte version.