We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.

public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
Set<Character> set = convertToSet(scan.next());
for(int i=1; i<t ;i++){
set.retainAll(convertToSet(scan.next()));
}
System.out.print(set.size());
}
public static Set<Character> convertToSet(String s) {
Set<Character> set = new HashSet<Character>(26);
for (char c : s.toCharArray())
set.add(Character.valueOf(c));
return set;
}

Very elegant solution, one small note just to catch an edge case, if the user enters 0 for the first input, you will still be trying to initalize your first set by calling scan.next() but that will throw an error if they don't enter any strings. I would do a check:
if (t>0) {.........} to account for this special case. But other than that, beautiful solution.

I didn't clearly understand your question. If you are asking how I reached one liner, then that's exactly what's written in Elaborated version : the variables in 2nd and 3rd lines are replaced by their values in 1st and 2nd lines respectively, to get a single line. Let me know if I misunderstood your question though.

Actually I am new to Python, and it is difficult to understand what is your logic in this one line of code. Can you please elaboratoly explain it, including of course the usage of the built-ins you have used in python.

Okay. As such, the only built-in used here, is "set". set() function forms a mathematical type of set and removes all the duplicate elements. Similarly, set.intersection() takes intersection of all the sets (as in mathematical context). Please have a look at the docs and tutorial for better understanding.

The logic is to form a set corresponding to each "rock" by removing the duplicate "gems". So, each set will have every gem present in rock, exactly once. Now, we just need to find the common gems in each set, which is basically equivalent to finding intersection of all sets mathematically. Thus, set.intersection gives the list of the "gems" present in each rock. The result just requires the count of gems, hence, length of above result is printed as answer.

Much nicer than what I did originally in python, but I'm pretty new still! Though this question has 1 <= N <= 100, if N could be much larger, it would be better not to save the entire list in memory, albeit temorarily. It's longer, but stores much less. Just thought I'd share. :D

n = int(raw_input())
intersection_chars = set(raw_input())
for _ in range(n-1):
rock = set(raw_input())
intersection_chars.intersection_update(rock)

console.log(// A JavaScript Set only allows distinct entries so we avoid duplicates.// Also, converting to lowercase means we can ignore case when doing matching.newSet(input.toLowerCase()// Split input by newline.split('\n')// Extract a subarray which ignores index 0: each line = one rock.slice(1)// For each rock, convert to an array of elements.map(rock=>rock.split(''))// Now an array of arrays [ [ 'A', 'B' ], [ 'C', 'D' ] ]// Iterate through all 'inner' arrays in 'outer' array.// For each 'inner' array we will create a new array which contains only those items which are in both the current and previous 'inner' arrays.// This new array becomes the input for the next iteration.// See function breakout below....reduce(keepOnlyItemsWhichAreInBothArrays)// Return the size of the new Set. We know each element will only be counted once because they're all lowercase and Set only allows distinct entries).size);// Reduce function//// Walkthrough://// for array [ // [ 'A', 'B' ], // [ 'B', 'C' ], // [ 'B', 'E' ] // ]// Iteration 1 compares: [ 'A', 'B' ], [ 'B', 'C' ]// Iteration 1 results in new array [ 'B' ]// Iteration 2 compares: [ 'B' ], [ 'B', 'E' ]// Iteration 2 results in new array [ 'B' ]// Function returns [ 'B' ]functionkeepOnlyItemsWhichAreInBothArrays(prev,curr){// Returns true if 'element' is in 'prev'.functionisInPreviousArray(element){returnprev.includes(element);}// Create new array out of items which return true for the function above.returncurr.filter(isInPreviousArray);}

Sure it's short but I'm not sure if creating a set/map in this case will actually run fast. I suggest just operating on array of 26 bools/ints instead.

importsysdefrstripped(fh):forlineinfh:yieldline.rstrip()next(sys.stdin)# Ignore first lineclean_stdin=rstripped(sys.stdin)gemstones=set(next(clean_stdin))forlineinclean_stdin:gemstones.intersection_update(list(line))print(len(gemstones))

It is used for unpacking the list. As per syntax, set.intersection() takes multiple sets as input and gives intersection of all of them as result.

The line gems = set.intersection(*rocks) is equivalent to writing :
gems = set.intersection(rocks[0],rocks[1],...,rocks[N-1]) with "..." replaced by proper values. But, since number of rocks is arbitrary it can't be coded this way.

Thus, * operators makes implementation a lot convenient here. Still, there can be several alternate ways. Statement gems = set.intersection(*rocks) can be replaced by following code :

## Gemstones

You are viewing a single comment's thread. Return to all comments →

One liner in python :

Elaborated version :

ha! that's exactly what i did (in c#, though)...

damn son , you're good :D

LOL you called him son. But hell spongman is definitely good. But One liners or Python in general feels like cheating.

JAVA SOLUTION: retainALL is the key :)

can HashSet length be 26 instead of s.length()?

Yes, HashLength should be 26 for this question. Edited :)

That would still make the HashSet resize once after 19 elements due to the default loadFactor being 0.75.

Even works without giving hashset length . So doesn't need to give capacity .

Scanner in =new Scanner(System.in); int n=in.nextInt(); int result=0; String s[]=new String[n]; for(int i=0; i

cool.. in my mind also come retainAll method.. ;)

will you please explain me .

Very elegant solution, one small note just to catch an edge case, if the user enters 0 for the first input, you will still be trying to initalize your first set by calling scan.next() but that will throw an error if they don't enter any strings. I would do a check: if (t>0) {.........} to account for this special case. But other than that, beautiful solution.

Very neat!

i got it!

I did't know about java retainAll method.....thanks for share. Sir,

set.add(c)working good then why u useset.add(Character.valueOf(c))??awesome dude...marvelous,hatsoff dude.

in Java 8:

Great solution!

cool

Could you please explain. Thanks in advance.

could be replaced with

Or use a real functional language! ;-) This is the Haskell version:

haha mine was identical, came here to post it! Love python one-liners!

Yeah ! Python oversimplifies things at times :)

lol, im sure anyone decent at python solved it with the same one-liner in under 2 minutes.. Easy problem! :)

Can you please explain the concept of doing this in Python. I am a bit confused.

I didn't clearly understand your question. If you are asking how I reached one liner, then that's exactly what's written in

Elaborated version: the variables in 2nd and 3rd lines are replaced by their values in 1st and 2nd lines respectively, to get a single line. Let me know if I misunderstood your question though.Actually I am new to Python, and it is difficult to understand what is your logic in this one line of code. Can you please elaboratoly explain it, including of course the usage of the built-ins you have used in python.

Okay. As such, the only built-in used here, is "set".

set()function forms amathematicaltype ofsetand removes all the duplicate elements. Similarly,set.intersection()takes intersection of all the sets (as in mathematical context). Please have a look at the docs and tutorial for better understanding.The logic is to form a set corresponding to each "rock" by removing the duplicate "gems". So, each set will have every gem present in rock, exactly once. Now, we just need to find the common gems in each set, which is basically equivalent to finding

intersection of all setsmathematically. Thus,set.intersectiongives the list of the "gems" present in each rock. The result just requires the count of gems, hence, length of above result is printed as answer.Thanks. Now I got it finally.

Its pretty elegant even in a 6 line Python solution, you should have no problem reading this:

You don't need to convert each input into a set, since the intersection method takes any iterable as an argument.

uhmm.. no

Much nicer than what I did originally in python, but I'm pretty new still! Though this question has 1 <= N <= 100, if N could be much larger, it would be better not to save the entire list in memory, albeit temorarily. It's longer, but stores much less. Just thought I'd share. :D

n = int(raw_input()) intersection_chars = set(raw_input()) for _ in range(n-1): rock = set(raw_input()) intersection_chars.intersection_update(rock)

print len(inters_chars)

I guess this is the best way to do it. Although I would go the long way than the oneliner approach - makes the code much more readable. :D

One line in ES6 JavaScript:

Not as minimal as Python but it's getting there :)

This is great! Any chance you can break it down a bit for us new to functional programming? Thanks!

Sure:

awesome, thank you for the clarification!! much neater than my solution!

How are you reading the input?

Sure it's short but I'm not sure if creating a set/map in this case will actually run fast. I suggest just operating on array of 26 bools/ints instead.

Agreed. I just saw the one-line-python version and got jealous :) For performance the 26 bools kills it.

Here's a more memory efficient version:

Essentially the same thing in Ruby

although I prefer using Set here which makes it two lines:

Can someone explain the * in the *rocks? Thanks.

It is used for unpacking the list. As per syntax,

`set.intersection()`

takes multiple sets as input and gives intersection of all of them as result.The line

`gems = set.intersection(*rocks)`

is equivalent to writing :`gems = set.intersection(rocks[0],rocks[1],...,rocks[N-1])`

with "..." replaced by proper values. But, since number of rocks is arbitrary it can't be coded this way.Thus, * operators makes implementation a lot convenient here. Still, there can be several alternate ways. Statement

`gems = set.intersection(*rocks)`

can be replaced by following code :Thanks

can you explain the meaning of (*rocks)

Already explained here !

General solution for any language. Without using any librery framework https://www.hackerrank.com/challenges/gem-stones/forum/comments/487346

or even better

C++ solution :

I'm so glad I don't ever have to write C++ any more! :-D

You have no idea how those Python one-liners make us feel dude XD