## Pangrams

Sort 894 Discussions, By:

using python feels like cheating :)

Absolutely! One line solution :D

[deleted]
• RT

What is the one line solution?

I can't offer you a one-liner, but these two lines will do fine:

from collections import Counter
print("pangram" if len(Counter(input().lower())) == 27 else "not pangram")


Pretty cool, but it fails if there's any other characters in the string (hyphens, commas, etc.) or if there's no space (like if the string was just the alphabet).

• Odiumediae + 1 comment

Yep. But that's not the case, as the problem description clearly states.

• lidiamcfreitas + 1 comment

the problem description says " it may contain spaces, lower case and upper case letters. Lower-case and upper-case instances of a letter are considered the same." it doesn't necessarily mean that you need to have spaces :p

Yes, I suppose strictly speaking you're right. However:

Pangrams are sentences constructed by using every letter of the alphabet at least once.


It's very unlikely that a sentence has only one word that contains all letters of the alphabet at least once. ;p

another python one-liner:

print("pangram") if len(set([i.lower() for i in input().strip()]) & set("abcdefghijklmnopqrstuvwxyz")) == 26  else print("not pangram")


what is set("abcdefghijklmnopqrstuvwxyz")) == 26 supposed to do? I did it through set too like this.

import string
s = raw_input().strip().lower()
for i in string.whitespace + string.punctuation:
if i in s:
s = s.replace(i, '')
if len(set(s)) == 26:
print "pangram"
else:
print "not pangram"

• john63 + 1 comment
len(set([i.lower() for i in input().strip()]) & set("abcdefghijklmnopqrstuvwxyz")) == 26


It is checking to see whether the intersection of the input matches characters a-z.

• F
friendsdivya + 1 comment

set may have more than 26 characters if the string has other special characters in it

The set of the characters from the input, yes. The intersection, though, cannot.

I used a set too:

ALPHABET_SIZE = 26

chars = set(input().lower().replace(' ', ''))

if len(chars) == ALPHABET_SIZE:
print('pangram')
else:
print('not pangram')

• john63 + 1 comment

not sure why the downvotes as this works.

• DB

downvotes for typing out the alphabet

I wrote a python one-liner too, but the code became a bit hard to understand so I wrote one in perl instead.

$_=<>,$_=join('',sort/\w/g),s/(.)\1+/\1/ig,print'not 'x(26>length).'pangram'


can you please explain the one liner code?

• kevinmathis08 + 1 comment

Well then all you would need to do is .replace() any of your special chars with nothing. See my edited solution, I removed all spaces.

from collections import Counter
print("pangram" if len(Counter(input().lower().replace(' ',''))) == 26 else "not pangram")

• pfcoperez + 1 comment

Or filter out space characters in the string:

filter(lambda x: x != ' ', input().lower())

• FC

x.isalpha would be better in situations of all special characters but of course in this case, space is perfectly fine.

• JK
private static boolean checkTect(String text) {

int numberOfCharacters = 26;
Set<String> characters = new HashSet<>();

String regexp = "[a-zA-Z]";
Pattern pattern = Pattern.compile(regexp);
Matcher matcher = pattern.matcher(text);

int index = 0;
boolean foundAll = false;

while (matcher.find() && !foundAll) {
String s = matcher.group().toLowerCase();
if (characters.size() == numberOfCharacters) {
foundAll = true;
}
index++;
}

return foundAll;
}


That's way more complex than it needs to be. Try this. This can be optimized even more but I'm a lazy man. Lazy men dont optimize once we pass all test cases.

Scanner in=new Scanner(System.in);
String s=in.nextLine();
int letters[]=new int[26];
boolean flag=true;
s=s.toLowerCase();
for(int i=0;i<s.length();i++)
{
if(s.charAt(i)!=' ')
letters[s.charAt(i)-'a']++;
}
for(int i=0;i<26;i++)
{
if(letters[i]<1)
{
flag=false;
System.out.print("not pangram");
break;
}
}
if(flag)
{
System.out.print("pangram");
}


Here is my solution:

public class Solution {
public static void main(String args[] ) throws Exception {
/* Enter your code here. Read input from STDIN. Print    output to STDOUT */
Scanner scn = new Scanner(System.in);
String s = scn.nextLine();
Set<Character> setValue = new HashSet<Character>();

String replaced = s.replaceAll(" ","").toLowerCase();
for(int i = 0; i<replaced.length(); i++)
{
}

if(seValue.size() == 26)
{
System.out.print("pangram");
}
else
{
System.out.print("not pangram");
}
}


}

• AA

Good One

• MD

I could only understand this one

Awesome trick...

• EH
rufoslk + 1 comment

I used this code

Scanner scanner = new Scanner(System.in);
String sentence = scanner.nextLine();
int count = 0;
sentence = sentence.toLowerCase();

//System.out.println(sentence.replaceAll("a",""));
for (char ch = 'a'; ch <= 'z'; ch++) {
if (sentence.contains(Character.toString(ch))) {
count++;
}
}

if (count>=26){
System.out.println ("pangram");
}else{
System.out.println ("not pangram");
}

• MS
mariojsanchez15 + 1 comment

If I am not mistaken the complexity of your algorithm would be O( N^2 ). Given the fact that in a data structure up to 26 characters would be stored I would suggest maybe using a hashset so it may run in O( N ). Overall, I liked your different approach.

• JR

Thanks for the input. I will look into hashset to solve this problem

• jasanign + 1 comment
import java.util.*;

public class Solution {
public static void main(String args[] ) throws Exception {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
sc.close();
String all = "abcdefghijklmnopqrstuvwxyz";
String test = "";
for(int i = 0; i < s.length(); i++){
test = (""+s.charAt(i)).toLowerCase();
if(all.contains(test)){
//System.out.println(test);
all = all.replace(test,"");
//System.out.println(all);
if(all.isEmpty()){
System.out.println("pangram");
break;
}
}
}
if(!all.isEmpty()){
System.out.println("not pangram");
}
}
}

• pandeynandancse + 1 comment

nice solution

• MD

Simple solution

[deleted]
• JR

Still entirely too complex for a lazy person :D

When foundAll becomes true break the while loop. This would significantly reduce the number of iterations.

The perfect solution is here, that will work also in case of using other character in string(hyphens,commas,etc.)

x="qwertyuiopasdfghjklzxcvbnm"
x=set(x)
if(set(input().lower()).intersection(x)==x):
print("pangram")
else:
print("not pangram")

• SS

for i in range(26): if (chr(65+i) not in s) and (chr(97+i) not in s) : print "not pangram" exit() print "pangram"

I have just started programming and chosen C++ as a language. Could you help me with the logic of your approach. Thanks in advance

• A
[deleted]
• A

create array storing characters a-z & A-Z compare with string char if match store 1 in another array check finally ur sum is 26 or not

string s; int sum =0; vector a(26,0); vector b(26); vector c(26);

for(int i=0;i<26;i++){ b[i]='a'+i;}

for(int i=0;i<26;i++){ c[i]='A'+i;}

        getline(cin,s);
for(int i=0;i<s.length();i++){
for(int j=0;j<26;j++){
if(s[i]==b[j] || s[i]==c[j]){
a[j]=1;
}
}
}

for(int i : a){
sum=sum+i;
}
if(sum==26) cout << "pangram";
else cout << "not pangram";


Here it is, essentially in C (especially in the char-to-index conversion), O(n) in the length of the input string, and somewhat optimized to avoid extra execution:

bool hasIt[26] = { false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false }; // Or use a loop, or something modern
int uniqueFound = 0; // How many distinct letters we have found
string s;
getline(cin, s);
for (string::iterator c = s.begin(); c != s.end(); c++) // <- This is C++
{
// Assume 'a' to 'z' is contiguous and 'A' to 'Z' is contiguous
int idx = -1;
if ((*c >= 'a') && (*c <= 'z'))
idx = *c - 'a';
else if ((*c >= 'A') && (*c <= 'Z'))
idx = *c - 'A';
else
continue;

// We have an alphabetic and have found its index in the alphabet
if (!hasIt[idx])
uniqueFound++;
if (uniqueFound >= 26)
break;
hasIt[idx] = true;
}

// We either found every letter, or we exhausted the input string
if (uniqueFound < 26)
cout << "not ";
cout << "pangram\n";


take only one array bt chang the string completely to upper or lower case

• MG

A simpler way to complete this problem would be to convert all the upper case letters to lower case letters. Here is my solution.

char s[1000];   fgets(s,1000,stdin);
for(int i=0; s[i]!='\0';i++)
s[i]=tolower(s[i]); //converted to lower case
int counter=0;
for(int a=97;a<=122;a++)
{ for(int i=0; s[i]!='\0';i++)
if((int)s[i]==a) {counter++; break;} //compares the                                                       //ASCII value

}
if(counter==26) cout<<"pangram";
else cout<<"not pangram";

• bhuvan95 + 1 comment

whAt if there are two a in the string your solution get wrong

• AN

break statement is there

• NB
balyan + 1 comment

I don't think it is an optimal solution since it takes O(n2) time.

• AG
int main()
{
vector<int>table(26,0);
int lettersUsed = 0;
string s;
getline(cin, s);
for(char ch:s)
{
if(ch != ' ')
{
if(isupper(ch))
ch = tolower(ch);
if(table[ch%97] == 0)
{
table[ch%97]++;
lettersUsed++;
}
}
}
if(lettersUsed == 26)
cout << "pangram";
else
cout << "not pangram";
return 0;
}


Hey, man would you mind telling me why you had used vector table(26,0)

Yes, that would have been the modern idiom :-) Except for the iterator, I was essentially writing old-school C. (I was considering using a 32-bit int as a bitmap, but that would add obfuscation more than efficiency.)

because it represent one dimensinal array of length 26. 0 is not compulasary to used if we are using 1-D array, 0 is use require when we are creating 2-D array

eg. vector table(26,3) here it means that 3 1-D array of length 26

Will this work for cases where there are characters used more than once? coz once you check if a char is present or not your code will be ignoring any further prescence of the char

And also if I use a char two times and leave out another char but if my total char are 26 your program will give a false positive

Further checking the table array for any 0 will correct your program :)

• wanghaitang_ufl + 1 comment

I took a similar approach. I used map to count the number of letters. string s; getline(cin,s);

map<char,int> letter;
for(int i=0; i<s.size(); i++)
{
if(isalpha(s.at(i)))
letter[tolower(s.at(i))]++;
}

letter.size()>=26 ? cout<<"pangram" : cout<<"not pangram";
return 0;

• S

Not passing all the test cases!

• 1L

y we are using %97 plz explain

you could also do it with only one loop here it is is java

public static void main(String[] args){
Scanner in=new Scanner(System.in);
String str=in.nextLine();
str=str.toLowerCase();
boolean isPanagram=true;
if(str.length()<26){
isPanagram=false;
}else {
boolean[] allLetters = new boolean[26];
for (int i = 0; i < allLetters.length; i++) {
allLetters[i] = false;
}
for (int i = 0; i < str.length(); i++) {
if((int)str.charAt(i)!=32) {
allLetters[(int) str.charAt(i) - 97] = true;
}
}
for (int i = 0; i < allLetters.length; i++) {
if (!allLetters[i]) {
isPanagram = false;
}
}
}
if(isPanagram){
System.out.println("pangram");
}else{
System.out.println("not pangram");
}
}


Why are you setting the allLetters variable to false? By default all boolean variable in Java are set to false.

• DS
[deleted]
• AV

Here is my java solution. It also only has one loop but it is a bit more simple.

    Scanner in = new Scanner(System.in);
String s = in.nextLine();
s = s.toLowerCase();
String hi = "abcdefghijklmnopqrstuvwxyz";
char letters[] = hi.toCharArray();
boolean isPangram = true;
for(int i =0; i<hi.length(); i++){
if(s.contains(String.valueOf(letters[i]))==false){
isPangram = false;
break;
}
}
if(isPangram){
System.out.println("pangram");
}
else{
System.out.println("not pangram");
}

• Z

wont that be O(n^2) since your calling s.contains(...) for each letter?

• DF

here is another one loop java solution: public static void main(String[] args) { Scanner scan = new Scanner(System.in); String s = scan.nextLine(); int[] a = new int[26]; int counter = 0; for (int i = 0; i < s.length(); i++) { char c = Character.toLowerCase(s.charAt(i)); int index = c - 'a'; if(index >=0 && index < 26) { if (a[index] == 0) { a[index] = 1; counter++; } } }

    String sol = counter == 26 ? "pangram" : "not pangram";
System.out.println(sol);
}

• AG

Nice way of thinking..Good Job (y)

• JW

c#

string s = Console.ReadLine().ToLower().Replace(" ", "");
int[] arr = new int[26];
for (int i = 0; (i < s.Length) && (s.Length >= 26); arr[Convert.ToInt16(s[i]) - 97]++, i++) ;
Console.WriteLine(arr.Min() > 0 ? "pangram" : "not pangram");


This doesn't take into account upper case letters though.

• SD

System.out.println(in.nextLine().replace(" ", "").toLowerCase().chars().boxed().collect(Collectors.toSet()).size() == 26 ? "pangram" : "not pangram");

Java 8. Single Line. And O(1) complexity.

what is this block of code doing actually?

for (int i = 0; i < str.length(); i++) { if((int)str.charAt(i)!=32) { allLetters[(int) str.charAt(i) - 97] = true; } 

Bro it's my solution only loop,no array:

import java.io.; import java.util.;

public class Solution {

public static boolean MyCheck(char c,String s1){
for(int i=0; i<s1.length() ; i++){
if(s1.charAt(i)==c)
return false;
}
return true ;
}

public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner scan=new Scanner(System.in) ;
String s=scan.nextLine();
int l=s.length();
s=s.toUpperCase();
int len=0,total=2015;
String newStr=" ";
for(int i=0 ; i<l ; i++){
char word=s.charAt(i) ;
int n=word ;
if((n>=65 || n<=90) && n!=32 && MyCheck(word,newStr) ){
newStr+=word ;
len++;
total=total-n ;
}
}
if(total==0 && len==26)
System.out.println("pangram");
else
System.out.println("not pangram");
}


}

• preethammessi + 1 comment

here is my java solution passed all test cases

public static void main(String args[] ) throws Exception {
Scanner t=new Scanner(System.in);
String s =t.nextLine();
StringBuilder sb=new StringBuilder(s);

Set<Character> p=new HashSet<Character>();
if(sb.length()<26){
System.out.println("not pangram ");
}
else{
for(int i=0;i<sb.length();i++)
{  char z=sb.charAt(i);

}
if(p.size()>26)
System.out.println("pangram");
else
System.out.println("not pangram");

}
}

• H
dd211094 + 1 comment

what if any special character is included in the sentence...here how its removed?

according to constraints only characters allowed are a-z,A-Z,whitespaces.

• DS
[deleted]
• DS

Much simpler version.

for(int i = 0; i < s.length(); i++) {
s.at(i) = tolower(s.at(i));
}
sort(s.begin(), s.end());
s.erase(unique(s.begin(), s.end()), s.end());
s.erase(s.begin());

if(s.length() == 26)
cout << "pangram" << endl;
else
cout << "not pangram" << endl;

• SS

well done bro

• SK
sonu6481 + 1 comment

s.erase(unique(s.begin(), s.end()), s.end()); ........................s.erase(s.begin());............. why we have to write two time erase() ??

• RJ

the 2nd erase removes the whitespaces

• NB

i searched and find out we can write the erasing of multiple character using this statement as well

auto last = std::unique(v.begin(), v.end());
// v now holds {1 2 3 4 5 6 7 x x x x x x}, where 'x' is indeterminate

v.erase(last, v.end());


but i am not understanding what does unique() returns any help will be highly appreciated. plz help me out.

• KY
[deleted]
• SD

Scanner in = new Scanner(System.in);

System.out.println(in.nextLine().replace(" ", "").toLowerCase().chars().boxed().collect(Collectors.toSet()).size() == 26 ? "Pangram" : "not pangram");

this code doesn't read any char after space.......after erasing size of string is showing 1 give a way to erase whitespaces

fgets(s , sizeof(s) , stdin);
int c =65,check=0;
while(c <= 90 && c>=65)
{
for(int i=0 ; i<strlen(s) ; i++)
{
if((int)s[i]==c || (int)s[i]==(c+32))
{

check++;

break;
}

}
c++;
}

if(check == 26)
cout<<"pangram";
else
cout<<"not pangram";


# include

using namespace std; int main() { string s;
getline(cin,s,'\n'); int sl,i,ele,a[27]={0},sum=0; sl=s.length(); for(i=0;i91) a[int(s[i])-97]=1; } for(i=0;i<27;i++) sum+=a[i]; if(sum==26) cout<<"pangram"; else cout<<"not pangram"; return 0; }

• AG
ashishgulati21 + 1 comment

we can directly compare the alphabets with their ASCII code values

int main() { string s; getline(cin,s);

int a_=96,A_=64;
int totalCount=0;
int alpCount=0;
int size=s.size();


for(int j=0;j<26;j++) { alpCount=0; a_++; A_++;

  for(int i=0;i<size;i++)
{
if(s[i]==a_|| s[i]==A_)
{
alpCount++;

}
}
if(alpCount>=1)
{
totalCount++;

}

}
if(totalCount==26)
cout<<"pangram";
else
cout<<"not pangram";
return 0;


}

Can u pls tell me the logic behind this?

• EM

int main() { string s;

// New ---
getline(cin, s);

bool isAPangram = true;
string alphabet = "abcdefghijklmnopqrstuvwxyz";

// New ---
isAPangram = std::all_of(alphabet.begin(), alphabet.end(),
[s](char i){
char upperCase = toupper(i);
bool hasLetter = count(s.begin(), s.end(),i)>0;
hasLetter |= count(s.begin(), s.end(),upperCase)>0;
//cout <<i<<hasLetter;
return hasLetter;});

if (isAPangram)
{
cout<<"pangram";
}
else{
cout<<"not pangram";
}
return 0;


} ​

• SG

(C++) This is technically this is O(n*m) where n is the number of words and m is the size of the word. This would mean n*m is the number of charcters in the line, so this is O(n). You also don't need to do weird stuff to toss out the whitespace like you would if you saved a string with getline.

    // a is index 0, b is index 1, ... etc
// we use this to check if it was used in the line
bool alphabet[26] = {false};

string word;
while(cin >> word) { // let cin ignore whitespace
for(int i = 0; i < word.length(); i++){
// this will give the an index between 0 and 25
int position = tolower(word[i]) - 'a';
alphabet[position] = true;
}
}

for(int i = 0; i < 26; i++) {
// if there was a letter not included
if(!alphabet[i]) {
cout << "not pangram" << endl;
return 0;
}
}

cout << "pangram" << endl;
return 0;

Here is a solution with less loops

set<int> set{};
string s{};

while (cin >> s) {
for (auto c : s) {
set.insert(tolower(c));
}
}

if (set.size() == 26) {
cout << "pangram";
} else {
cout << "not pangram";
}

• satyajitsql + 1 comment

how this will work , if a string contains numerals or other characters??

• SD

the problem statement says it is only alphabets and space.

• SC
[deleted]
• pulkit2728 + 1 comment

can you tell me if using sets could prove to be helpful in this case ?

• MG

you can use sets i suppose. The way I understand what you are trying to do is to store every unique instance of the letter in a set right?
Personally, though sets might seem easier for this problem, i would suggest using sets when you have large sets of values and you want that strict time limit of log N. For this problem though, i wanted a simple algorithm because that makes error finding that much easier. Happy coding :)

• MI
[deleted]

and if exits white space? or just count letters

• AV
abherc + 1 comment

import java.io.; import java.util.; import java.text.; import java.math.; import java.util.regex.*;

public class Solution {

public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner sc=new Scanner(System.in);//set doesnt differentiate betrween lower and upper case.
Set<Character> myset=new HashSet<Character>();
while(sc.hasNext()){
String str=sc.next().toLowerCase();
int len=str.length();
for(int i=0;i<str.length();i++ ){

}

}
//  System.out.println(myset);
int size=myset.size();
if(size==26){
System.out.println("pangram");
}
else{
System.out.println("not pangram");
}
}


}

• warwattik + 1 comment
[deleted]
• AV

dint get u??the example which you gavce is a pangram and my code also gives the same output..!!.plz elaborate..according to the question each letter should be present at least once..not only once!!

• DJ

you can make it one line by using set instead of Counter. When using set you need not import anything (in Python 3)...

A variation on what everyone else has done. I don't feel half as smart now.

print('pangram' if len({c.lower() for c in input() if c.isalpha()}) == 26 else 'not pangram')


I agree this is "cheating" because what would I do if all those helpful functions weren't available? Still fun though.

This code works...

print("pangram" if len(set(input().replace(" ","").upper()))==26 else "not pangram")


Question : why did you use Counter instead of Set ?

• SA

"We promptly judged antaque ivory buckles for the next prize"

Can you test the above sentence with your code?

• DK

Here is one-liner:

print('pangram' if set([ord(letter) for letter in ''.join(input().lower().strip().split())]) == set(list(range(97, 123))) else 'not pangram')

Nice one!

• JF

I'm new to python and am trying to understand the above line. I follow everying other than the '' before.join. what specificially is that part of the code contributing? Thanks.

mine is

print('pangram' if len(set(str.lower(input()))) == 27 else 'not pangram'


Definitely short and better than mine. Using set is actually better than importing anything. Nice!

• NM
nawin918 + 1 comment

I dont think its right! Question says it may contain upper case and lower case which may be repeatitions ("atleast once"). So, ideally the count may be any number more than or equal to 26.

[deleted]

I put this into two lines for readability, but you could do something like:

print("pangram" if len({char.lower() for char in input() if char.isalpha()}) == 26 else "not pangram")


List comprehension is fun.

• PC

Here's one:

print("pangram" if sum(set(map(ord,map(str.lower,[c for c in "".join(raw_input().split(" "))])))) == 2847 else "not pangram")

Python 2 one liner
print ('pangram' if len(set(''.join(raw_input().lower().split())))==26 else 'not pangram')

• I

3 lines for me:

s = raw_input().strip()

s = set(filter(lambda x: x.isalpha(), s.lower()))

print 'pangram' if len(s) == 26 else 'not pangram'

[deleted]
• VS

https://www.hackerrank.com/challenges/pangrams/submissions/code/38213079

print('pangram' if (len(list(set((input().lower()))))) == 27 else 'not pangram')

print(['not pangram','pangram'][len(set(input().lower())) == 27])

• KC

Regex works wonders:

print ('pangram' if ''.join(sorted(set(re.findall(r'[a-z]', input().strip().lower())))) == 'abcdefghijklmnopqrstuvwxyz' else "not pangram")


s=raw_input() l=len(s) if l>=1 and l<=1000: sen=list(s) a=list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') f=0 c=0 for i in range(52): for j in range(l): if a[i]==sen[j]: f=1 elif a[i]!=sen[j]: c=1 if f==1 and c==0: print "pangram" elif c==1: print "not pangram" wats wrong in my code ??? my test case 0 is faling

• G

lower case, only lower case

• R

there is a case what if repeated charecter comes...?

C solution:

int main() {

char s[1000];
while (scanf("%s", &s[strlen(s)]) == 1);
char big[26] = {0};
char small[26] = {0};
for (int i = 0; i < strlen(s); i++) {
if (s[i] >= 'a' && s[i] <= 'z') {
small[s[i] - 'a'] = 1;
}
else if (s[i] >= 'A' && s[i] <= 'Z') {
big[s[i] - 'A'] = 1;
}
}

for (int i = 0; i < 26; i++) {
if (!(big[i] == 1 || small[i] == 1)) {
printf("not pangram");
return 0;
}
}

printf("pangram");

return 0;
}

• santhoshkumar5 + 1 comment

Awsome bro

• santhoshkumar5 + 1 comment

int main() {

/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int s[26]={0},c[26]={0},i,n;
char str[1000];
scanf("%s",str);
n=strlen(str);
for(i=0;i<n;i++)
{
if(str[i]>='a' && str[i]<='z')
s[str[i]-'a']++;
else if(str[i]>='A' && str[i]<='Z')
c[str[i]-'A']++;
}

for(i=0;i<26;i++)
{
if(!(s[i]==1 && c[i]==1))
printf("not pangram");
return 0;
}
printf("pangram");
return 0;


}

• BG
bhushan017 + 1 comment

scanf("%s",str); This statement will not be able to scan the entire string. if(!(s[i]==1 && c[i]==1)) you need to use '||'

bhuskhan017 it's also not working bcz according to condition there is clearly told that atleast one letter should be(it may be upper or lower case) but here if(!(s[i]==1 || c[i]==1)) means all lower case letter must be include or all upper case must be....

I used gets() function in place in which you used scanf() inside while(). It is giving me a problem "abort called" for the last two test cases. can you help me with this.

• AK

gets is not allowed on this plateform..everything is taken from STDIN

• G

I'm getting something similar my code works except for big strings. I'm using getline. do i have to use scanf ?

• CG

then how are we supposed to counter that? we cannot use scanf() because that will stop scanning at a whitespace right?

gets is deprecated. Please use fgets with 'stdin' as the FILE *

• AN

increase the array size to A[10000] .I was getting the same error for last 2 cases

while (scanf("%s", &s[strlen(s)]) == 1);

• 7Nikhil + 1 comment

please explain me this line: while (scanf("%s", &s[strlen(s)]) == 1);

scanf returns 1 if you keep giving inputs......so it will take the inputs whenever you enter it ....

• PK

int main() {

string s;
char small[26]={0};
char big[26]={0};

for(int i=0; i<s.length(); i++)
{
if (s[i] >= 'a' && s[i] <= 'z') {
small[s[i] - 'a'] = 1;

}
else if (s[i] >= 'A' && s[i] <= 'Z') {
big[s[i] - 'A'] = 1;

}
}

for(int i=0; i<26; i++)
{
if(!(big[i]==1 || small[i]==1))
{
cout << "not pangram";
return 0;
}
}

cout << "pangram";
return 0;


}

for all the test cases its returning "not pangram".Can you plz help ??

• PK
[deleted]
• VE
efimenko + 1 comment

You're checking an empty string in your code and it is not a pangram.

• PK
khanna_pankaj + 1 comment

why is it empty ? where am i doing it wrong ?

• VE
efimenko + 1 comment

You do not read test data from input stream. That's why an instance of string s is always empty.

• SS

lol

• RK
kurrey007 + 1 comment

You know what!!!! its taking input only first word. That's why for every test case you are getting 'We' as input String not the whole statement as input. if you debug your input you will come to know that.

strins s; getline(cin,s); //you are not using this

• AU
[deleted]
• AU
[deleted]

I originally implemented it this way, then I realized the comparisons are not really needed. The program just needs to figure out if it has touched every letter in the alphabet, and can do with a simple integer array that is incremented as the ASCII values are found:

int main() {
int alpha[26] = {0};
int offset = 0;
char input[1024] = {0};
fgets(input, 1024, stdin);

for ( int i=0; input[i] != '\0'; i++) {
if ( input[i] > 96 && input [i] < 123 ) {
offset = input[i] - 97;
alpha[offset] = 1;
} else if ( input[i] > 64 && input[i] < 91 ) {
offset = input[i] - 65;
alpha[offset]= 1;
}
}
for ( int i=0; i < 26; i++) {
if ( alpha[i] == 0 ) {
printf("not pangram\n");
return 0;
}
}
printf("pangram\n");

return 0;
}

• AA

string s;
getline(cin, s);

for(int i = 0, len = s.size(); i != len; ++i) {
if(s[i] == ' ') continue;
mask |= 1 << (s[i] >= 'a' && s[i] <= 'z' ? s[i] - 'a' : s[i] - 'A');
}

cout << (mask ^ ((1 << 26) - 1) ? "not pangram" : "pangram") << endl;

• MC

It's the best solution. Congratulation

• ZG
ZenMonitor + 1 comment

While you're playing with bits, you don't have to do the comparisons:

mask |= 1 << (s[i] & 0x1F) - 1;
• AA

You are right. But now it's too hard to read and trace.

• KA

getting compile error with ur code

• RG

C with bitwise operators:

https://www.hackerrank.com/challenges/pangrams/submissions/code/20791918


I'm curious is there an advantage to use this

for (int i = 0; i < strlen(s); i++) {
if (s[i] >= 'a' && s[i] <= 'z') {
small[s[i] - 'a'] = 1;
}
else if (s[i] >= 'A' && s[i] <= 'Z') {
big[s[i] - 'A'] = 1;
}
}


vs

for (int i = 0; i < strlen(s); i++) {
if (tolower(s[i]) >= 'a' && s[i] <= 'z') {
small[tolower(s[i]) - 'a'] = 1;
}
}

• TT

smaller C solution int main() {

/* Enter your code here. Read input from STDIN. Print output to STDOUT */
char c;
int a[26]={0},i;
while(scanf("%c",&c)==1)
{
if(c>=65&&c<=90)
{a[c-65]++;}
else if(c>=97&&c<=122)
{a[c-97]++;}
}
for(i=0;i<26;i++)
{
if(a[i]==0)
break;
}
if(i==26)
printf("pangram");
else
printf("not pangram");
return 0;


}

There's no need to have two char arrays big and small. You can just have one and keep a counter, if it reaches 26, just break.

if(s[c] - 'A' < 26 && s[c] - 'A' >= 0
&& map[s[c] - 'A'] ==0) {
map[s[c] - 'A']++;
count++;
}else if(c - 'a' < 26 && s[c] - 'a' >= 0
&&  map[s[c] - 'a'] ==0) {
map[s[c] - 'a']++;
count++;
}
if(count == 26) {
System.out.println("pangram");
return;
}


I tried to run this program on devc++. It runs but gives no output. i can't understand why!

while (scanf("%s", &s[strlen(s)]) == 1); what it means exactly?

• SS
universedecoder + 1 comment

• vijay_laxmi3 + 1 comment

suppose s[i]=99 and 'a'= 97 (since the ascii code of a =97). so, small[s[i]-'a'] = small[99-97] =small[2]. i.e, if s[i]=c ( which is 3rd alphabet if u start counting from zero and its ascii code is 99) then small[2] will be computed. a better way to understand is small[0] will store entries of 'a', small[1] will store entries of 'b' and so on. Hope it's helpful!

• SS

Thank you very much for your help. I have understood that clearly

• NM

Interesting solution!

[deleted]
[deleted]

hey why you used scanf function inside while loop.I am doing the same but instead of scanning string inside while loop i am scanning ouside while loop, in doing so only one test case is running.please explain the concept.

• S

wouldnt s[i]-'a' is same as s[i]-'A'?? In that case, why do we need two separate arrays one for capital and one for lower case? Anyway for panagram, both are counted the same..

• DF
davidrossfisher + 1 comment

I do not have two arrays, only one; an array of ints which is really a boolean (this could be changed). There is no "s[i] - 'A'" in the code. All the chars are converted to lower case and then an index into the array is derived. The purpose of the array is to track which letters were used. Apologies, the code was mangled when I copied it into the the comment.

• S

My apologies.. true. I think I misplaced my comment.

crazzyyy one bro!!! amazing thinking

• MY

how bout this one?

  int chare;
char* s = (char *)malloc(512000 * sizeof(char));
int count=0;
gets(s);
for(int i=0;i<strlen(s);i++)
s[i]=tolower(s[i]);
for(chare = 97;chare<=123;chare++)
{
for(int i=0;i<strlen(s);i++){
if(s[i]==(char)chare){
count++;
break;
}
}
}
if(count>=26)
printf("pangram\n");
else
printf("not pangram\n")   ;

• AP
Promilla + 1 comment

Hi cdv20! Could you provide the solution! Mine has something like 10 lines... :D Trying to improve.

Fewer lines != improvement

• wgcrouch + 1 comment
[deleted]
• anirudhkhannacse + 1 comment
[deleted]
• wgcrouch + 1 comment

It creates a set (a standard python type https://docs.python.org/2/library/stdtypes.html#set) from the input, and compares it to a set of the alphabet.

Haha True that :D

Simple Solution in Java O(N) =D

Scanner sc = new Scanner(System.in);
String str = sc.nextLine().replace("\\s+","").toLowerCase();
BitSet b = new BitSet();

for(char c: str.toCharArray()){
if(c >='a' && c<='z'){
b.set(c-'a');
}
}
System.out.println(b.cardinality()==26?"pangram":"not pangram");


Thanks bro

BitSet sounds an interesting approach here. Thanks.

Cool approach bro! Thanks for sharing :D

• VE

So did I:

   String s = new Scanner(System.in).nextLine().toLowerCase();

int val = (1 << 26) - 1;
int res = 0;
for(int i = 0; i < s.length(); ++i){
int c = s.charAt(i) - 'a';
if(c>= 0 && c< 26)
res |= 1 << c;
}
System.out.println(val == res ? "pangram" : "not pangram");


+1

New to bit manipulation!! What does the line res |= 1 << c in your code means?

Super Boss

• SV

Thank you for sharing. Can you explain, please, why we need ( c-'a' ) ? It works as expected even b.set(c);

• NM
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
BitSet bs = new BitSet(25);

str = str.toLowerCase();
for( int i = 0; i < str.length(); i++ ) {
if( Character.isLetter(str.charAt(i)) ) {
bs.set(str.charAt(i) - 97);
}
}

if( bs.cardinality() == 26 ) {
System.out.println("pangram");
} else {
System.out.println("not pangram");
}
}


I had the same idea! Although yours is a little more efficient.

• jmxdbx + 1 comment

I love python... I used a dictionary, but still very simple, 11 lines.

• SD

I used Java 8. One line. System.out.println(in.nextLine().replace(" ", "").toLowerCase().chars().boxed().collect(Collectors.toSet()).size() == 26 ? "pangram" : "not pangram");

C# "one-liner" (aside from using/class/method declarations):

using System;
using System.Collections.Generic;
using System.IO;

class Solution {
static void Main(String[] args) {
Console.WriteLine(new HashSet<char>(Console.ReadLine().ToLower().Replace(" ", "")).Count == 26 ? "pangram" : "not pangram");
}
}


Superb :) I din know the concept of hashset. Thanks :)

• cartan + 1 comment

Or with Linq:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class Solution {
static void Main(String[] args) {
Console.WriteLine(Console.ReadLine().Where(char.IsLetter).Select(char.ToLower).Distinct().Count() == 26 ? "pangram" : "not pangram");
}
}


You can save some characters by calling ToLower() on the initial string instead of using Select:

Console.WriteLine(Console.ReadLine().ToLower().Where(Char.IsLetter).Distinct().Count() == 26 ? "pangram" : "not pangram");


and JS feels dirty

container = {};
input.toLowerCase().replace(/\s/g, '').split("").forEach(function(item){
if (!container.hasOwnProperty(item)) container[item] = true;
});
Object.keys(container).length == 26 ? console.log("pangram") : console.log("not pangram");


In Java, it's a one line solution as well...

System.out.println(word.chars().distinct().count() > 25 ? "pangram" : "not pangram");

• EJ

Yeah everytime I use it, I feel like cheating. Java's not too bad. But c++ kind of sucks some time.

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

String s = sc.nextLine();

//Coversion to Lower Case to maintain consistency.
s = s.toLowerCase();

//Making life easier.
char[] input = s.toCharArray();
Arrays.sort(input);

//To check for each alphabets existence.
byte[] checked = new byte[26];

//Initialise it for keeping a counter.
for (int i=0; i<checked.length; i++) checked[i] = 0;

//Check each letter and update the alphabets location counter
for (int i=0; i<input.length; i++) {
if ((((int)input[i])-97) > -1 && (((int)input[i])-97) < 26) {
checked[(((int)input[i])-97)] += 1;
}
}

boolean pangram = true;

//If any checking counter is less than 1, that means it is zero and the alphabet is not present.
for (int i=0; i<checked.length; i++) {
if(checked[i] < 1) {
pangram=false;
}
}

if (pangram)
System.out.println("pangram");
else System.out.println("not pangram");
}


Is this simple and easy to understand? Passes all the test though. Is this efficient?

Dont forget Ruby!

puts gets.upcase.scan(/\w/).sort.uniq.join('')=="ABCDEFGHIJKLMNOPQRSTUVWXYZ" ? "pangram" : "not pangram"

• AA

and using C feels like shit

Yep ::)

s = input()
print('pangram' if all(c in s.lower() for c in [chr(i) for i in range(ord('a'), ord('z') + 1)]) else 'not pangram')


all that matters is sex

• F

cSet = {chr(c) for c in range(97,123)} pangram = "not pangram" for c in s: cSet.discard(c.lower()) if not cSet: pangram = "pangram" break print(pangram)

Java simple code..

     Scanner sc = new Scanner(System.in);
String s= sc.nextLine();
s = s.toLowerCase();
HashSet<Integer> h = new HashSet<Integer>();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i)!=' '){
int put = (int)s.charAt(i);
}
}
if(h.size()==26)
System.out.println("pangram");
else
System.out.println("not pangram");

• AS

your code fails if we add a character other than an alphabet. Add this condition to make it fool proof

if(put>=97 && put<=122 )

ya i forgot..thanks

More generic: java.lang.Character.isAlphabetic()

• MR

one more condition for improving your algorithm
if you already got all the alphabests in the hashSet , exit from for loop.

Ex::
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i)!=' '){
int put = (int)s.charAt(i);
}
//New code :: start
if(h.size()==26) {
break;
}
//New code :: end
}

• KW

exactely what I am thinking

• CP

Using java 8 streams:

Scanner scan = new Scanner(System.in);
String s = new String( scan.nextLine() ).toLowerCase();
HashSet<Integer> h = new HashSet<Integer>();
System.out.println( (h.size()==27 ? "" :"not ")  + "pangram");

import string
print ["not pangram", "pangram"][set(string.ascii_lowercase).issubset(set(raw_input().lower()))]


It seems to be ok but I had tried with c

hey could you help me out how to enter multiple word strings using scanf

i dont know if you already figured it out, if not use fgets

• zhenyakornev + 1 comment

Try this: scanf("%[^\n]", str);

• MB

you can also use cin.getline(s, 1000) works in C++, should in C

Just to make sure I understand set() and issubset() correctly. You're basically comparing the raw_input().lower() subset to the alpha set? The results is either true or false, which dictates not pangram or pangram correct?

One line solution, the same approach:

import string; print('pangram') if not set(string.ascii_lowercase) - set(input().lower()) else print('not pangram')


This is way too easy in Ruby...the editorial solution is overly complex...

My solution in c:

# include

int main() { int a[26]={0}; int i,n,c=0; char *s=(char *)malloc(10240*sizeof(char)); scanf("%[^\n]s",s); for(i=0;s[i]!='\0';i++) { int k=s[i]; if(k>=97 && k<=122) { n=k-97; a[n]++; } else if(k>=65&&k<=91) { n=k-65; a[n]++;

    }

}
for(i=0;i<=25;i++)
{
if(a[i]!=0)
c++;
}
if(c==26)
{
printf("pangram");

}
else
printf("not pangram");

return 0;


}

• AP
rec14981a0585 + 1 comment

thanks for your code... it really helped me. :-)

• REC14981A05A2 + 1 comment

nice code! :)

brilliant approch ur code is very helpful

• Rohitha_sripathi + 1 comment
[deleted]
• RM

Anyone solve this by converting the string to a char array, sorting distinct, then adding them according to their ascii value? if exactly equals 2725 (i think it was) then contains all letters otherwise it doesnt?

Dude, there are both uppercase and lowercase letters , so you'll first need to convert the entire string to either uppercase or lowercase

• RM
rmit102 + 1 comment

Yeah i know, I did that too was just wondering if anyone else had done it that way. Only problem would be if there were numbers/other characters in the sentence I guess

• VS

using the ascii values delete all other characters other than alphabets. u ll get the result

• SB
samishbedi + 1 comment

I did it in a way similar to what you are thinking but not using their ascii value

• RM

string compare?

• HS
hfarwah + 1 comment

this would only be right for few instances. for example a=97 b=98 c=99 a+b+c=294 but also d=100, ^=94 thus d+d+^=294

• Sigi_ + 1 comment

I like the char array idea but would do it a little bit different: Make the string lower case, convert it to char array, sort it and than start from the beginning:

Check if start is 'a' and than check that every next char is bigger by one or equal to the char you testing. Than make sure that the last one is 'z'.

If there is any hole, you know that there is a letter missing.

• I_am_Nobody + 1 comment

have u written the code for the same? if yes, then please post the same! thanks :D

• Icarus_XXII + 1 comment
	import java.io.*;
import java.util.*;
import java.util.Scanner;

public class Solution {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String phrase = in.nextLine();
phrase = phrase.toLowerCase();
phrase = phrase.trim();
phrase = phrase.replaceAll("\\s+", "");
int length = phrase.length();
char [] checkAlphabet = phrase.toCharArray();
Arrays.sort(checkAlphabet);
int index = 0;
int charVal;
int nextCharVal;
if(Character.valueOf(checkAlphabet[index])==97 && length>25){
while(checkAlphabet[index]!='z' && index<=length-2){
charVal = Character.valueOf(checkAlphabet[index]);
nextCharVal = Character.valueOf(checkAlphabet[index+1]);
if(charVal == nextCharVal || charVal+1 == nextCharVal){
index++;
}
else {
System.out.println("not pangram");
return;
}
}
}
else{
System.out.println("not pangram");
return;
}
in.close();
System.out.println("pangram");
return;
}
}


GREAT CODE SIGI!! My previous one was failing number 3 for some reason. Sorry ahead of time for unreadability.

• AK
amankumarsingh11 + 1 comment

What is wrong in my method why editor in hackerrank is giving incorrect while in eclipse its correct

public static void pangaram(String s){

   Set<Character> s1= new HashSet<Character>();
for (int i=0; i<s.length(); i++){

}
s1.remove(' ');

if (s1.size()==26)
System.out.println("pangram");
else
System.out.println("not pangram");


}

• MM

Probably the remove, the string ' ' doesn't exist, you'd need to do s1.remove(' '.toCharArray()[0]) because it's a set of Character so you need to remove the char ' ' not the string ' '

I did this like you said but the correct number is 2847 (97-122 as ASCII decimal values). Of course you need to lower the string and remove extra characters and take unique array out of it but hey - they are all built-in functions in PHP :P

Java8

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
import java.lang.*;
public class Solution {
public static void main(String args[] ) throws Exception {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
Scanner in = new Scanner(System.in);
String s = in.nextLine().toLowerCase();

String smallchars="abcdefghijklmnopqrstuvwxyz";
char[] smallcharsar=smallchars.toCharArray();
boolean isPangrams=true;

for(int i=0;i<smallcharsar.length;i++){

if(s.indexOf(smallcharsar[i])>=0){
continue;
}else{

isPangrams=false;
break;
}

}

if (isPangrams){
System.out.println("pangram");
}else{
System.out.println("not pangram");
}
}
}

• PK

My Solution in Java with bit manipulation

Scanner s = new Scanner(System.in);
String text = s.nextLine();
int allLetters = Integer.parseInt("11111111111111111111111111",2);
int currentLetter = 0;
for(int i=0; i<text.length(); i++){
char c = Character.toLowerCase(text.charAt(i));
if(Character.isLowerCase(c)){
currentLetter = currentLetter | 1 << (Integer.valueOf(c-97));
if(currentLetter == allLetters){
System.out.println("pangram");
return;
}
}

}
System.out.println("not pangram");


JavaScript Solution using map

process.stdin.on("end", function () {
var map = {};
var sum = 0;
for(let i = 0; i < input.length; i ++){
var value = input[i].toLowerCase();
if(value === " ") continue;
if(map[value] !== undefined) continue;
map[value] = 1;
sum ++;
}
console.log(sum === 26 ? "pangram" : "not pangram");
});


Easy solution in c...

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>

int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
char s[1000];
scanf("%[^\n]%*c", s);
int len = strlen(s);
int a[26] = {0};
for(int i = 0; i < len; i++){
if(s[i] >= 65 && s[i] <= 90){
int j = s[i];
a[j-65]++;
}
if(s[i] >= 97 && s[i] <= 122){
int k = s[i];
a[k-97]++;
}
}
int count = 0;
for(int i = 0; i < 26; i++){
if(a[i] > 0)
count++;
}
if(count == 26)
printf("pangram");
else
printf("not pangram");
return 0;
}
`