I want to use a Structure like HashTable. Is there similar structure in Wolfram Mathematica?
Update: Mathematica version 10 introduced the Association data structure (tutorial).
There are a number of possibilities. The easiest possibility, which works well if you don't need to add or delete keys from your table, or change their associated values, is to construct a list of rules with the key on the left-hand side and the value on the right-hand side, and use Dispatch on it.
If you do need to change the entries in your table, you can use the DownValues of a symbol as a hash table. This will support all the operations one commonly uses with hash tables. Here's the most straightforward way of doing that:
(* Set some values in your table.*)
In[1]:= table[a] = foo; table[b] = bar; table[c] = baz;
(* Test whether some keys are present. *)
In[2]:= {ValueQ[table[a]], ValueQ[table[d]]}
Out[2]:= {True, False}
(* Get a list of all keys and values, as delayed rules. *)
In[3]:= DownValues[table]
Out[3]:= {HoldPattern[table[a]] :> foo, HoldPattern[table[b]] :> bar,
HoldPattern[table[c]] :> baz}
(* Remove a key from your table. *)
In[4]:= Unset[table[b]]; ValueQ[table[b]]
Out[4]:= False
I'd say the most similar structure you can get out of the box are sparse arrays.
I agree with Pillsy, but see also this answer:
Mathematica Downvalue Lhs
It includes a handy function for getting the keys of a hash table.
I've made Dictionary.m module, which contained:
DictHasKey = Function[
{
dict,
key
},
ValueQ[dict[key]]
]
DictAddKey = Function[
{
dict,
key,
value
},
If[
DictHasKey[dict,key],
Print["Warning, Dictionary already has key " <> ToString[key]]
];
dict[key] = value;
]
DictKeys = Function[
{
dict
},
res = {};
ForEach[DownValues[dict], Function[{dictKeyDescr},
res = Append[res, ((dictKeyDescr[[1]]) /. dict -> neverUsedSymbolWhatever)[[1, 1]]];
]];
res
]
DictValues = Function[
{
dict
},
res = {};
ForEach[DownValues[dict], Function[{dictKeyDescr},
res = Append[res, dictKeyDescr[[2]]];
]];
res
]
DictKeyValuePairs = Function[
{
dict
},
res = {};
ForEach[DownValues[dict], Function[{dictKeyDescr},
res = Append[res, {((dictKeyDescr[[1]]) /. dict -> neverUsedSymbolWhatever)[[1, 1]], dictKeyDescr[[2]]}];
]];
res
]
ForEach = Function[
{
list,
func
},
len = Length[list];
For[i = 1, i <= len, i++,
func[
list[[i]]
];
];
]
Mathematica 10 introduces Association, <| k -> v |>,
<|a -> x, b -> y, c -> z|>
%[b]
y
Which is basically a wrapper for a list of rules:
Convert a list of rules to an association:
Association[{a -> x, b -> y, c -> z}]
<|a -> x, b -> y, c -> z|>
Convert an association to a list of rules:
Normal[<|a -> x, b -> y, c -> z|>]
{a -> x, b -> y, c -> z}
Related
Lets say I have an array declaration looking like this
array[1..5] of int: temp = [1,0,5,0,3];
Is there a way to initiate a new array looking the same as temp but without the 0's? The result would look like the following
[1,5,3]
or sort the array in such a way that the 0's would be either in the beginning or in the end of the array, which would be
[0,0,1,5,3]
or
[1,5,3,0,0]
Thanks
Even though Axel has answered this, I'll show another approach which - in my book is a little neater.
Case 1: the array ("temp") is a constant array.
Then one can simply write
array[int] of int: temp2 = [temp[i] | i in index_set(temp) where temp[i] != 0];
MiniZinc 2 (in contrast to version 1.*) don't need the size declaration if it can be calculated; it suffices to just use "array[int]". Also, "index_set" is used to be a little more general, e.g. to handle cases where the indices are from 0..4 (see the commented line).
Case 2: the array ("s") is an array of decision variables
If the array to handle is decision variables, we don't know (per definition) how many 0's there are and must rely on the alternative variant, namely to sort the array. One can then use the "sort" function, as shown in the model.
include "globals.mzn";
% constant
array[1..5] of int: temp = [1,0,5,0,3];
% array[0..4] of int: temp = array1d(0..4, [1,0,5,0,3]);
array[int] of int: temp2 = [temp[i] | i in index_set(temp) where temp[i] != 0];
% decision variables
array[1..5] of var int: s;
array[1..5] of var int: s2 = sort(s); % NOT CORRECT, see model below
solve satisfy;
constraint
s = [1,0,5,0,3]
;
% show our variables
output
[
"temp: \(temp)\n",
"temp2: \(temp2)\n",
"s: \(s)\n",
"s2: \(s2)\n",
];
Update
For the stable version of decision variables, this works what I can see. It calculating the position where to place this number depending on if "s[i]" is 0 or not. Not very pretty though.
int: n = 5;
array[1..n] of var 0..5: s;
array[1..n] of var lb_array(s)..ub_array(s): s2;
solve satisfy;
constraint
s = [1,0,5,0,3] /\
forall(i in 1..n) (
if s[i] != 0 then
s2[sum([s[j]!=0 | j in 1..i-1])+1] = s[i]
else
s2[sum([s[j]!=0 | j in 1..n]) + sum([s[j]=0 | j in 1..i-1])+1 ] = 0
endif
)
;
output
[
"s: \(s)\n",
"s2: \(s2)\n",
]
;
The output is
s: [1, 0, 5, 0, 3]
s2: [1, 5, 3, 0, 0]
Using MiniZinc 2, this can be done as follows:
array[1..5] of int: temp = [1,0,5,0,3];
% calculate upper bound of temp index
int: i_max = max(index_set(temp));
% use array comprehension to count non-zero elements
int: temp_non_zero = sum([1 | i in 1..i_max where temp[i] != 0]);
% copy non-zero elements to new array
array[1..temp_non_zero] of int: temp2 = [temp[i] | i in 1..i_max where temp[i] != 0];
% calculate upper bound for temp2 index
int: i2_max = max(index_set(temp2));
solve satisfy;
% show our variables
output
["\ni_max=" ++ show(i_max)]
++ ["\ni2_max=" ++ show(i2_max)]
++ ["\n" ++ show(temp2[i]) | i in 1..i2_max]
;
Another alternative:
A 1:1 mapping between the two arrays is established as an array of unique index values (= array positions). These indices are then sorted. The comparison weights elements higher if they point to a zero. Thus, the zero values are shifted to the back while leaving the order of the non-zero elements unchanged.
int: n = 5;
int: INF = 99999; % infinity
array[1..n] of var 0..5: s;
array[1..n] of var 1..n: map;
array[1..n] of var 0..5: s2;
solve satisfy;
% set s[]
constraint
s = [1,0,5,0,3]
;
% 1:1 mapping between s[] and s2[]
constraint
forall (i in 1..n) (
exists(j in 1..n) (
map[j] = i
)
)
;
constraint
forall(i in 1..n) (
s2[i] = s[map[i]]
)
;
% sort the map and move zero values to the back
constraint
forall(i in 1..n-1) (
(if s2[i] != 0 then map[i] else INF endif) <=
(if s2[i+1] != 0 then map[i+1] else INF endif)
)
;
output
[
"s: \(s)\n",
"map: \(map)\n",
"s2: \(s2)\n",
]
;
Output:
s: [1, 0, 5, 0, 3]
map: [1, 3, 5, 4, 2]
s2: [1, 5, 3, 0, 0]
How to modify below code to Return "string" so that returned output displayed on my MVC page and also would like to accept enteredChar from user.
Is there better way to do create this pyramid?
Current code:
let enteredChar = 'F' // As Interactive window doesn't support to Read Input
let mylist = ['A'..enteredChar]
let mylistlength = mylist |> List.length
let myfunc i x tlist1 =
(for j = 0 to mylistlength-i-2 do printf "%c" ' ')
let a1 = [for p in tlist1 do if p < x then yield p]
for p in a1 do printf "%c" p
printf "%c" x
let a2 = List.rev a1
for p in a2 do printf "%c" p
printfn "%s" " "
mylist |> List.iteri(fun i x -> myfunc i x mylist)
Output:
A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
ABCDEFEDCBA
A few small optimizations could be:
Use StringBuilder instead of printf which is quite slow with long strings.
Use Array instead of List since Array works better with String.
Here is a version producing a pyramid string, which is kept closely to your code:
open System
open System.Text
let generateString c =
let sb = StringBuilder()
let generate i x arr =
String.replicate (Array.length arr-i-1) " " |> sb.Append |> ignore
let a1 = Array.filter (fun p -> p < x) arr
String(a1) |> sb.Append |> ignore
sb.Append x |> ignore
String(Array.rev a1) |> sb.Append |> ignore
sb.AppendLine " " |> ignore
let arr = [|'A'..c|]
arr |> Array.iteri(fun i x -> generate i x arr)
sb.ToString()
generateString 'F' |> printfn "%s"
As an alternative to Daniel's solution, you can achieve what you want with minimal changes to the code logic. Instead of using printf that writes the output to the console, you can use Printf.bprintf which writes the output to a specified StringBuilder. Then you can simply get the resulting string from the StringBuilder.
The modified function will look like this. I added parameter str and replaced printf with Printf.bprintf str (and printfn with bprintf together with additional \n char):
let myfunc i x tlist1 str =
(for j = 0 to mylistlength-i-2 do Printf.bprintf str "%c" ' ')
let a1 = [for p in tlist1 do if p < x then yield p]
for p in a1 do Printf.bprintf str "%c" p
Printf.bprintf str "%c" x
let a2 = List.rev a1
for p in a2 do Printf.bprintf str "%c" p
Printf.bprintf str "%s\n" " "
To call the function, you first create StringBuilder and then pass it to myfunc in every call. At the end, you can get the result using ToString method:
let str = StringBuilder()
mylist |> List.iteri(fun i x -> myfunc i x mylist str)
str.ToString()
I think Daniel's solution looks nicer, but this is the most direct way to tunr your printing code into a string-building code (and it can be done, pretty much, using Search & Replace).
If I understand your question (this likely belongs on Code Review) here's one way to rewrite your function:
let showPyramid (output: TextWriter) lastChar =
let chars = [|'A' .. lastChar|]
let getRowChars n =
let rec loop acc i =
[|
if i < n then let c = chars.[i] in yield c; yield! loop (c::acc) (i+1)
else yield! List.tail acc
|]
loop [] 0
let n = chars.Length
for r = 1 to n do
output.WriteLine("{0}{1}{0}", String(' ', n - r), String(getRowChars r))
Example
showPyramid Console.Out 'F'
or, to output to a string
use output = new StringWriter()
showPyramid output 'F'
let pyramid = output.ToString()
EDIT
After seeing Tomas' answer I realized I skipped over "return a string" in your question. I updated the code and added examples to show how you could do that.
let pyramid (ch:char) =
let ar = [| 'A'..ch |]
let len = ar.Length
Array.mapi
(fun i ch ->
let ar = ar.[0..i]
String.replicate (len - i - 1) " " + new string(ar) + new string((Array.rev ar).[1..]))
ar
|> String.concat "\n"
pyramid 'F' |> printfn "%s"
Here's another approach that seems to be a good demonstration of functional composition. I bet it's the shortest solution among the answers here. :)
let charsToString = Seq.map string >> String.concat String.Empty
let pyramid lastChar =
let src = '-'::['A'..lastChar] |> List.toArray
let len = Array.length src - 1
fun row col -> row-abs(col-len+1)+1 |> max 0 |> Array.get src // (1)
>> Seq.init (len*2-1) >> charsToString // (2)
|> Seq.init len // (3)
pyramid 'X' |> Seq.iter (printfn "%s")
First, we generate an unusual array of initial data. Its element [0] contains a space or whatever separator you want to have; I preferred dash (-) for debugging purposes.
The (1) line makes a function that calculates what character to be placed. The result of row-abs(col-len+1)+1 can be either positive (and there is a char to be placed) or zeronegative, and there should be a space. Note that there is no if statement: it is hidden within the max function;
The (2) line composes a function int -> string for generating an individual row;
The (3) line passes the function above as argument for sequence initializer.
The three lines can be written in a more verbose way:
let genCell row col = row-abs(col-len+1)+1 |> max 0 |> Array.get src
let genRow = genCell >> Seq.init (len*2-1) >> charsToString
Seq.init len genRow
Note genRow needs no formal argument due to functional composition: the argument is being bound into genCell, returning a function of a single argument, exactly what Seq.init needs.
I am interested in writing multiple vectors to a file such that each vector forms one row in the file, and is written to the file as soon as it is generated. The elements of the vector need to be separated by a single space, and I do not want to include the { } parentheses for the vector. Basically, I want to mimic the fprintf("file", "%f %f %f\n") functionality of C.
Here is what I have. Is there a better way of doing this?
st1 = OpenWrite["C:\\junk\\mu.out", FormatType -> OutputForm];
vt = Table[
v = RandomReal[{0, 1}, 5];
For[j = 1, j <= Length[v], j++,
WriteString[
st1,
SequenceForm[NumberForm[v[[j]], ExponentFunction -> (Null &)],
" "]
]
];
Write[st1, ""];
v,
{200}
];
In[3]:= Close[st1]
Out[3]= "C:\\junk\\mu.out"
Based on the wonderful Riffle function, courtesy Arnoud and Mr. Wizard, below, I modified it as follows:
WriteVector[stream_, vector_] :=
Apply[WriteString[stream, ##, "\n"] &,
Riffle[Map[NumberForm[#, ExponentFunction -> (Null &)] &, vector],
" "]
]
Maybe this?
WriteVector[stream_, vector_] :=
WriteString[stream, ##, "\n"] & ## Riffle[vector, " "]
and:
fname = "c:\\users\\arnoudb\\test.out";
then:
Do[WriteVector[fname, RandomReal[{0, 1}, 5]],{10}]
and check:
FilePrint[fname]
close stream when done:
Close[fname]
I have defined three variables a,b,c before a while loop, then compute a new var d.
I want to get rid of the biggest value in the three vars a,b,c and then replace it with d value; So I can keep the smallest values in the thre original vars.
a = 1;
b = 2;
c = 10;
While[ condition,
compute d using values of a b and c
d = 4;
a = 1;
b = 2;
c = 4; (*c = d *)
]
to do so I was think to get the max of the three vars and then update it depeneding wich has greatest value..
a = 1;
b = 2;
c = 10;
d = 4;
temp = Max[a, b];
maxim = Max[c, temp];
a = a; (*did not change*)
b = b; (*did not change*)
c = d = 4 (*changed!!*)
So after that a new iteraion will occur and update the three vars...
Another option is as follows:
Clear#updateList
SetAttributes[updateList, HoldFirst]
updateList[list_, value_] :=
Module[{listMax = Max#list},
list = (list /. listMax -> value);]
Now if I define variables as in your case and use the function:
a = 1; b = 10; c = 0;
updateList[{a,b,c},5];
{a,b,c}
Out[1]= {1, 5, 0}
You can see that the variable b, which was the largest has been replaced with the new value.
If you can accept the values in a list (array) rather than individual named Symbols, and if you really mean "most near" rather than greatest, then you may do something like this:
vars = {1, 10, 0};
vars = ReplacePart[vars, Position[vars, Nearest[vars, 5][[1]]] -> 5];
vars
(* Out= {5, 10, 0} *)
This also assumes that values are unique, or that you want to replace all values that match (such as if there is more than one 1 in the list in this example).
If you always what to replace the greatest value, then you could Max[vars] rather than Nearest.
In light of the updated problem description, I propose:
vars = {1, 10, 0};
d = 5;
vars = With[{m = Max[vars]}, If[d < m, vars /. m -> d, vars]]
If you wish to automate this, you may use:
SetAttributes[repmax, HoldFirst]
repmax[s_Symbol, n_?NumericQ] := If[n < #, s = s /. # -> n]& # Max#s
Now:
vals = {1, 10, 0};
repmax[vals, 5];
vals
{1, 5, 0}
vals = {1, 10, 0};
repmax[vals, 12];
vals
{1, 10, 0}
This is probably not the best way to go about this problem,
a = 1; b = 10; c = 0;
Position[#, Max##] &#{a, b, c}
{a, b, c} = ReplacePart[{a, b, c}, % -> 5]
You'd be better off defining your original values in as a list abc = {1, 10, 0} and then replacing the max element of the list. As I noticed Mr Wizard has just done in his answer.
You can also do something like
SetAttributes[ReplaceMax, HoldFirst]
ReplaceMax[list : {__Symbol}, val_] := Module[{pos},
pos = Flatten#Position[#, Max#Select[#, N[#] \[Element] Reals &]]&#list;
Do[Evaluate[(HoldPattern /# Unevaluated#list)[[p]]] = val,
{p, pos}]]
Then
In[15]:= {a, b, c, d, e} = {1, 15, 6, 17 + I, x};
In[16]:= ReplaceMax[{a, b, c, d, e}, 5]
{a, b, c, d, e}
Out[17]= {1, 5, 6, 17 + I, x}
I have a record in erlang:
-record(myrec,
{
id = 0,
price = 0,
quantity = 0
}).
I then have a list of records that I want to sort by id and price, both in descending and ascending order, where price is the first key and if two records have the same price I want to sort those by id.
How can I define a fun for this?
I'm a newb at Erlang :)
thanks,
nisbus
This is a shorter solution than what has been suggested so far. First define your record:
1> rd(myrec, {id=0, price=0, quantity=0}).
myrec
Then let's invent 3 of them:
2> A = #myrec{id=1, price=10, quantity=2}, B = #myrec{id=2, price=4, quantity=3}, C = #myrec{id=3, price=10, quantity=1}.
#myrec{id = 3,price = 10,quantity = 1
Now we need a comparison function. This is where the solution is shorter. Erlang can compare terms of a tuple in the order they appear, so if we want to sort by price, then by id, we just have to compare two tuples of the form {PriceA, IdA} < {PriceB, IdB}:
3> F = fun(X, Y) -> {X#myrec.price, X#myrec.id} < {Y#myrec.price, Y#myrec.id} end.
#Fun<erl_eval.12.113037538>
And plug it in lists:sort/2:
4> lists:sort(F, [C,B,A]).
[#myrec{id = 2,price = 4,quantity = 3},
#myrec{id = 1,price = 10,quantity = 2},
#myrec{id = 3,price = 10,quantity = 1}]
The order is now [B, A, C] and your list is sorted.
Note that if you wanted to sort by descending id instead, You could trick it by reversing the ids in the tuples as follows:
5> G = fun(X, Y) -> {X#myrec.price, Y#myrec.id} < {Y#myrec.price, X#myrec.id} end.
#Fun<erl_eval.12.113037538>
6> lists:sort(G, [C,B,A]).
[#myrec{id = 2,price = 4,quantity = 3},
#myrec{id = 3,price = 10,quantity = 1},
#myrec{id = 1,price = 10,quantity = 2}]
Giving us [B, C, A]. This is not obvious to the reader, so you'd better document it or use Dustin's solution in this case. The advantage of the solution presented here is that there is no nesting required. By setting elements in either tuple in the comparison, you can pretty much compare as many of them as you want without making the code that much longer.
First, you figure out how to compare your records:
-spec compare(#myrec{}, #myrec{}) -> boolean().
compare(A, B) ->
case A#myrec.price == B#myrec.price of
true ->
A#myrec.id < B#myrec.id;
_ ->
B#myrec.price < A#myrec.price
end.
Then, you just use the normal lists:sort function with your comparison function to get what you want (this is an eunit test of the above I ran to make sure I did something that made sense):
compare_test() ->
R1 = #myrec{id=5, price=3, quantity=2},
R2 = #myrec{id=6, price=5, quantity=1},
R3 = #myrec{id=7, price=5, quantity=0},
false = compare(R1, R2),
true = compare(R2, R1),
true = compare(R2, R3),
false = compare(R3, R2),
false = compare(R1, R3),
true = compare(R3, R1),
% Run a sort with the above comparator.
[R2, R3, R1] = lists:sort(fun compare/2, [R1, R2, R3]).
% 3723064
-module(t).
-export([record_sort/0, price_cmp/2, qty_cmp/2]).
-record (item, {id = 0, price = 0, quantity = 0}).
price_cmp(A, B) ->
A#item.price < B#item.price.
qty_cmp(A, B) ->
A#item.quantity < B#item.quantity.
record_sort() ->
Items = [
#item{id=1, price=10, quantity=5},
#item{id=2, price=50, quantity=0},
#item{id=3, price=30, quantity=3},
#item{id=4, price=60, quantity=9}
],
io:format("Unsorted Items: ~p~n", [Items]),
io:format("By Price: ~p~n", [lists:sort({t, price_cmp}, Items)]),
io:format("By Quantity: ~p~n", [lists:sort({t, qty_cmp}, Items)]).
% Alternatively use anonymous functions:
% io:format("By Price: ~p~n", [lists:sort(
% fun(A, B) -> A#item.price < B#item.price end, Items)]),
%
% io:format("By Quantity: ~p~n", [lists:sort(
% fun(A, B) -> A#item.quantity < B#item.quantity end, Items)]).
This will yield (assuming example file t.erl):
1> c(t).
{ok,t}
2> t:record_sort().
Unsorted Items: [{item,1,10,5},{item,2,50,0},{item,3,30,3},{item,4,60,9}]
By Price: [{item,1,10,5},{item,3,30,3},{item,2,50,0},{item,4,60,9}]
By Quantity: [{item,2,50,0},{item,3,30,3},{item,1,10,5},{item,4,60,9}]
ok