# How to replace numbers by letters in a special way?

There are few sublists:

lists = {{0,0,0}, {0,0,1}, {0,1,0}, {0,1,1}, {1,0,0}, {1,0,1}, {1,1,0}, {1,1,1}}


The goal is to put A if the first element of a sublist is 1, B if the second element of a sublist is 1, C is the third element of a sublist is one, 1 if all elements of a sublists equals to 0. So the result should be:

{1, C, B, BC, A, AC, AB, ABC}


Honestly, I don't even know how to approach this problem. So I would be happy if you help me tackle it.

• What is the context this problem comes from? It calls to mind binary numbers so there might be some direct approach rather than the one I took in my answer – b3m2a1 Dec 9 '19 at 4:42
• This problem is from a boolean algebra, I'v got a triangle that is used to build Zhegalkin normal form, I'm on the final step, the goal is to translate the result to "ANF". – Rumato Dec 9 '19 at 4:46
• Ah then it probably has no good correspondence in binary notation. Might be a fun way to think about it though! (e.g. think about: FromDigits[#, 2] & /@ lists which perhaps by chance is 0, 1, 2, 3, 4, 5, 6, 7 for what you gave us) – b3m2a1 Dec 9 '19 at 4:48

Here's a way to do it (it's bad practice to put an involved answer in a comment so I'm moving it here):

lists = {{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1,
1, 0}, {1, 1, 1}};
With[{a = ToUpperCase@Alphabet[]},
StringJoin /@ MapIndexed[If[# == 1, a[[#2[[-1]]]], ""] &, lists, {2}] /.
"" -> "1"
]

(* Out: {"1", "C", "B", "BC", "A", "AC", "AB", "ABC"} *)


Basically I directly translated what you said into code.

Here's a fun way that involves using the 0/1 as a position, extracting that, then doing the string join:

With[{a = Prepend[ToUpperCase@Alphabet[], ""], sublen = Length@lists[]},
Replace[
StringJoin /@
Partition[
a[[
Flatten[1 + ConstantArray[Range[sublen], Length@lists]*lists]
]],
sublen
],
"" -> "1",
1
]
]


Some tests show that it might be minimally faster than the former

• Just want to say thanks again, you were very helpful! – Rumato Dec 9 '19 at 20:07
• Glad to help :) – b3m2a1 Dec 9 '19 at 20:08
lists.{"A", "B", "C"} /. 0 -> "1" /. Plus -> StringJoin


{"1", "C", "B", "BC", "A", "AC", "AB", "ABC"}

% // ToExpression


{1, C, B, BC, A, AC, AB, ABC}

• Finally a clean method. :-) A little shorter: StringJoin @@@ (lists.{"A", "B", "C"} /. 0 -> "1") – Mr.Wizard Dec 10 '19 at 7:40

One possibility is to use ReplaceAll (the short form of which is /.) with a list of rules. There are probably more concise ways of doing this that I'm not seeing.

{{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}} /.
{{0, 0, 0} -> 1, {0, 0, 1} -> C, {0, 1, 0} -> B, {0, 1, 1} -> BC,
{1, 0, 0} -> A, {1, 0, 1} -> AC, {1, 1, 0} -> AB, {1, 1, 1} -> ABC}
(* {1,C,B,BC,A,AC,AB,ABC} *)


However, I would recommend surrounding each of those capital letters with quotation marks to make them strings, or else using lower case letters. All built-in functions in Mathematica begin with capital letters, and there are a number of single character capitals reserved by the system such as C, D, E, I, K, N, and O.

"" <> Pick[{"A","B","C"}, #, 1] & /@ lists /. "" -> 1

{1, "C", "B", "BC", "A", "AC", "AB", "ABC"}

Map[
ToExpression@*StringJoin,
Transpose[
ReplaceAll,
{Transpose[a], {{1 -> "A"}, {1 -> "B"}, {1 -> "C"}}}
]
] /. 0 -> Nothing /. {} -> "1"
]


{1, C, B, BC, A, AC, AB, ABC}

Just for variety:

p = Position[#, 1] & /@ lists
StringJoin /@ (Extract[{"A", "B", "C"}, #] & /@ p) /. "" -> 1


Or using Sow and Reap

fun[x_] :=
StringJoin[Reap[Sow @@@ Thread[{{"A", "B", "C"}, x}], 1][]] /.
"" -> "1"
fun /@ lists

• +1 for the application of Sow/Reap! – Mr.Wizard Dec 13 '19 at 19:48
• @Mr.Wizard thank you. Enjoyed your answer and kglr answer – ubpdqn Dec 14 '19 at 1:13