I'm writing a simple interpreter that people can use (among other things) to sort a list via a comparison function (preferably a stable sort). Sorting algorithms that I'm familiar with all seem to require a variable number of calls to that comparison function and you don't know ahead of time which items will be compared to each other. That won't work because of the nature of what work is done in the interpreted language vs the runtime at what times.
The steps required by the interpreter are:
Step 1: Create a list of as to be compared to another list of bs, one a & b at a time. Something like sort([1, 2, 3]) producing:
a = [2, 3]
b = [1, 2]
(2 is compared to 1 and then 3 is compared to 2 in the above example, going index by index.)
Step 2: Create two new lists (before and after) with the same number of items as a and b to represent the result of the comparison function. The values are any null or non-null value. Something like:
before = [2, 3]
after = [null, null]
(2 should come before 1, representing 1 from b as null. The non-null values are preserved, but any non-null value could be in 2's place.)
I can impose a limitation that the values in before and after must be items from the lists a and b, but I'd prefer not to if I possibly can. I mention it because I'm unsure how I could know where the non-null value came from (a or b). But if the items compared from a and b are the same but only one is null at the end, I have the same problem.
Step 3: Use those two lists before and after to sort the original list. Something like:
sort([1, 2, 3], greaterThan) => [3, 2, 1]
// a = [2, 3]
// b = [1, 2]
// before = [2, 3]
// after = [null, null]
(If both values are non-null or both null, it should favor their original order relative to each other, or a "stable" sort.)
In such a trivial example, the items in a and b are sufficient to sort the list. The Javascript (the language the interpreter is written in) Array.sort method will compare them like this:
(2, 1)
(3, 2)
and be done. But if the order of the original list were [2, 3, 1] then it has to do:
(3, 2)
(1, 3)
(1, 2)
(1, 3)
(I don't know why or what algorithm they use).
In that example, I would have to provide lists a and b as [3, 1, 1, 1] and [2, 3, 2, 3] respectively.
How do I get a list for a and b that will work given any comparison function or order of the original list -- and then use the resulting before and after lists to sort that original list?
This question already has answers here:
How is this HashSet producing sorted output?
(5 answers)
Closed 2 years ago.
can you please let me know why below code returns the set sorted order given an unsorted array?
Stream<Integer> s = Stream.of(2, 3, 1, 4, 5);
Set<Integer> mySet = s.collect(Collectors.toSet());
System.out.println(mySet);
O/p
1, 2, 3, 4, 5
This doesn't happen if I use List instead of Set.
Also the sorting is not always correct when there are negative numbers in the input.
Is there any inbuilt functionality to sort the Set?
This is just an accident and has nothing to do with Collector or Stream. On OpenJDK 11.0.2, I'm getting this (as Collector.toSet() is currently backed by HashSet):
Set<Integer> set = new HashSet<>();
set.add(2);
set.add(3);
set.add(1);
set.add(4);
set.add(5);
System.out.println(set); // [1, 2, 3, 4, 5]
But try this:
set.add(100);
System.out.println(set); // [1, 2, 3, 4, 100, 5]
It is really just an accident. A very curious one, indeed, which has to do with the Integer.hashCode() implementation (it's just the Integer.intValue() itself), and how this results in accidentally ordering HashSet elements for certain sets.
It is just a coincidence. The Set interface does not provide any ordering guarantees, but LinkedHashSet.
I want to extract certain values from one array and concat them into another empty one:
freqs=[1,12,4,15,7,8,11,5,6]
less_freqs=[]
This is what I've come up with.
freqs.collect{|x| x<9 then x.to_a{|y|less_freqs<<y}}
Perhaps a different method? And, I'm not even sure if then makes any sense.
Is this what you're looking for?
freqs = [1,12,4,15,7,8,11,5,6]
less_freqs = freqs.select{|x| x < 9 } # => [1, 4, 7, 8, 5, 6]
I'm new to Ruby (and programming in general) and have been reading a ton of docs, how-tos and SO questions to try to find an answer to this problem but no luck so far.
I have an array of integers and I'm trying to save one of the object's integers to a variable to later delete that object from the array. What I have so far:
array = [3, 5, 1, 2, 6, 9]
objToDel = array[3]
array.delete_at(objToDel)
array
This deletes "1" in the array... I want it to delete "2" instead. I know this happens because having the variable point to array[3] points it to "2" instead of the actual third element in the array. I have tried the slice method as well to no avail.
So, is it possible to get a variable to equal an element's index instead of its content? Is this possible without turning the array into a hash?
Thanks in advance!
Sure, just assign the index to the variable:
index = 3
array.delete_at(index) # => 2
array # => [3, 5, 1, 6, 9]
You could also use the delete method to remove the object directly.
object_to_delete = 2
array.delete(object_to_delete) # => 2
array # => [3, 5, 1, 6, 9]
Note that this deletes all instances of the object in the array, which might not be what you want.
To keep it in your words, try this:
array = [3, 5, 1, 2, 6, 9]
objToDel = 3
array.delete_at(objToDel)
array
Good luck.
Example:
list:={ Plus[1,1], Times[2,3] }
When looking at list, I get
{2,6}
I want to keep them unevaluated (as above) so that list returns
{ Plus[1,1], Times[2,3] }
Later I want to evaluate the functions in list sequence to get
{2,6}
The number of unevaluated functions in list is not known beforehand. Besides Plus, user defined functions like f[x_] may be stored in list
I hope the example is clear.
What is the best way to do this?
The best way is to store them in Hold, not List, like so:
In[255]:= f[x_] := x^2;
lh = Hold[Plus[1, 1], Times[2, 3], f[2]]
Out[256]= Hold[1 + 1, 2 3, f[2]]
In this way, you have full control over them. At some point, you may call ReleaseHold to evaluate them:
In[258]:= ReleaseHold#lh
Out[258]= Sequence[2, 6, 4]
If you want the results in a list rather than Sequence, you may use just List##lh instead. If you need to evaluate a specific one, simply use Part to extract it:
In[261]:= lh[[2]]
Out[261]= 6
If you insist on your construction, here is a way:
In[263]:= l:={Plus[1,1],Times[2,3],f[2]};
Hold[l]/.OwnValues[l]
Out[264]= Hold[{1+1,2 3,f[2]}]
EDIT
In case you have some functions/symbols with UpValues which can evaluate even inside Hold, you may want to use HoldComplete in place of Hold.
EDIT2
As pointed by #Mr.Wizard in another answer, sometimes you may find it more convenient to have Hold wrapped around individual items in your sequence. My comment here is that the usefulness of both forms is amplified once we realize that it is very easy to transform one into another and back. The following function will split the sequence inside Hold into a list of held items:
splitHeldSequence[Hold[seq___], f_: Hold] := List ## Map[f, Hold[seq]]
for example,
In[274]:= splitHeldSequence[Hold[1 + 1, 2 + 2]]
Out[274]= {Hold[1 + 1], Hold[2 + 2]}
grouping them back into a single Hold is even easier - just Apply Join:
In[275]:= Join ## {Hold[1 + 1], Hold[2 + 2]}
Out[275]= Hold[1 + 1, 2 + 2]
The two different forms are useful in diferrent circumstances. You can easily use things such as Union, Select, Cases on a list of held items without thinking much about evaluation. Once finished, you can combine them back into a single Hold, for example, to feed as unevaluated sequence of arguments to some function.
EDIT 3
Per request of #ndroock1, here is a specific example. The setup:
l = {1, 1, 1, 2, 4, 8, 3, 9, 27}
S[n_] := Module[{}, l[[n]] = l[[n]] + 1; l]
Z[n_] := Module[{}, l[[n]] = 0; l]
placing functions in Hold:
In[43]:= held = Hold[Z[1], S[1]]
Out[43]= Hold[Z[1], S[1]]
Here is how the exec function may look:
exec[n_] := MapAt[Evaluate, held, n]
Now,
In[46]:= {exec[1], exec[2]}
Out[46]= {Hold[{0, 1, 1, 2, 4, 8, 3, 9, 27}, S[1]], Hold[Z[1], {1, 1, 1, 2, 4, 8, 3, 9, 27}]}
Note that the original variable held remains unchanged, since we operate on the copy. Note also that the original setup contains mutable state (l), which is not very idiomatic in Mathematica. In particular, the order of evaluations matter:
In[61]:= Reverse[{exec[2], exec[1]}]
Out[61]= {Hold[{0, 1, 1, 2, 4, 8, 3, 9, 27}, S[1]], Hold[Z[1], {2, 1, 1, 2, 4, 8, 3, 9, 27}]}
Whether or not this is desired depends on the specific needs, I just wanted to point this out. Also, while the exec above is implemented according to the requested spec, it implicitly depends on a global variable l, which I consider a bad practice.
An alternative way to store functions suggested by #Mr.Wizard can be achieved e.g. like
In[63]:= listOfHeld = splitHeldSequence[held]
Out[63]= {Hold[Z1], Hold[S1]}
and here
In[64]:= execAlt[n_] := MapAt[ReleaseHold, listOfHeld, n]
In[70]:= l = {1, 1, 1, 2, 4, 8, 3, 9, 27} ;
{execAlt[1], execAlt[2]}
Out[71]= {{{0, 1, 1, 2, 4, 8, 3, 9, 27}, Hold[S[1]]}, {Hold[Z[1]], {1, 1, 1, 2, 4, 8, 3, 9, 27}}}
The same comments about mutability and dependence on a global variable go here as well. This last form is also more suited to query the function type:
getType[n_, lh_] := lh[[n]] /. {Hold[_Z] :> zType, Hold[_S] :> sType, _ :> unknownType}
for example:
In[172]:= getType[#, listOfHeld] & /# {1, 2}
Out[172]= {zType, sType}
The first thing that spings to mind is to not use List but rather use something like this:
SetAttributes[lst, HoldAll];
heldL=lst[Plus[1, 1], Times[2, 3]]
There will surely be lots of more erudite suggestions though!
You can also use Hold on every element that you want held:
a = {Hold[2 + 2], Hold[2*3]}
You can use HoldForm on either the elements or the list, if you want the appearance of the list without Hold visible:
b = {HoldForm[2 + 2], HoldForm[2*3]}
c = HoldForm#{2 + 2, 2*3}
{2 + 2, 2 * 3}
And you can recover the evaluated form with ReleaseHold:
a // ReleaseHold
b // ReleaseHold
c // ReleaseHold
Out[8]= {4, 6}
Out[9]= {4, 6}
Out[10]= {4, 6}
The form Hold[2+2, 2*3] or that of a and b above are good because you can easily add terms with e.g. Append. For b type is it logically:
Append[b, HoldForm[8/4]]
For Hold[2+2, 2*3]:
Hold[2+2, 2*3] ~Join~ Hold[8/4]
Another way:
lh = Function[u, Hold#u, {HoldAll, Listable}];
k = lh#{2 + 2, Sin[Pi]}
(*
->{Hold[2 + 2], Hold[Sin[\[Pi]]]}
*)
ReleaseHold#First#k
(*
-> 4
*)