6
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 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 $\endgroup$ – b3m2a1 Dec 9 '19 at 4:42
  • $\begingroup$ 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". $\endgroup$ – Rumato Dec 9 '19 at 4:46
  • $\begingroup$ 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) $\endgroup$ – b3m2a1 Dec 9 '19 at 4:48
3
$\begingroup$

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[[1]]},
 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

$\endgroup$
  • $\begingroup$ Just want to say thanks again, you were very helpful! $\endgroup$ – Rumato Dec 9 '19 at 20:07
  • $\begingroup$ Glad to help :) $\endgroup$ – b3m2a1 Dec 9 '19 at 20:08
5
$\begingroup$
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}

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

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.

$\endgroup$
  • $\begingroup$ I'm sure you meant it, but /. is shorthand/infix notation for ReplaceAll not Replace $\endgroup$ – That Gravity Guy Dec 10 '19 at 0:43
  • $\begingroup$ @ThatGravityGuy Oops! Good catch, thanks! $\endgroup$ – MassDefect Dec 10 '19 at 2:24
3
$\begingroup$
"" <> Pick[{"A","B","C"}, #, 1] & /@ lists /. "" -> 1
{1, "C", "B", "BC", "A", "AC", "AB", "ABC"}
$\endgroup$
2
$\begingroup$
Map[
 ToExpression@*StringJoin,
 Transpose[
    MapThread[
     ReplaceAll,
     {Transpose[a], {{1 -> "A"}, {1 -> "B"}, {1 -> "C"}}}
     ]
    ] /. 0 -> Nothing /. {} -> "1"
 ]

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

$\endgroup$
1
$\begingroup$

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][[2]]] /. 
  "" -> "1"
fun /@ lists
$\endgroup$
  • $\begingroup$ +1 for the application of Sow/Reap! $\endgroup$ – Mr.Wizard Dec 13 '19 at 19:48
  • $\begingroup$ @Mr.Wizard thank you. Enjoyed your answer and kglr answer $\endgroup$ – ubpdqn Dec 14 '19 at 1:13

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.