Jewels and stones: Difference between revisions
Line 749: | Line 749: | ||
0</pre> |
0</pre> |
||
=={{header|VBA}}== |
|||
{{trans|Phix}}<lang vb>Function count_jewels(stones As String, jewels As String) As Integer |
|||
Dim res As Integer: res = 0 |
|||
For i = 1 To Len(stones) |
|||
res = res - (InStr(1, jewels, Mid(stones, i, 1), vbBinaryCompare) <> 0) |
|||
Next i |
|||
count_jewels = res |
|||
End Function |
|||
Public Sub main() |
|||
Debug.Print count_jewels("aAAbbbb", "aA") |
|||
Debug.Print count_jewels("ZZ", "z") |
|||
End Sub</lang>{{out}} |
|||
<pre> 3 |
|||
0 </pre> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
<lang zkl>fcn countJewels(a,b){ a.inCommon(b).len() }</lang> |
<lang zkl>fcn countJewels(a,b){ a.inCommon(b).len() }</lang> |
Revision as of 20:51, 15 February 2019
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Create a function which takes two string parameters: 'stones' and 'jewels' and returns an integer.
Both strings can contain any number of upper or lower case letters. However, in the case of 'jewels', all letters must be distinct.
The function should count (and return) how many 'stones' are 'jewels' or, in other words, how many letters in 'stones' are also letters in 'jewels'.
Note that:
- Only letters in the ISO basic Latin alphabet i.e. 'A to Z' or 'a to z' need be considered.
- A lower case letter is considered to be different to its upper case equivalent for this purpose i.e. 'a' != 'A'.
- The parameters do not need to have exactly the same names.
- Validating the arguments is unnecessary.
So, for example, if passed "aAAbbbb" for 'stones' and "aA" for 'jewels', the function should return 3.
This task was inspired by this problem.
ALGOL 68
<lang algol68>BEGIN
# procedure that counts the number of times the letters in jewels occur in stones # PROC count jewels = ( STRING stones, jewels )INT: BEGIN # count the occurences of each letter in stones # INT upper a pos = 0; INT lower a pos = 1 + ( ABS "Z" - ABS "A" ); [ upper a pos : lower a pos + 26 ]INT letter counts; FOR c FROM LWB letter counts TO UPB letter counts DO letter counts[ c ] := 0 OD; FOR s pos FROM LWB stones TO UPB stones DO CHAR s = stones[ s pos ]; IF s >= "A" AND s <= "Z" THEN letter counts[ upper a pos + ( ABS s - ABS "A" ) ] +:= 1 ELIF s >= "a" AND s <= "z" THEN letter counts[ lower a pos + ( ABS s - ABS "a" ) ] +:= 1 FI OD; # sum the counts of the letters that appear in jewels # INT count := 0; FOR j pos FROM LWB jewels TO UPB jewels DO CHAR j = jewels[ j pos ]; IF j >= "A" AND j <= "Z" THEN count +:= letter counts[ upper a pos + ( ABS j - ABS "A" ) ] ELIF j >= "a" AND j <= "z" THEN count +:= letter counts[ lower a pos + ( ABS j - ABS "a" ) ] FI OD; count END # count jewels # ;
print( ( count jewels( "aAAbbbb", "aA" ), newline ) ); print( ( count jewels( "ABCDEFGHIJKLMNOPQRSTUVWXYZ@abcdefghijklmnopqrstuvwxyz" , "ABCDEFGHIJKLMNOPQRSTUVWXYZ@abcdefghijklmnopqrstuvwxyz" ) , newline ) ); print( ( count jewels( "AB", "" ), newline ) ); print( ( count jewels( "ZZ", "z" ), newline ) )
END</lang>
- Output:
+3 +52 +0 +0
AppleScript
<lang applescript>-- jewelCount :: String -> String -> Int on jewelCount(jewels, stones)
set js to chars(jewels) script on |λ|(a, c) if elem(c, jewels) then a + 1 else a end if end |λ| end script foldl(result, 0, chars(stones))
end jewelCount
-- OR in terms of filter -- jewelCount :: String -> String -> Int on jewelCount2(jewels, stones)
script on |λ|(c) elem(c, jewels) end |λ| end script length of filter(result, stones)
end jewelCount2
-- TEST -------------------------------------------------- on run
unlines(map(uncurry(jewelCount), ¬ {Tuple("aA", "aAAbbbb"), Tuple("z", "ZZ")}))
end run
-- GENERIC FUNCTIONS -------------------------------------
-- Tuple (,) :: a -> b -> (a, b) on Tuple(a, b)
{type:"Tuple", |1|:a, |2|:b}
end Tuple
-- chars :: String -> [Char] on chars(s)
characters of s
end chars
-- elem :: Eq a => a -> [a] -> Bool on elem(x, xs)
considering case xs contains x end considering
end elem
-- filter :: (a -> Bool) -> [a] -> [a] on filter(f, xs)
tell mReturn(f) set lst to {} set lng to length of xs repeat with i from 1 to lng set v to item i of xs if |λ|(v, i, xs) then set end of lst to v end repeat return lst end tell
end filter
-- foldl :: (a -> b -> a) -> a -> [b] -> a on foldl(f, startValue, xs)
tell mReturn(f) set v to startValue set lng to length of xs repeat with i from 1 to lng set v to |λ|(v, item i of xs, i, xs) end repeat return v end tell
end foldl
-- map :: (a -> b) -> [a] -> [b] on map(f, xs)
tell mReturn(f) set lng to length of xs set lst to {} repeat with i from 1 to lng set end of lst to |λ|(item i of xs, i, xs) end repeat return lst end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: First-class m => (a -> b) -> m (a -> b) on mReturn(f)
if class of f is script then f else script property |λ| : f end script end if
end mReturn
-- Returns a function on a single tuple (containing 2 arguments) -- derived from an equivalent function with 2 distinct arguments -- uncurry :: (a -> b -> c) -> ((a, b) -> c) on uncurry(f)
script property mf : mReturn(f)'s |λ| on |λ|(pair) mf(|1| of pair, |2| of pair) end |λ| end script
end uncurry
-- unlines :: [String] -> String on unlines(xs)
set {dlm, my text item delimiters} to ¬ {my text item delimiters, linefeed} set str to xs as text set my text item delimiters to dlm str
end unlines</lang>
- Output:
3 0
AutoHotkey
<lang AutoHotkey>JewelsandStones(ss, jj){ for each, jewel in StrSplit(jj) for each, stone in StrSplit(ss) if (stone == jewel) num++ return num }</lang> Example:<lang AutoHotkey>MsgBox % JewelsandStones("aAAbbbbz", "aAZ") return</lang>
Outputs:
3
AWK
<lang AWK># syntax: GAWK -f JEWELS_AND_STONES.AWK BEGIN {
printf("%d\n",count("aAAbbbb","aA")) printf("%d\n",count("ZZ","z")) exit(0)
} function count(stone,jewel, i,total) {
for (i=1; i<length(stone); i++) { if (jewel ~ substr(stone,i,1)) { total++ } } return(total)
} </lang>
- Output:
3 0
C
<lang c>#include <stdio.h>
- include <string.h>
int count_jewels(const char *s, const char *j) {
int count = 0; for ( ; *s; ++s) if (strchr(j, *s)) ++count; return count;
}
int main() {
printf("%d\n", count_jewels("aAAbbbb", "aA")); printf("%d\n", count_jewels("ZZ", "z")); return 0;
}</lang>
- Output:
3 0
C++
<lang cpp>#include <algorithm>
- include <iostream>
int countJewels(const std::string& s, const std::string& j) {
int count = 0; for (char c : s) { if (j.find(c) != std::string::npos) { count++; } } return count;
}
int main() {
using namespace std;
cout << countJewels("aAAbbbb", "aA") << endl; cout << countJewels("ZZ", "z") << endl;
return 0;
}</lang>
- Output:
3 0
C#
<lang csharp>using System; using System.Linq;
public class Program {
public static void Main() { Console.WriteLine(Count("aAAbbbb", "Aa")); Console.WriteLine(Count("ZZ", "z")); }
private static int Count(string stones, string jewels) { var bag = jewels.ToHashSet(); return stones.Count(bag.Contains); }
}</lang>
- Output:
3 0
D
<lang d>import std.algorithm; import std.stdio;
int countJewels(string s, string j) {
int count; foreach (c; s) { if (j.canFind(c)) { count++; } } return count;
}
void main() {
countJewels("aAAbbbb", "aA").writeln; countJewels("ZZ", "z").writeln;
}</lang>
- Output:
3 0
Factor
<lang factor>USING: kernel prettyprint sequences ;
- count-jewels ( stones jewels -- n ) [ member? ] curry count ;
"aAAbbbb" "aA" "ZZ" "z" [ count-jewels . ] 2bi@</lang>
- Output:
3 0
Go
Four solutions are shown here. The first of two simpler solutions iterates over the stone string in an outer loop and makes repeated searches into the jewel string, incrementing a count each time it finds a stone in the jewels. The second of the simpler solutions reverses that, iterating over the jewel string in the outer loop and accumulating counts of matching stones. This solution works because we are told that all letters of the jewel string must be unique. These two solutions are simple but are both O(|j|*|s|).
The two more complex solutions are analogous to the two simpler ones but build a set or multiset as preprocessing step, replacing the inner O(n) operation with an O(1) operation. The resulting complexity in each case is O(|j|+|s|).
Outer loop stones, index into jewels: <lang go>package main
import (
"fmt" "strings"
)
func js(stones, jewels string) (n int) {
for _, b := range []byte(stones) { if strings.IndexByte(jewels, b) >= 0 { n++ } } return
}
func main() {
fmt.Println(js("aAAbbbb", "aA"))
}</lang>
- Output:
3
Outer loop jewels, count stones: <lang go>func js(stones, jewels string) (n int) {
for _, b := range []byte(jewels) { n += strings.Count(stones, string(b)) } return
}</lang>
Construct jewel set, then loop over stones: <lang go>func js(stones, jewels string) (n int) {
var jSet ['z' + 1]int for _, b := range []byte(jewels) { jSet[b] = 1 } for _, b := range []byte(stones) { n += jSet[b] } return
}</lang>
Construct stone multiset, then loop over jewels: <lang go>func js(stones, jewels string) (n int) {
var sset ['z' + 1]int for _, b := range []byte(stones) { sset[b]++ } for _, b := range []byte(jewels) { n += sset[b] } return
}</lang>
Haskell
<lang haskell>jewelCount :: String -> String -> Int jewelCount jewels =
foldr (\c -> if elem c jewels then succ else id) 0
-- TEST ----------------------------------------------
main :: IO () main = mapM_ print $
(uncurry jewelCount) <$> [ ("aA", "aAAbbbb") ,("z", "ZZ") ]</lang>
- Output:
3 0
Or in terms of filter rather than foldr
<lang haskell>jewelCount :: String -> String -> Int jewelCount jewels =
length . filter (flip elem jewels)
-- Which could be further reduced to -- jewelCount = (length .) . filter . flip elem
-- TEST ----------------------------------------------
main :: IO () main = do
print $ jewelCount "aA" "aAAbbbb" print $ jewelCount "z" "ZZ"</lang>
- Output:
3 0
Java
<lang java>import java.util.HashSet; import java.util.Set;
public class App {
private static int countJewels(String stones, String jewels) { Set<Character> bag = new HashSet<>(); for (char c : jewels.toCharArray()) { bag.add(c); }
int count = 0; for (char c : stones.toCharArray()) { if (bag.contains(c)) { count++; } }
return count; }
public static void main(String[] args) { System.out.println(countJewels("aAAbbbb", "aA")); System.out.println(countJewels("ZZ", "z")); }
}</lang>
- Output:
3 0
JavaScript
<lang javascript>(() => {
// jewelCount :: String -> String -> Int const jewelCount = (j, s) => { const js = j.split(); return s.split() .reduce((a, c) => js.includes(c) ? a + 1 : a, 0) };
// TEST ----------------------------------------------- return [ ['aA', 'aAAbbbb'], ['z', 'ZZ'] ] .map(x => jewelCount(...x))
})();</lang>
- Output:
[3, 0]
Julia
Module: <lang julia>module Jewels
count(s, j) = Base.count(x ∈ j for x in s)
end # module Jewels</lang>
Main: <lang julia>@show Jewels.count("aAAbbbb", "aA") @show Jewels.count("ZZ", "z")</lang>
- Output:
Jewels.count("aAAbbbb", "aA") = 3 Jewels.count("ZZ", "z") = 0
Kotlin
<lang scala>// Version 1.2.40
fun countJewels(s: String, j: String) = s.count { it in j }
fun main(args: Array<String>) {
println(countJewels("aAAbbbb", "aA")) println(countJewels("ZZ", "z"))
}</lang>
- Output:
3 0
Lua
<lang lua>function count_jewels(s, j)
local count = 0 for i=1,#s do local c = s:sub(i,i) if string.match(j, c) then count = count + 1 end end return count
end
print(count_jewels("aAAbbbb", "aA")) print(count_jewels("ZZ", "z"))</lang>
- Output:
3 0
Maple
<lang Maple>count_jewel := proc(stones, jewels) local count, j, letter: j := convert(jewels,set): count := 0: for letter in stones do if (member(letter, j)) then count++: end if: end do: return count: end proc: count_jewel("aAAbbbb", "aA")</lang>
- Output:
3
Modula-2
<lang modula2>MODULE Jewels; FROM FormatString IMPORT FormatString; FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
PROCEDURE WriteInt(n : INTEGER); VAR buf : ARRAY[0..15] OF CHAR; BEGIN
FormatString("%i", buf, n); WriteString(buf)
END WriteInt;
PROCEDURE CountJewels(s,j : ARRAY OF CHAR) : INTEGER; VAR c,i,k : CARDINAL; BEGIN
c :=0;
FOR i:=0 TO HIGH(s) DO FOR k:=0 TO HIGH(j) DO IF (j[k]#0C) AND (s[i]#0C) AND (j[k]=s[i]) THEN INC(c); BREAK END END END;
RETURN c
END CountJewels;
BEGIN
WriteInt(CountJewels("aAAbbbb", "aA")); WriteLn; WriteInt(CountJewels("ZZ", "z")); WriteLn;
ReadChar
END Jewels.</lang>
- Output:
3 0
Perl
<lang perl>sub count_jewels {
my( $j, $s ) = @_; my($c,%S);
$S{$_}++ for split //, $s; $c += $S{$_} for split //, $j; return "$c\n";
}
print count_jewels 'aA' , 'aAAbbbb'; print count_jewels 'z' , 'ZZ';</lang>
- Output:
3 0
Perl 6
<lang perl6>sub count-jewels ( Str $j, Str $s --> Int ) {
my %counts_of_all = $s.comb.Bag; my @jewel_list = $j.comb.unique;
return %counts_of_all ∩ @jewel_list.Bag ?? %counts_of_all{ @jewel_list }.sum !! 0;
}
say count-jewels 'aA' , 'aAAbbbb'; say count-jewels 'z' , 'ZZ';</lang>
- Output:
3 0
Phix
<lang Phix>function count_jewels(string stones, jewels)
integer res = 0 for i=1 to length(stones) do res += find(stones[i],jewels)!=0 end for return res
end function ?count_jewels("aAAbbbb","aA") ?count_jewels("ZZ","z")</lang>
- Output:
3 0
Python
<lang python>def countJewels(s, j):
return sum(x in j for x in s)
print countJewels("aAAbbbb", "aA") print countJewels("ZZ", "z")</lang>
- Output:
3 0
Python 3 Alternative
<lang python>def countJewels(stones, jewels):
jewelset = set(jewels) return sum(1 for stone in stones if stone in jewelset)
print(countJewels("aAAbbbb", "aA")) print(countJewels("ZZ", "z"))</lang>
- Output:
3 0
Racket
<lang racket>#lang racket
(define (jewels-and-stones stones jewels)
(length (filter (curryr member (string->list jewels)) (string->list stones))))
(module+ main
(jewels-and-stones "aAAbbbb" "aA") (jewels-and-stones "ZZ" "z"))
</lang>
- Output:
3 0
REXX
Programming note: a check is made so that only (Latin) letters are counted as a match. <lang rexx>/*REXX pgm counts how many letters (in the 1st string) are in common with the 2nd string*/ say count('aAAbbbb', "aA") say count('ZZ' , "z" ) exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ count: procedure; parse arg stones,jewels /*obtain the two strings specified. */
#= 0 /*initialize the variable # to zero.*/ do j=1 for length(stones) /*scan STONES for matching JEWELS chars*/ x= substr(stones, j, 1) /*obtain a character of the STONES var.*/ if datatype(x, 'M') then if pos(x, jewels)\==0 then #= # + 1 end /*j*/ /* [↑] if a letter and a match, bump #*/ return # /*return the number of common letters. */</lang>
- output when using the default inputs:
3 0
Ring
<lang ring># Project Jewels and Stones
jewels = "aA" stones = "aAAbbbb" see jewelsandstones(jewels,stones) + nl jewels = "z" stones = "ZZ" see jewelsandstones(jewels,stones) + nl
func jewelsandstones(jewels,stones)
num = 0 for n = 1 to len(stones) pos = substr(jewels,stones[n]) if pos > 0 num = num + 1 ok next return num
</lang> Output:
3 0
Ruby
<lang ruby>stones, jewels = "aAAbbbb", "aA"
stones.count(jewels) # => 3 </lang>
Scala
<lang Scala>object JewelsStones extends App {
def countJewels(s: String, j: String): Int = s.count(i => j.contains(i))
println(countJewels("aAAbbbb", "aA")) println(countJewels("ZZ", "z"))
}</lang>
- Output:
See it in running in your browser by ScalaFiddle (JavaScript) or by Scastie (JVM).
Sidef
<lang ruby>func countJewels(s, j) {
s.chars.count { |c| j.contains(c) }
}
say countJewels("aAAbbbb", "aA") #=> 3 say countJewels("ZZ", "z") #=> 0</lang>
Swift
<lang swift>func countJewels(_ stones: String, _ jewels: String) -> Int {
return stones.map({ jewels.contains($0) ? 1 : 0 }).reduce(0, +)
}
print(countJewels("aAAbbbb", "aA")) print(countJewels("ZZ", "z"))</lang>
- Output:
3 0
VBA
<lang vb>Function count_jewels(stones As String, jewels As String) As Integer
Dim res As Integer: res = 0 For i = 1 To Len(stones) res = res - (InStr(1, jewels, Mid(stones, i, 1), vbBinaryCompare) <> 0) Next i count_jewels = res
End Function Public Sub main()
Debug.Print count_jewels("aAAbbbb", "aA") Debug.Print count_jewels("ZZ", "z")
End Sub</lang>
- Output:
3 0
zkl
<lang zkl>fcn countJewels(a,b){ a.inCommon(b).len() }</lang> <lang zkl>println(countJewels("aAAbbbb", "aA")); println(countJewels("ZZ", "z"));</lang>
- Output:
3 0