46
\$\begingroup\$

Write a function or program that takes as its input a string and prints a truthy value if the string is a pangram (a sequence of letters containing at least one of each letter in the English alphabet) and a falsey value otherwise.

Case of letters should be ignored; If the string is abcdefghijklmnopqrstuvwXYZ, then the function should still return a truthy value. Note that the string can contain any other characters in it, so 123abcdefghijklm NOPQRSTUVWXYZ321 would return a truthy value. An empty input should return a falsey value.


Test cases

AbCdEfGhIjKlMnOpQrStUvWxYz

==> True


ACEGIKMOQSUWY
BDFHJLNPRTVXZ

==> True


public static void main(String[] args)

==> False


The quick brown fox jumped over the lazy dogs. BOING BOING BOING

==> True

This is code golf. Standard rules apply. Shortest code in bytes wins.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Plus points if your code can check if input is a Pungram. \$\endgroup\$ – Sainan May 17 '16 at 16:43
  • 8
    \$\begingroup\$ Question name request: Did the quick brown fox jump over the lazy dog? \$\endgroup\$ – user54200 Aug 4 '16 at 11:59

84 Answers 84

1 2
3
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), 48 bytes

x=>x.ToUpper().Distinct().Count(c=>c>64&c<91)>25

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Stax, 5 bytes

é►Ö_Z

Run and debug it

\$\endgroup\$
1
\$\begingroup\$

BaCon, 49 bytes

?IIF(AMOUNT(UNIQ$(EXPLODE$(LCASE$(s$))))>25,1,0)

\$\endgroup\$
1
\$\begingroup\$

Factor + math.unicode, 34 23 bytes

[ >lower ALPHABET ⊃ ]

Try it online!

-11 bytes thanks to @Bubbler!

Explanation:

This is a quotation (anonymous function) that takes a string as input and leaves a boolean value as output.

  • >lower Convert a string to lowercase.
  • ALPHABET Push a string containing the lowercase alphabet to the data stack.
  • Is the input a superset of the alphabet?
\$\endgroup\$
3
  • \$\begingroup\$ subset? is two bytes shorter than diff "" =. Kudos to all set operations working on plain sequences :) \$\endgroup\$ – Bubbler Mar 29 at 0:57
  • \$\begingroup\$ Also, if you accept to use sets.extras, you can shorten swap subset? further to superset? (which has that exact definition). \$\endgroup\$ – Bubbler Mar 29 at 1:09
  • \$\begingroup\$ @Bubbler Thanks for that insight. superset? also exists in math.unicode as for further reduction. \$\endgroup\$ – chunes Mar 29 at 2:01
1
\$\begingroup\$

C, 87 bytes

For platforms that use ASCII character coding.

f(char*s){char*t=s,i,r=0;for(;*t;)*t++|=32;for(i=97;i<123;)r|=!strchr(s,i++);return!r;}

This first modifies the input string to make it all lower-case (it doesn't matter what happens to non-letters, as they will not become letters or NUL). Then we test each lower-case letter to see whether it's present.

For an EBCDIC version, we need to replace *t++|=32; with *t++|=64; and for(i=97;i<123;) with for(i=193;i<234;i+=7*(i&16==9)+i==161).

Simple test program:

#include<stdio.h>
int main(int argc, char **argv)
{
    while (*++argv) {
        printf("%s: ", *argv);
        printf("%s\n", f(*argv) ? "Yes" : "No");
    }
}

Online test

\$\endgroup\$
1
\$\begingroup\$

Scratch, 145 bytes

define(s
set[z v]to[abcdefghijklmnopqrstuvwxyz
set[i v]to[
set[o v]to[1
repeat[26
change[i v]by(1
set[o v]to((o)*<(s)contains(letter(l)of(z
say(o

Uses scratchblocks syntax.

Function should have "Run before screen refresh" checked. Defines a function with an empty name and one argument (s). Output is 1 if s is a pangram and 0 if it is not.

<[]contains[]> works in scratchblocks syntax (which I used), but <[]contains[]?> is used in Scratch. This adds an extra byte, but because I'm using scratchblocks syntax, I don't think it should count.

\$\endgroup\$
2
  • \$\begingroup\$ set[i v]to((i)+(1 is a byte shorter than change[i v]by(1 if I've gotten my byte count correct. Also, very nice scratch answer! \$\endgroup\$ – lyxal Mar 30 at 21:40
  • \$\begingroup\$ @Lyxal Thanks, but it looks like it's two bytes longer to me. \$\endgroup\$ – Bo_Tie Mar 31 at 12:24
1
\$\begingroup\$

C, 64 bytes

n=63<<26;f(char*s){while(*s)n|=1<<(tolower(*s++)-97);return!~n;}

Explanation

  • Create a mask of 32-26 = 0b111111 = 63 and shl by 26 (you will understand why) with n=63<<26;

  • Iterate over string, set bit at index tolower(*s) - 'a' with while(*s)n|=1<<(tolower(*s++)-97);
    NB: Characters beyond 'z', {|}~, do not matter, as flags are already set.

  • Reverse all bits with ~, if all letters were encountered it should give 0, else it would give value of all letters that were missing in the char array. We return the opposite with !, so it becomes true if it is a pangram, else false.

\$\endgroup\$
2
  • \$\begingroup\$ Is n ever reseted on second call? \$\endgroup\$ – l4m2 Apr 2 at 13:18
  • \$\begingroup\$ it is not, it is a trick to save 4 bytes (int and space), if you want it to be reset you just move n declaration inside the function (68 bytes). \$\endgroup\$ – Antonin GAVREL Apr 2 at 16:02
1
\$\begingroup\$

JavaScript (ES9), 38 bytes

a=>a.match(/$|([A-Z])(?!.*\1)/igs)[25]

Try it online!

$| just to not crash if there's no letter. Worth mentioned competitor

\$\endgroup\$
7
  • \$\begingroup\$ I like this; it may not be the shortest overall but it's the shortest that runs fast. Here is a JavaScript ES9 way of doing it: Try it online! Please note that it's good manners to credit the code your answer is based on. \$\endgroup\$ – Deadcode Apr 2 at 13:54
  • \$\begingroup\$ Oh damn, my ES9 variant isn't always correct: Try it online! it fails when the first character is a non-letter and there are 25 unique letters. \$\endgroup\$ – Deadcode Apr 2 at 14:08
  • 1
    \$\begingroup\$ @Deadcode We all missed that the +1 can be easily saved \$\endgroup\$ – l4m2 Apr 2 at 14:26
  • \$\begingroup\$ Well done. But I suggest you name the language "JavaScript (ES6)" or "JavaScript ES6" because it doesn't have anything specific to SpiderMonkey (the test harness doesn't count). \$\endgroup\$ – Deadcode Apr 2 at 14:41
  • \$\begingroup\$ I just realized this doesn't accept multi-line input like the challenge requires. I've fixed my answer at +1 byte cost, and here's the same fix for yours: Try it online! – note that this requires changing your language spec to "JavaScript (ES9)". \$\endgroup\$ – Deadcode Apr 11 at 21:55
0
\$\begingroup\$

Seriously, 14 13 12 bytes

,ûOk"A["Ox-Y

Hex Dump:

2c964f6b22415b224f782d59

Try it online!

Explanation:

,                  read in the string from stdin
 û                 make it uppercase
  O                push all the character codes to the stack
   k               listify the stack
    "A["           push this string 
        O          pop it and push all of its character codes 
         x         push range(65,91)
          -        do set subtraction with the lists
           Y       logical not the result (so a zero length list becomes 1)

EDIT: moved input to the beginning to save a byte, thanks to @Mego

\$\endgroup\$
0
\$\begingroup\$

SpecBAS - 107 bytes

1 INPUT a$: LET a$=UP$(a$),c=0
2 FOR EACH l$ IN ["A" TO "Z"]: IF POS(l$,a$)>0 THEN INC c: NEXT l$
3 TEXT c=26

Set a counter to 0, loops through "A" to "Z" and increments the counter if found. Prints 0 (false) or 1 (true) if counter is 26.

\$\endgroup\$
0
\$\begingroup\$

Mumps, 86 bytes

R S F I=65:1:90{S J(I)=0} F I=1:1:$L(S){S Q=$A($E(S,I)) S:Q>92 Q=Q-32 K J(Q)} W '$D(J)

I built an array of nodes with all the ordinals of upper case characters, took the ordinal of each character in the string, converted lowercase to uppercase if necessary, and killed the associating node in the array. Here's my routine a bit more 'ungolfed':

R S                   ; Read STDIN into S
F I=65:1:90{S J(I)=0} ; Create an array of J() with all the uppercase ASCII ordinals
F I=1:1:$L(S)         ; loop through the # of characters in S
    {S Q=$A($E(S,I))  ; Set Q=the ordinal number of each character
    S:Q>92            ; if Q>92 (above the upper case, below the lower case ordinals
    Q=Q-32            ; subtract 32 from Q to convert to upper case.
    K J(Q)}           ; Kill the J(Ordinal) node of the array.
    W '$D(J)          ; $D will output False if there's no nodes in the array, true if some remain. \
                      ; write out the binary 'NOT' of this value.

The braces enable one-liners a bit more easily (multiple lines could add a few characters) and is a function of InterSystems Cache's version of Mumps.

\$\endgroup\$
0
\$\begingroup\$

Ruby, 39 33 bytes

This is the case insensitive version.

->s{(?a..?z).all?{|x|s[/#{x}/i]}}

Ruby, 32 bytes

Invalid (lowercase only)

No one has posted a ruby answer yet, so I made this. Nice and simple.

->s{(?a..?z).all?{|x|s.index x}}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ It only works for lowercase letters. \$\endgroup\$ – Vasu Adari Dec 11 '15 at 7:45
  • \$\begingroup\$ More love for ruby! ->s{(?a..?z).all?{|x|s[/#{x}/i]}} is 33 bytes. \$\endgroup\$ – blutorange Dec 13 '15 at 20:22
0
\$\begingroup\$

C, 97 bytes

c;t=26;i=26;f[26];p(char*s){while(*s)(c=*s++&~32-65)>=0&c<t?f[c]=1:0;while(i)t-=f[--i];return!t;}

Assumes ASCII or compatible character encoding.

C is not the best tool when it comes to string-related golf, nevertheless it was fun to code.

Globals are not reset, so this function will work as expected only once, but, hey, nobody said it should work the second time! ;-)

Test main:

#include <stdio.h>

int main(int argc, char **argv) {
  if (argc < 2) {
    fprintf(stderr, "Usage: %s <phrase>\n", argv[0]);
    return 1;
  }

  printf("%d\n", p(argv[1]));
}
\$\endgroup\$
0
\$\begingroup\$

R, 77 bytes

g=function(x){length(intersect(unlist(strsplit(tolower(x),"")),letters))==26}

Test cases:

> g("AbCdEfGhIjKlMnOpQrStUvWxYz")
[1] TRUE
> g("ACEGIKMOQSUWY
+ BDFHJLNPRTVXZ")
[1] TRUE
> g("public static void main(String[] args)")
[1] FALSE
> g("The quick brown fox jumped over the lazy dogs. BOING BOING BOING")
[1] TRUE
> g("")
[1] FALSE
\$\endgroup\$
1
  • \$\begingroup\$ You don't need the curly braces here since there is only one statement, thus saving 2 bytes \$\endgroup\$ – plannapus Nov 1 '16 at 8:19
0
\$\begingroup\$

Groovy, 57 bytes

u={print it.toLowerCase().toList().containsAll('a'..'z')}

Will groovy ever win?

\$\endgroup\$
0
\$\begingroup\$

Bash 4+, 86 48 bytes

Thanks to @Dennis for saving me 38 bytes!

Since return codes are what's checked by test/[ for truthy-ness in bash, the return code should be valid truthy/falsy output, right? If not, I'll edit to echo more typical truthy/falsy values (since bash true/false values are inverted compared to most things)

for x in {a..z}
{ [[ ${1,,} =~ $x ]] || exit 1
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ The exit code works as valid truthy/falsy output, since an exit code is a valid way of outputting an integer. \$\endgroup\$ – a spaghetto Dec 10 '15 at 19:56
  • 1
    \$\begingroup\$ 1. do and done can be replaced with { and }. 2. [[ ... ]]||exit 1 is shorter than if...fi. 3. I don't think the tr command is required at all; ${1,,} =~ $x should work just fine. \$\endgroup\$ – Dennis Dec 12 '15 at 13:58
  • \$\begingroup\$ @Dennis I think my tr command got leftover from when I was doing the search more as "is each character of the input in {a..z}" and it just never occurred to me to remove it when I changed that. Wouldn't have caught the other stuff, still getting the hang of this golfing thing \$\endgroup\$ – SnoringFrog Dec 28 '15 at 16:20
0
\$\begingroup\$

C++, 121 bytes

int P(char *s){int c;bitset<26> a;while(c=*s){c=tolower(c)-'a';if(c>=0&&c<26)a.set(c);if(a.all())return 1;s++;}return 0;}
\$\endgroup\$
0
\$\begingroup\$

32-bit x86 machine code, 27 bytes

In hex:

31c031d2ac48780d344024df3c1977f40fabc2ebef31d0c1e006c3

Input: ESI: NULL-terminated string. Returns: EFLAGS.ZF (1=truthy, 0=falsey).

0:  31 c0               xor eax, eax  
2:  31 d2               xor edx, edx  ;Bit array to keep track of letters
_loop :
4:  ac                  lodsb         ;Read next char
5:  48                  dec eax       ;Align 'A' to the power of two boundary, i.e. 0x40
6:  78 0d               js _break     ;...which also tests for NULL
8:  34 40               xor al, 0x40  ;Swap block [0x40..0x7f] (with letters) with [0..0x3f]
a:  24 df               and al, 0xdf  ;Map [0x60..0x7f] to [0x40..0x5f], that's toupper()
c:  3c 19               cmp al, 25    ;Letter are now in the [0..25] range
e:  77 f4               ja _loop      ;Anything else is greater if taken as unsigned
10: 0f ab c2            bts edx, eax  ;Set AL-th bit in EDX
13: eb ef               jmp _loop     
_break :
15: 31 d0               xor eax, edx  ;EAX=~EDX (EAX==-1 here), for pangram EDX==0x03FFFFFF
17: c1 e0 06            shl eax, 6    ;Shift out 6 unused bits. EFLAGS.ZF=EAX<<6==0?1:0
1a: c3                  ret           
\$\endgroup\$
0
\$\begingroup\$

Javascript (using external library - Enumerable) (83 bytes)

 n=>_.From("abcdefghijklmnopqrstuvwxyz").All(x=>_.From(n.toLowerCase()).Contains(x))

Link to library: https://github.com/mvegh1/Enumerable

Code explanation: Load the lowercase alphabet as char array, then test that every single char is contained in the lowercased input

enter image description here

\$\endgroup\$
0
\$\begingroup\$

K4, 12 bytes

Solution

&/.Q.a in\:_

Examples:

q)k)&/.Q.a in\:_"AbCdEfGhIjKlMnOpQrStUvWxYz"
1b
q)k)&/.Q.a in\:_"ACEGIKMOQSUWY\nBDFHJLNPRTVXZ"
1b
q)k)&/.Q.a in\:_"public static void main(String[] args)"
0b
q)k)&/.Q.a in\:_"The quick brown fox jumped over the lazy dogs. BOING BOING BOING"
1b

Explanation:

Lowercase the input, check whether each letter in a..z is in this. Take the min.

&/.Q.a in\:_ / the solution
           _ / lowercase
       in\:  / apply in to left and each-right (\:)
  .Q.a       / "abcdefghijklmnopqrstuvwxyz"
&/           / take the minimum
\$\endgroup\$
0
\$\begingroup\$

Smalltalk, 44 bytes

(($ato:$z)intersection:s asLowercase)size=26
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 5 bytes

lAیP

Try it online!

lAیP  # full program
    P  # product of...
  €    # each letter of...
 A     # "abcdefghijklmnopqrstuvwxyz"...
   å   # in...
       # implicit input...
l      # in lowercase
       # implicit output
\$\endgroup\$
0
\$\begingroup\$

Pxem, Filename: 118 bytes + Content: 0 bytes = 118 bytes.

  • Filename: @@€€.!.!.!.cX.w.i.c`.x .-XX.a.c@.x.c[.yA.-.t.m.w.!.m.-.c.t.a.t.c.m.$.%.z.m.+XX.aXX@.aXX.a.+.a.t.!.-.m.z.d.aY.o
    • Escaped: \100\100\200\200.!.!.!.cX.w.i.c\140.x\040.-XX.a.c@.x.c[.yA.-.t\001.m.w\002.!\001.m.-.c.t.a.t.c.m.$\002.%\001.z.m.+XX.aXX@.aXX.a\001.+.a.t\002.!\001.-.m.z.d.aY.o
  • Content: empty.

Try it online!

Usage

  • Input from stdin
  • Y to stdout for truthy, no output for falsey

With comments

XX.z
# push 2^26; dup; push non-zero value;
## NOTE 2^26 is initialized table
# while empty||pop!=0; do
.a\100\100\200\200.!.!.!.cX.wXX.z
  # push getchar
  .a.iXX.z
  ## NOTE capitalizing here
  .a.c\140.x\040.-XX.aXX.z
  # if isalpha top; then
  .a.c@.x.c[.yXX.z
      # let c is difference between 'A' and the character
      .aA.-.tXX.z
      # let m is 1; what digit to see
      ## NOTE m==2^c
      .a\001.m.w\002.!\001.m.-.c.t.aXX.z
      ## NOTE actual updating table
      # if tbl&m!=1; then tbl&=m; fi
      ## NOTE no logical operators
      .a.t.c.m.$\002.%%\001.z.m.+XX.aXX.z
      # push rando character and get out
      .aXX@.aXX.z
  .aXX.aXX.z
  # get out if EOF (-1)
.a\001.+.aXX.z
# finally: if tbl==2^27-1; then putchar Y; fi
.a.t\002.!\001.-.m.z.d.aY.o
\$\endgroup\$
-1
\$\begingroup\$

PHP, 172 bytes

function is_pangram ($s) {
return  preg_match("#^".implode(
   array_map(function ($x) {return "(?=.*{$x})" ;} ,
   str_split("ABCDEFGHIJKLMNOPQRSTUVWXYZ")))."#uis", $s);
}
\$\endgroup\$
1
  • 3
    \$\begingroup\$ I don't know PHP but it looks like there's a lot of whitespace that can be removed here, and using a shorter function name than is_pangram will help -- remember that the point of code golf is to solve the problem in as few bytes as possible! \$\endgroup\$ – Giuseppe Feb 22 '18 at 14:48
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.