Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I tried to implement some logic gates for a series of "0 & 1" strings, just like and, or, nand, nor and not listed below. How could I limit xor only accept a two strings list as its argument?

str2 = {"11000000", "10000001", "11111111"};

or[str : {__String}] := 
  StringJoin[
   MapThread[Or, 
     Characters[str] /. {"0" -> False, "1" -> True}] /. {False -> "0", True -> "1"}];

and[str : {__String}] := 
  StringJoin[
   MapThread[And, 
     Characters[str] /. {"0" -> False, "1" -> True}] /. {False -> "0", True -> "1"}];

nand[str : {__String}] := 
  not[StringJoin[
    MapThread[ And, 
      Characters[str] /. {"0" -> False, "1" -> True}] /. {False -> "0", True -> "1"}]];

nor[str : {__String}] := 
  not[StringJoin[
    MapThread[ Or, 
      Characters[str] /. {"0" -> False, "1" -> True}] /. {False -> "0", True -> "1"}]];

not[str : _String ] := 
  StringJoin[ 
   Characters[str] /. {"1" -> False, "0" -> True}  /. {False -> "0", True -> "1"}];

(* ????? *)
xor[str : {_String, _String}] := 
  StringJoin[
   MapThread[Xor, 
     Characters[str] /. {"0" -> False, "1" -> True}] /. {False -> "0", True -> "1"}];

enter image description here

share|improve this question
    
I'm having trouble following. Could you provide an example of your desired input/output? –  mfvonh Jul 19 at 21:37
    
I suppose xor should only take two strings for its xor operation, as I used the {_string,_string} pattern to control the argument. The example above showed that it took str2(a three string list) as its argument with no sign of error and gave a wrong result! –  Putterboy Jul 19 at 21:59
    
@user16069 Have you tried restarting your kernel? You could have some old definition lingering that accepts more than two strings. The current definition looks right to me. –  Pickett Jul 19 at 22:28
    
@Pickett You are right. Everything becomes normal after quitting MM and back again. –  Putterboy Jul 20 at 3:28

3 Answers 3

up vote 1 down vote accepted

I think it would be simpler to implement the logic directly, with fewer transformations:

str2={"11000000","10000001","11111111"};

do[f_]:=StringJoin[ToString/@Boole@MapThread[f,StringSplit[#,""]]]&;

not=StringReplace[#,{"1"->"0","0"->"1"}]&;
not@str2[[1]]

"00111111"

or=do[!FreeQ[{##},"1"]&];
or@str2

"11111111"

and=do[FreeQ[{##},"0"]&];
and@str2

"10000000"

nand=do[!FreeQ[{##},"0"]&];
nand@str2

"01111111"

nor=do[FreeQ[{##},"1"]&];
nor@str2

"00000000"

xor=do[Count[{##},"1"]==1&];
xor@str2

"00111110"

share|improve this answer

Perhaps

xor[ab : {a_String /; StringFreeQ[a, Except["0" | "1"]], 
          b_String /; StringFreeQ[b, Except["0" | "1"]]}] := 
  StringJoin[
    MapThread[Xor, Characters[ab] /. {"0" -> False, "1" -> True}] /. 
      {False -> "0", True -> "1"}]

Since xor is limited to two strings in the list it will be convenient to support this form:

xor[a_String, b_String] := xor[{a, b}]

Some tests:

a = "1100"; b = "1010"; c = "1111"; d = "105a";
xor[{a, b}]
"0110"
xor[{a, b, c}]
xor[{"1100", "1010", "1111"}]
xor[a, b]
"0110"
xor[a, d]
xor[{"1100", "105a"}]
share|improve this answer

Here's a bitwise approach, using a two-argument definition like @m_goldberg:

xor[str1_String, str2_String] := 
  IntegerString[
   BitXor[FromDigits[str1, 2], FromDigits[str2, 2]],
   2, 
   StringLength[str1]];

The other functions could be implemented with bitwise operators, too.

share|improve this answer
    
@Karsten7. I didn't notice your deleted answer until now. If you'll undelete, I delete mine. I think it's worth showing the bitwise approach (obviously, since I did). –  Michael E2 Jul 20 at 1:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.