3
$\begingroup$

I have two lists, one contains the variables and the other the corresponding values that the variables should take.

letters = {"a","m","t","h","e"}
bonus = {10, 20, 30, 40, 50}
words = {math, the, gps, log}

I know that this works (as in the manual of Mathematica):

{a,b,c} = {10,20,30}

But the lists are rather long, so I would like to write:

letters = bonus

Which does not work. Output: I would like to have the variables (letters) taking the values (bonus) a=10, b=20, c=30. Having the weight of the letters, it should be possible to compute the weight of every word in list "words" [math (100), the (120) etc.] I would appreciate some pointers to get me started. Thank you for your time.

$\endgroup$
3
  • 1
    $\begingroup$ The items in your "letters" List are Strings not Symbols and therefore can't be assigned values. You might be better off creating a Rule for the letter values. $\endgroup$ Mar 12, 2016 at 20:28
  • 1
    $\begingroup$ You can try Clear[letters]; Evaluate@(Symbol /@ letters) = bonus. This will create symbols from your strings, then assign them a value, i.e. a=10 etc. Beware that the Clear bit is important if you plan to run this code more than once. Notice, however, that you are NOT assigning a value TO THE STRING "a", but to the symbol a. This may still not work for what you want. An Association construct would probably work a lot better. $\endgroup$
    – MarcoB
    Mar 12, 2016 at 20:31
  • $\begingroup$ @Xavier, @Quantum_Oli, @garej - I used "// Timing" to time the processes. The three answers below demand different times with a dictionary of about 240 thousand words. Plus: 0.005087, Total: 0.013299 and Map: 0.039653. The Plus solution is thus the quickest. $\endgroup$
    – JSP
    Mar 14, 2016 at 15:48

3 Answers 3

5
$\begingroup$

Using associations:

letters = {"a","m","t","h","e"};
bonus = {10, 20, 30, 40, 50};
words = {math, the, gps, log};

assoc = AssociationThread[letters -> bonus];

Plus @@@ (Lookup[assoc, #, 0] & /@ Characters[ToString /@ words])

(* {100, 120, 0, 0} *)

If the words are strings, rather than symbols, then simply Characters[words] instead of Characters[ToString /@ words].

$\endgroup$
2
  • $\begingroup$ Sorry for the delay before responding, I have been travelling. Thank you @Xavier, It works like a charm. I have to understand Associations. Every time I get here I learn something. $\endgroup$
    – JSP
    Mar 14, 2016 at 15:11
  • $\begingroup$ Re: associations -- You may find this post (52393) useful. $\endgroup$
    – user31159
    Mar 14, 2016 at 15:29
3
$\begingroup$

Converting your words to strings first:

    letters = {"a", "m", "t", "h", "e"}
    bonus = {10, 20, 30, 40, 50}
    words = {"math", "the", "gps", "log"}

We can create a list of rules for the values of letters (rather than assign values to many variables):

    Thread[letters -> bonus]

{"a" -> 10, "m" -> 20, "t" -> 30, "h" -> 40, "e" -> 50}

Then we can use Characters to split each word into a list of it's characters:

    Characters /@ words

{{"m", "a", "t", "h"}, {"t", "h", "e"}, {"g", "p", "s"}, {"l", "o", "g"}}

Putting it all together:

    Total /@ ((Characters /@ words) /. Thread[letters -> bonus])

{100, 120, "g" + "p" + "s", "g" + "l" + "o"}

$\endgroup$
1
  • $\begingroup$ Sorry for the delay before responding, I have been travelling. Thank you @Quantum_Oli, It works like a charm. Every time I get here I learn something. It is especially useful with such a pedagogical explanation! $\endgroup$
    – JSP
    Mar 14, 2016 at 15:15
2
$\begingroup$
letters = {"a", "m", "t", "h", "e"};
bonus = {10, 20, 30, 40, 50};
words = {math, the, gps, log};

Solution:

Map[Total @ Replace[#, Append[Thread[letters -> bonus], _ -> 0], 1] &,
Characters[ToString /@ words]]

{100, 120, 0, 0}

$\endgroup$
2
  • $\begingroup$ Thank you @garey, it also works nicely. I will try to find the timings for all three solutions (if I can do that). I do not understand the "_->0". Where can I read about it? Thanks. $\endgroup$
    – JSP
    Mar 14, 2016 at 15:23
  • $\begingroup$ @JSP, This is a pattern with Rule. You may see that Raplace expects a pattern as an option. So your letter->score are simple replacement rules that applied first. Then _->0 construct applies (it replaces all the rest letters in characters list). It means "replace any symbol to 0". Here _ is blank and stands for any symbol. $\endgroup$
    – garej
    Mar 14, 2016 at 15:31

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.