two questions on string manipulation in Mathematica - wolfram-mathematica

Given a character or a string s, generate a result string with n (an integer) repeats of s
Given a list of characters or strings, and a list of the frequencies of their appearance (in correspondence), generate a result string with each string in the list repeated with the desired times as specified in the second list and StringJoin them together. For example, given {"a", "b", "c"} and {1,0,3}, I want to have "accc".
I of course want to have the most efficient way of doing these. Otherwise, my own way is too ugly and slow.
Thank you for your help!

rep[s_String, n_] := StringJoin[ConstantArray[s, n]]
then
rep["f", 3]
(*fff*)
next
chars = {"a", "b", "c"};
freqs = {1, 0, 3};
StringJoin[MapThread[rep, {chars, freqs}]]
gives "accc"

For 1, Table will do what you need.
s = "samplestring";
StringJoin[Table[s, {3}]]
"samplestringsamplestringsamplestring"
But acl's answer using ContantArray is faster, if you care about the last 1/100th second.
Do[StringJoin[Table[s, {30}]];, {10000}] // Timing
{0.05805, Null}
Do[StringJoin[ConstantArray[s, 30]];, {10000}] // Timing
{0.033306, Null}
Do[StringJoin[Table[s, {300}]];, {10000}] // Timing
{0.39411, Null}
Do[StringJoin[ConstantArray[s, 300]];, {10000}] // Timing
{0.163103, Null}
For 2, MapThread will handle cases where the second list is known to be non-negative integers.
StringJoin #
MapThread[Table[#1, {#2}] &, {{"a", "b", "c"} , {1, 0, 3}}]
"accc"
If the second list contains negative integers, these are treated as zeros.
Non-integer elements in the second list are treated as if they are the integer part. I am not sure if this is what you want.
StringJoin #
MapThread[Table[#1, {#2}] &, {{"a", "b", "c"} , {1, 0, 3.7}}]
"accc"

Knowing your application I propose using Inner:
sets = {{0, 0, 0, 4}, {0, 0, 1, 3}, {0, 1, 0, 3}, {0, 1, 1, 2}, {0, 2, 0, 2},
{0, 2, 1, 1}, {1, 0, 0, 3}, {1, 0, 1, 2}, {1, 1, 0, 2}, {1, 1, 1, 1},
{1, 2, 0, 1}, {1, 2, 1, 0}, {2, 0, 0, 2}, {2, 0, 1, 1}, {2, 1, 0, 1},
{2, 1, 1, 0}, {2, 2, 0, 0}};
chars = {"a", "b", "c", "d"};
Inner[ConstantArray[#2, #] &, sets, chars, StringJoin]
{"dddd", "cddd", "bddd", "bcdd", "bbdd", "bbcd", "addd", "acdd",
"abdd", "abcd", "abbd", "abbc", "aadd", "aacd", "aabd", "aabc", "aabb"}

Related

How can i generate combination of arbitrary bit strings in mathematica [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
How can i write a function which has two parameters,and it should generate combination arbitrary range bits for example:
function(n,k) n=range, k=number of 1 digits. if i give 4 and 2 to function input: function(4,2)
output:1100,1010,1001,0110,0011,0101
This gives you a list of random digits:
rands[n_, k_] := Module[{out},
out = Table[0, {n}];
out[[RandomSample[Range[n], k]]] = 1;
out]
rands[4, 2]
(* {1, 1, 0, 0} *)
Not sure what output form you want, but you might use FromDigits.
edit a somewhat cleaner approach..
rands[n_, k_] := Table[0, {n - k}]~Join~Table[1, {k}] // RandomSample
Edit: based on your comment I guess what you want are permutations: (I suppose I took "arbitrary" to mean random..)
p[n_, k_] := Permutations[Table[0, {n - k}]~Join~Table[1, {k}], {n}]
(*
{{0, 0, 1, 1}, {0, 1, 0, 1}, {0, 1, 1, 0}, {1, 0, 0, 1},
{1, 0, 1, 0}, {1, 1, 0, 0}}
*)
function[n_, k_] := Permutations[PadRight[ConstantArray[1, k], n]]
In[72]:= function[4, 2]
Out[72]= {{1, 1, 0, 0}, {1, 0, 1, 0}, {1, 0, 0, 1}, {0, 1, 1, 0}, {0, 1, 0, 1}, {0, 0, 1, 1}}
In[73]:= function[3, 1]
Out[73]= {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}

Eliminate element of every list within a nested list

I would like to eliminate the third element of every list within a nested list.
E.g.,
lst = { {1, 0, 0}, {1, 1, 1}, {1, 1, 4} }
So it would become
{ {1, 0}, {1, 1}, {1, 1} }
How should I do that?
yet another:
lst = #[[1;;2]] & /# lst
or if you want to drop only the third element from possibly longer sublists:
lst = Drop[#,{3}]& /# lst
Lots of way to do that, e.g.
lst = {{1, 0, 0}, {1, 1, 1}, {1, 1, 4}};
lst = lst[[All, {1, 2}]]
{{1, 0}, {1, 1}, {1, 1}}
Or
lst = Transpose[Most[Transpose[lst]]]
Or, without transposing
lst = MapThread[Delete, {lst, Table[3, {Length[lst]}]}]

Generating Manipulate 'sliders' on the fly

Mathematica's Manipulate function takes as its final arguments separate lists of the parameters you want sliders for along with their value ranges. But why not a list of lists?
This way I could I easily generate all the sliders for this big list of transformation rules that I have, e.g.:
parms = {a -> 2, b -> 4, c -> 5};
Table[{{parms[[i]][[1]], parms[[i]][[2]]}, 0, 10}, {i, 1,Length[parms]}]
{{{a, 2}, 0, 10}, {{b, 4}, 0, 10}, {{c, 5}, 0, 10}}
What I would like to have, however, is:
{{a, 2}, 0, 10}, {{b, 4}, 0, 10}, {{c, 5}, 0, 10}
This I'm copy pasting now between cells, which is rather messy. I'm sure there's a better way to do this. Please help, thanks!
Please see this and this on similar questions.
What you need is Sequence## to get the list of lists to be treated as your desired output when used as input.
Perhaps something like:
ClearAll[a, b, c];
parms = {a -> 2, b -> 4, c -> 5};
With[{values = Table[parms[[i]][[1]], {i, 1, Length[parms]}],
controls = Sequence ##
Table[{{parms[[i]][[1]], parms[[i]][[2]],
Style[ToString[parms[[i]][[1]]], Red, Bold]}, 0, 10}, {i, 1,
Length[parms]}]},
Manipulate[values, controls]]
which gives

Sort a list of lists based on alphabetical order of inner list elements in Mahtematica

I have a list of lists with inner lists possibly of variable lengths. I need to sort the outer list based on the alphabetical order of the inner list elements. For example, given a list of
{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 10, 0}, {0, 6, 2}, {5, 1, 2}, {0, 3, 6, 1, 4}}
I want the output after Sort to be
{{0, 0, 10, 0}, {0, 0, 7}, {0, 3, 6, 1, 4}, {0, 6, 2}, {5, 0, 2, 3}, {5, 1, 2}}
I just do not know how to handle the variable lengths of inner lists in order to write a comparison function. Please help.
Edit
BTW, the original list is a numerical one.
Edit 2
For example, I have a list:
{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 11, 0}, {0, 0, 1, 12}, {0, 6, 2}, {5, 1, 2}, {0, 3, 6, 1, 4}}
The output should be:
{{0, 0, 1, 12}, {0, 0, 11, 0}, {0, 0, 7}, {0, 3, 6, 1, 4}, {0, 6, 2}, {5, 0, 2, 3}, {5, 1, 2}}
The reason is that 1 is lexically less than 11, which is less than 7.
You can set up a lexciographic comparator like this:
lexComp[_, {}] := False;
lexComp[{}, _] := True;
lexComp[{a_, as___}, {b_, bs___}] := a < b || a == b && lexComp[{as}, {bs}];
You can then sort using that to get the desired effect:
Sort[{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 10, 0}, {0, 6, 2}, {5, 1, 2}, {0, 3, 6, 1, 4}}, lexComp]
{{0, 0, 7}, {0, 0, 10, 0}, {0, 3, 6, 1, 4}, {0, 6, 2}, {5, 0, 2, 3}, {5, 1, 2}}
If you wish to treat the numbers as strings in your sorting, you can modify it like so:
lessAsString[a_, b_] := Order ## (ToString /# {a, b}) === 1;
olexComp[_, {}] := False;
olexComp[{}, _] := True;
olexComp[{a_, as___}, {b_, bs___}] := lessAsString[a, b] || a === b && olexComp[{as}, {bs}];
Here is the example of such a sort:
In[5]:= Sort[{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 11, 0}, {0, 0, 1, 12}, {0, 6, 2}, {5, 1, 2}, {0, 3, 6, 1, 4}}, olexComp]
Out[5]= {{0, 0, 1, 12}, {0, 0, 11, 0}, {0, 0, 7}, {0, 3, 6, 1, 4}, {0, 6, 2}, {5, 0, 2, 3}, {5, 1, 2}}
alphaSort = #[[ Ordering # Map[ToString, PadRight##, {2}] ]] &;
This works by preparing the data for the default Ordering sort, and then using that order to sort the original list.
In this case, padding all of the lists to the same length keeps this Sort property from interfering:
Sort usually orders expressions by putting shorter ones first, and then comparing parts in a depth-first manner.
ToString is used to get an alphabetical order rather than a numeric one.
This should do it
{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 10, 0}, {0, 6, 2}, {5, 1, 2}, {0, 3,
6, 1, 4}} // SortBy[#, ToString] &
This works because lexically, comma and space precede the numbers, so {a,b} is lexically before {a,b,c}.

how to solve for all non-negative integer xi's in mathematica

I have a problem similar to IntegerPartitions function, in that I want to list all non-negative integer xi's such that, for a given list of integers {c1,c2,...,cn} and an integer n:
x1*c1+x2*c2+...+xn*cn=n
Please share your thoughts. Many thanks.
The built-in function FrobeniusSolve solves the case where the c1, c2, ..., cn are positive integers (and the right hand side is not n):
In[1]:= FrobeniusSolve[{2, 3, 5, 6}, 13]
Out[1]= {{0, 1, 2, 0}, {1, 0, 1, 1}, {1, 2, 1, 0}, {2, 1, 0, 1}, {2,
3, 0, 0}, {4, 0, 1, 0}, {5, 1, 0, 0}}
Is this the case you need, or do you need negative c1, c2, ..., cn also?
Construct your list of ci's and coefficients using
n = 10;
cList = RandomInteger[{1, 20}, n]
xList = Table[Symbol["x" <> ToString[i]], {i, n}]
Then, if there's a set of solutions for non-negative xi's, it will be found by
Reduce[cList.xList == n && And##Thread[xList >= 0], xList, Integers]

Resources