42
\$\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\$
  • 3
    \$\begingroup\$ Plus points if your code can check if input is a Pungram. \$\endgroup\$ – timmyRS May 17 '16 at 16:43
  • 4
    \$\begingroup\$ Question name request: Did the quick brown fox jump over the lazy dog? \$\endgroup\$ – user54200 Aug 4 '16 at 11:59

63 Answers 63

25
\$\begingroup\$

Pyth, 7 bytes

L!-Grb0

Explanation:

L             lambda (implicit b:)
    rb0       Convert b to lowercase
   G          Lowercase alphabet, "abcd...z"
  -           Set difference, all elts of first that aren't in second
 !            Logical NOT (The empty string is falsey)

Try the full-program, single-line version here.

\$\endgroup\$
  • \$\begingroup\$ I think the shortest way to fix this for newlines in the input is to make a function: L!-Grb0. !-Grs.z0 would also work but is longer. \$\endgroup\$ – FryAmTheEggman Dec 10 '15 at 16:13
  • \$\begingroup\$ Oh, I didn't see the question updated to include \n in the string. Thanks. \$\endgroup\$ – lirtosiast Dec 10 '15 at 22:30
  • \$\begingroup\$ 6 bytes: pyth.herokuapp.com/… \$\endgroup\$ – Maltysen Dec 11 '15 at 3:56
  • \$\begingroup\$ @Maltysen While there is a (weak) consensus on allowing strings from input to be delimited by quotes, I'm not sure about this as it goes further in requiring Python string syntax. \$\endgroup\$ – lirtosiast Dec 11 '15 at 16:04
  • \$\begingroup\$ I never would have thought an alphabet built-in would be useful... \$\endgroup\$ – Cyoce Dec 12 '15 at 8:43
16
\$\begingroup\$

Perl 6, 20 bytes

'a'..'z'⊆*.lc.comb

usage:

my &code = 'a'..'z'⊆*.lc.comb;
#  the parameter is ^ there

say code '123abcdefghijklm NOPQRSTUVWXYZ321' # True
say code '123abcdefghijklm NOPQRSTUVWXY'     # False

I used the 3 byte "french" version () of U+2286 SUBSET OF OR EQUAL TO operator instead of the 4 byte "texas" version ((<=)) which would have also required an extra space in front of it.

\$\endgroup\$
12
\$\begingroup\$

GS2, 11 9 bytes

☺ 6ΘàB1."

Thanks to @MitchSchwartz for golfing off 2 bytes!

The source code uses the CP437 encoding. Try it online!

How it works

☺              Push 32 (code point of space).
  6            Bitwise OR.
   Θ           Make a block of these two instructions and map it over the input.
               This turns uppercase letters into their lowercase counterparts.
      à        Push the lowercase alphabet.
       B1      Swap and apply set difference.
         ."    Push the logical NOT of the length of the result.
\$\endgroup\$
  • \$\begingroup\$ quick block m2 (\xe9) saves 2 bytes. \$\endgroup\$ – Mitch Schwartz Dec 10 '15 at 5:24
  • \$\begingroup\$ @MitchSchwartz Oh, so that's how you use those. Thanks! \$\endgroup\$ – Dennis Dec 10 '15 at 5:29
11
\$\begingroup\$

JavaScript ES6, 51 57

Edit 6 bytes save thx @user81655

a=>new Set(a.toUpperCase().match(/[A-Z]/g)).size>25

Test snippet

F=a=>new Set(a.toUpperCase().match(/[A-Z]/g)).size>25

function update() {  O.innerHTML=F(I.value) }
I.value='qwertyuiopasdfghjklzxcvbnm';update()
input { width: 70% }
<input id=I oninput='update()'>
<pre id=O></pre>

\$\endgroup\$
  • \$\begingroup\$ Would a.replace(/[^A-Z]|[^a-z]/g,'') or a.replace(/[^A-Z]/gi,'') work? \$\endgroup\$ – ev3commander Dec 11 '15 at 1:12
  • 2
    \$\begingroup\$ @ev3commander no. A and a must become the same character, else the set will keep them as distinct and the size will be > 26 \$\endgroup\$ – edc65 Dec 11 '15 at 6:21
  • \$\begingroup\$ What if you use the spread operator with [...a.toUpperCase().replace(/[^A-Z]/g,'')].length>25 ? \$\endgroup\$ – Scott Dec 11 '15 at 16:55
  • \$\begingroup\$ @ScottKaye obviously no. Try it with 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' \$\endgroup\$ – edc65 Dec 11 '15 at 17:35
  • 1
    \$\begingroup\$ @user81655 right, it works, great. Thanks. I should not answer comments while asleep \$\endgroup\$ – edc65 Dec 12 '15 at 11:07
9
\$\begingroup\$

R 50 ,46 39 bytes

all(sapply(letters,grepl,readline(),T))

Edit drops the need for tolower by adding ignore.case=TRUE (T)

\$\endgroup\$
  • \$\begingroup\$ Not too familiar with R, but shouldn't ignore.case=TRUE (T) be included in the count as well then? \$\endgroup\$ – Ruslan Dec 11 '15 at 13:30
  • 2
    \$\begingroup\$ @Ruslan It is! It is the Tas the end, thanks to argument placement matching there is no need to actually specify the name of the argument (and T is the default alias for TRUE). The code written here performs the needed action as is, without any need to add anything. \$\endgroup\$ – plannapus Dec 11 '15 at 14:29
9
\$\begingroup\$

O, 11 bytes

GQ_s{n-}dS=

Try it online.

Sadly, O does not have set difference :/

Explanation

G            Pushes the alphabet to the stack
 Q           Pushes input to the stack
  _          Converts the string to lowercase
   s         Split string into char array
    {  }d    Iterate through array
     n       Pushes current element to the stack
      -      String subtraction
         S   Pushes a blank string to the stack
          =  Equals
\$\endgroup\$
6
\$\begingroup\$

Julia, 38 bytes

s->endof(∩('a':'z',lowercase(s)))>25

This is simple - lowercase deals with the uppercase/lowercase issue, 'a':'z' holds all of the lowercase letters, is intersection, removes any character that isn't a letter and, because 'a':'z' comes first, will only have one of each letter that appears in s. endof is the shortest way to get the length of the resulting array, and if it's 26, then it's a pangram (it can't be more than 26, and >25 saves a byte relative to ==26).

\$\endgroup\$
6
\$\begingroup\$

Python 2, 53 51 bytes

f=lambda s,c=65:c>90or(chr(c)in s.upper())*f(s,c+1)

Alternate solutions:

lambda s:all(chr(c)in s.upper()for c in range(65,91))

lambda s:not set(range(65,91))-set(map(ord,s.upper()))

Thanks to xnor for pointing out that sets have an <= operator, for an alternate 51:

lambda s:set(range(65,91))<=set(map(ord,s.upper()))
\$\endgroup\$
  • 1
    \$\begingroup\$ If I'm not mistaken, the last expression is the same as lambda s:set(range(65,91))<=set(map(ord,s.upper())), also for 51. \$\endgroup\$ – xnor Dec 10 '15 at 5:06
  • \$\begingroup\$ Python 3.5 can save bytes here: p=lambda s:{*range(65,91)}<={*map(ord,s.upper())}. By the way, I can't seem to find any rules on whether a lambda needs to be assigned (as in your first case) or not (as in your later ones). Help? \$\endgroup\$ – Tim Pederick Dec 11 '15 at 16:30
  • \$\begingroup\$ @TimPederick Naming the lambda is unnecessary unless you need to use the function elsewhere, like in the first recursive solution. \$\endgroup\$ – FryAmTheEggman Dec 11 '15 at 16:57
  • \$\begingroup\$ @TimPederick Thanks for pointing that out. I renamed my answer as Python 2 instead of just Python. You have my blessing to post that as a new answer if you want, which I think would be ok by community norms although I'm not sure. \$\endgroup\$ – Mitch Schwartz Dec 11 '15 at 17:33
  • \$\begingroup\$ @FryAmTheEggman: Thanks for clarifying. That distinction hadn't occurred to me! I've also found a meta post explaining the rule. There goes two bytes from a few things I've written... \$\endgroup\$ – Tim Pederick Dec 12 '15 at 13:51
5
\$\begingroup\$

Retina, 22 bytes

Msi`([a-z])(?!.*\1)
26

Try it online.

The first line matches any letter which does not appear again later in the string. That ensures that we don't match each letter at most once, no matter how often it occurs. Match mode will by default replace the string with the number of matches found. So in the second stage, we match 26 against the result of the first input, which will give either 0 or 1, depending on whether we found the maximum of 26 matches or not.

\$\endgroup\$
4
\$\begingroup\$

Minkolang 0.14, 18 bytes

$o7$ZsrlZ'26'$ZN.

Try it here.

Explanation

$o                    Read in whole input as characters
  7$Z                 Uppercase every letter
     s                Sort
      r               Reverse
       lZ             Alphabet - uppercase and lowercase
         '26'         Pushes 26 on the stack
             0$Z      Count how often the top 26 numbers of the stack appear in the stack
                N.    Output as number and stop.
\$\endgroup\$
4
\$\begingroup\$

Python 3.5, 47 bytes

lambda s:{*map(chr,range(65,91))}<={*s.upper()}

Same principle as Mitch Schwartz's answer, but using the PEP 0448 enhancements to * unpacking, first introduced in Python 3.5.

This version differs slightly from what I wrote in my comment to Mitch's post, in that I turn the numbers into letters rather than vice versa. That's because that's how I wrote my original attempts at a solution, before discovering that I couldn't out-golf Mitch without outright copying his approach. So consider that tweak my one remaining shred of originality!

\$\endgroup\$
4
\$\begingroup\$

Ruby, 41 33

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

Usage

p=->s{(?a..?z).all?{|c|s[/#{c}/i]}}
p["AbCdEfGhIjKlMnOpQrStUvWxYz"] 
  #=> true
p["ACEGIKMOQSUWY
BDFHJLNPRTVXZ"]
  #=> true
p["public static void main(String[] args)"]
  #=> false
p["The quick brown fox jumped over the lazy dogs. BOING BOING BOING"]
  #=> true

Thanks to Vasu Adari for saving me 8 bytes

\$\endgroup\$
  • 2
    \$\begingroup\$ You can save 8 bytes by making your regex to ignorecase. \$\endgroup\$ – Vasu Adari Dec 11 '15 at 7:49
4
\$\begingroup\$

R, 53 45 bytes

all(97:122%in%utf8ToInt(tolower(readline())))

Old version at 53 bytes:

all(letters%in%strsplit(tolower(readline()),"")[[1]])

Usage:

> all(97:122%in%utf8ToInt(tolower(readline())))
The quick brown fox jumps over the lazy dog
[1] TRUE
> all(97:122%in%utf8ToInt(tolower(readline())))
Write a function or program that takes as its input a string and prints a truthy value if the string is a pangram and a falsey value otherwise.
[1] FALSE
> all(97:122%in%utf8ToInt(tolower(readline())))
123abcdefghijklm NOPQRSTUVWXYZ321
[1] TRUE
> all(97:122%in%utf8ToInt(tolower(readline())))
Portez ce vieux whisky au juge blond qui fume
[1] TRUE
\$\endgroup\$
4
\$\begingroup\$

MATLAB / Octave, 35 33 bytes

@(x)~nnz(setdiff(65:90,upper(x)))

Try it online!


The anonymous function returns a logical 1 if the input x is a pangram, or a logical 0 if it isn't.

Essentially it uses the same approach as @ThomasKwa's Pyth solution. The set difference between all characters in the upper case alphabet range (65:91) and the input string (converted to upper case). Any characters that are in the alphabet but not in the input string are returned by setdiff. Only if the array returned by the set difference is empty is the string a pangram.

Using upper case instead of lower case saves a couple of bytes compared with 'a':'z' because the ASCII value can be used instead to make the range.

\$\endgroup\$
  • \$\begingroup\$ Great answer! Mine was 10 bytes longer \$\endgroup\$ – Luis Mendo Dec 10 '15 at 23:37
4
\$\begingroup\$

Haskell, 59 56 53 51 bytes

p s=and[any(`elem`map toEnum[a,a+32])s|a<-[65..90]]

Try it online!

Explanation:

Give an input string s, for each a in range 65 to 90 (the ASCII codes for A to Z) it is checked whether any character in s is equal to either a (the upper case character) or a+32 (the lower case character), converted to a character by toEnum. This generates a list of booleans. and checks if they're all True.

Old version:

import Data.Char
p s=and[any((==)a.toUpper)s|a<-['A'..'Z']]

For every upper case alphabet letter, check whether some letter from s in upper case is equal to it. any(==a)s is the same as elem a s but allows to modify the elements of s before the comparison - in this case, covert them to upper case.

\$\endgroup\$
3
\$\begingroup\$

Japt, 14 bytes

#ao#{ e@Uv fXd

Try it online!

How it works

        // Implicit: U = input string
#ao#{   // Generate a range of integers from charCode("a") to charCode("{").
e@      // Check if every item X in this range returns truthily to:
Uv fXd  //  convert U to lowercase, and put all instances of X.toCharCode() in an array.
        // This returns false if U does not contain one of the characters.
        // Implicit: output last expression
\$\endgroup\$
3
\$\begingroup\$

CJam, 11 bytes

'[,65>qeu-!

This is a complete program. Try it online.

Explanation:

'[,65>  Build upper case alphabet (see CJam tips thread).
q       Get input.
eu      Convert to all upper case.
-       Set difference between alphabet and upper cased input.
!       Negate.
\$\endgroup\$
3
\$\begingroup\$

Javascript, 110 109 99 95 93 bytes

a=prompt(b=0).toUpperCase();for(i=65;i++<91;)b+=!~a.indexOf(String.fromCharCode(i));alert(!b)

Saved 6 bytes thanks to Thomas Kwa, and 10 thanks in part to ev3.

\$\endgroup\$
  • \$\begingroup\$ Would b=0 work for b=[]? \$\endgroup\$ – ev3commander Dec 11 '15 at 1:13
  • \$\begingroup\$ Not with this approach. But I may be able to make that work. \$\endgroup\$ – SuperJedi224 Dec 11 '15 at 1:32
  • \$\begingroup\$ I don't know Javascript, but can you do for(i=65;i++<91;)b+=!~a.indexOf(String.fromCharCode(i));alert(!b)? \$\endgroup\$ – lirtosiast Dec 11 '15 at 1:40
  • \$\begingroup\$ Wow. That's even shorter than what I just did. \$\endgroup\$ – SuperJedi224 Dec 11 '15 at 1:50
3
\$\begingroup\$

05AB1E, 4 bytes (Probably Non-competing)

lêAå

Try it online!

l    # Push lowercase input.
 ê   # Push sorted, uniquified lowercase input.
  A  # Push lowercase alphabet.
   å # Is lowercase alphabet in sorted, uniquified, lowercase input?
     # True if panagram, false if not.
\$\endgroup\$
3
\$\begingroup\$

2sable, 6 5 bytes

6 byte version:

AIl-g_

Try it online!

Explanation:

A        Push alphabet
 Il      Push lowercase input
   -     Remove all chars of input from alphabet
    g    Get length of the remainder
     _   Print negative bool, where length < 1 = 1 (true), length > 0 = 0 (false)

5 byte version, inspired by carusocomputing's 05AB1E answer:

lÙ{Aå

Try it online!

Explanation:

l        Push lowercase input
 Ù{      Push sorted uniquified input
   A     Push alphabet
    å    Is alphabet in sorted, uniquified input?
\$\endgroup\$
3
\$\begingroup\$

Brachylog, 4 bytes

ḷo⊇Ạ

Try it online!

        The input
ḷ       lowercased
 o      sorted
  ⊇     is a superlist of
   Ạ    the lowercase alphabet.
\$\endgroup\$
2
\$\begingroup\$

TeaScript, 12 bytes

Sz.e»xL.I(l©

First TeaScript post since I killed TeaScript :p

Try it online

Ungolfed

Sz.e(#xL.I(l))

Sz   // Lower case alphabet
.e(#   // Loop through alphabet, ensure
       // for every character, below returns true
    xL    // Input lowercased
    .I(l) // Checks if above contains current char
)
\$\endgroup\$
  • 1
    \$\begingroup\$ ;-; I feel bad now. TBH I like TeaScript the most. \$\endgroup\$ – Conor O'Brien Dec 10 '15 at 19:24
2
\$\begingroup\$

JavaScript ES6, 124 114 113 bytes

I'm sure this can be golfed more.

v=(Q,s=[...Array(26)].map((x,i)=>String.fromCharCode(i+97)))=>s.length-1?Q.search(RegExp(s.pop(),"i"))+1&&v(Q,s):1

Generates an anonymous function.

v=(Q,s=[...Array(26)].map((x,i)=>String.fromCharCode(i+97)))=>s.length-1?Q.search(RegExp(s.pop(),"i"))+1&&v(Q,s):1

alert(v(prompt("Enter pangram:")));

\$\endgroup\$
  • \$\begingroup\$ @apsillers I think I found the problem. Please test it again (my browser does not support ES6 atm) \$\endgroup\$ – Conor O'Brien Dec 10 '15 at 19:21
  • \$\begingroup\$ Yep, looks good now! \$\endgroup\$ – apsillers Dec 10 '15 at 19:30
2
\$\begingroup\$

C, 107 bytes

#include<string.h>
int p(char*i){int a=64;while(++a<91)if(!strchr(i,a)&!strchr(i,a+32))return 0;return 1;}
\$\endgroup\$
2
\$\begingroup\$

ES6, 68 bytes

s=>[..."abcdefghijklmnopqrstuvwxyz"].every(x=>RegExp(x,"i").test(s))

That string looks awfully wasteful, but I don't know any better way.

\$\endgroup\$
  • \$\begingroup\$ Maybe using a range of charcodes? \$\endgroup\$ – Cyoce Dec 12 '15 at 8:51
  • \$\begingroup\$ @Cyoce That got me thinking and I tried a range of base 36 digits but so far it still takes 70 bytes: s=>[...Array(x=9,26)].every(z=>RegExp((++x).toString(36),"i").test(s)) \$\endgroup\$ – Neil Dec 13 '15 at 0:29
2
\$\begingroup\$

Scala, 59 48 46 bytes

print(('a'to'z'diff(readLine.map(_|32)))==Nil)
\$\endgroup\$
  • \$\begingroup\$ Using 32| rather than _|32 will (yield a warning but) shave off one more byte \$\endgroup\$ – Jacob May 17 '16 at 14:48
2
\$\begingroup\$

Bash, 45 42 bytes

41 byte program, plus 1 because it must be invoked with bash -e:

for i in {a..z}
{ [ ${1//[^$i${i^}]} ]
}

Amazingly, I managed a Bash answer with no quote characters! (yes, I checked with inputs beginning with -f and the like).

This assumes a locale where the lower-case English letters are contiguous from a to z. Input is via the first argument to the program.

The way this works is, for each alphabetic letter $i, we test whether the string contains $i or its upper-case equivalent ${i^} by removing all other characters. If this results in the empty string, then the input did not contain that letter, and we exit with 1 (false). If we have a non-empty result, then we passed the test and move on to the next letter. If the input string contains every English letter, we will reach the end of the program, thus exiting with 0 (true).

\$\endgroup\$
2
\$\begingroup\$

Perl 5, 33 bytes

$i=<>;map$=*=$i=~/$_/i,a..z;say$=
\$\endgroup\$
  • \$\begingroup\$ For perl <5.10 -pl61e '$i=$_;map$\*=$i=~/$_/i,a..z}{'. \$\endgroup\$ – Denis Ibaev May 17 '16 at 8:52
2
\$\begingroup\$

PlatyPar, 14 bytes

'a'z_,X,F(x;l!

Explanation (stack visualizer feature coming soon!):

               ## Implicit: push the input (as a string) to the stack
'a'z_          ## Push the range of a-z (the alphabet) to the stack
     ,X        ## Invert stack, expand input string into individual characters
       ,       ## Invert again
        F  ;   ## Fold (While stack.length > 1)
         (      ## Rotate left, moving the first letter of the input string to the top
          x     ## remove any occurences of that letter from the alphabet array
            l! ## Negate the length of the array, so if there's nothing left
               ## output true, else output false

If I had a ridiculous "push all letters of the alphabet" function this would be 10...

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Pyke, 6 bytes

l1GR-!

Try it here!

l1     -   input().lower()
  G -  -  set_difference(alphabet,^)
     ! - not ^
\$\endgroup\$

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.