Jewels and stones: Difference between revisions

From Rosetta Code
Content added Content deleted
(Go solution(s))
(Added solution for D)
Line 65: Line 65:
0
0
</pre>
</pre>

=={{header|D}}==
{{trans|Kotlin}}
<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>
{{out}}
<pre>3
0</pre>


=={{header|Factor}}==
=={{header|Factor}}==

Revision as of 00:58, 16 June 2018

Jewels and stones is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
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:

  1. Only letters in the ISO basic Latin alphabet i.e. 'A to Z' or 'a to z' need be considered.
  2. A lower case letter is considered to be different to its upper case equivalent for this purpose i.e. 'a' != 'A'.
  3. The parameters do not need to have exactly the same names.
  4. 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.

AWK

<lang AWK>

  1. 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

Translation of: Kotlin

<lang c>#include <stdio.h>

  1. 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

D

Translation of: Kotlin

<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>

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

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

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

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>

  1. 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. */

  1. =0 /*initalize 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 & a match, bump # counter*/

return # /*return the number of common letters. */</lang>

output   when using the default inputs:
3
0

Ring

<lang ring>

  1. Project Jewels and Stones
  2. Date 2018/04/25
  3. Author Gal Zsolt (~ CalmoSoft ~)
  4. Email <calmosoft@gmail.com>

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

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>

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