Related
I wrote a function that works, to split a binary to every char, but I have a feeling there is an easier way to do it:
my_binary_to_list(<<H,T/binary>>) ->
%slightly modified version of http://erlang.org/doc/efficiency_guide/binaryhandling.html
[list_to_binary([H])|my_binary_to_list(T)];
my_binary_to_list(<<>>) -> [].
> my_binary_to_list(<<"ABC">>).
[<<"A">>,<<"B">>,<<"C">>]
I think this is probably messy because of the list_to_binary([H]) because H should already be a binary.
I tried using that linked function directly but got "AA" which was not what I wanted. Then I tried just [H] and got ["A","B","C"] which was also not what I wanted.
You can create a binary from a single byte without creating a list and calling list_to_binary like this:
my_binary_to_list(<<H,T/binary>>) ->
[<<H>>|my_binary_to_list(T)];
You can also use binary comprehensions here to do the same logic as above in a single line:
1> [<<X>> || <<X>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]
You can also directly extract binaries of size 1 (this is probably not faster than above though):
2> [X || <<X:1/binary>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]
Edit: a quick bench using timer:tc/1 runs the second code in roughly half the time compared to first, but you should benchmark yourself before using either one for performance reasons. Maybe the second one is sharing the large binary by creating sub binaries?
1> Bin = binary:copy(<<"?">>, 1000000).
<<"????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"...>>
2> timer:tc(fun() -> [<<X>> || <<X>> <= Bin] end).
{14345634,
[<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
3> timer:tc(fun() -> [X || <<X:1/binary>> <= Bin] end).
{7374003,
[<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
You can use a list comprehension with a bit string generator (<= consumes binaries, as opposed to <- which consumes lists):
> [<<A>> || <<A>> <= <<"foo">>].
[<<"f">>,<<"o">>,<<"o">>]
In your version, list_to_binary([H]) can be replaced by <<H>> - both generate a binary containing one byte. Whether using a list comprehension instead of a recursive function qualifies as "easier" might be a matter of taste.
This code is an excerpt from this book.
count_characters(Str) ->
count_characters(Str, #{}).
count_characters([H|T], #{ H => N }=X) ->
count_characters(T, X#{ H := N+1 });
count_characters([H|T], X) ->
count_characters(T, X#{ H => 1 });
count_characters([], X) ->
X.
So,
1> count_characters("hello").
#{101=>1,104=>1,108=>2,111=>1}
What I understand from this is that, count_characters() takes an argument hello, and place it to the first function, i.e count_characters(Str).
What I don't understand is, how the string characters are converted into ascii value without using $, and got incremented. I am very new to erlang, and would really appreciate if you could help me understand the above. Thank you.
In erlang the string literal "hello" is just a more convenient way of writing the list [104,101,108,108,111]. The string format is syntactic sugar and nothing erlang knows about internally. An ascii string is internally string is internally stored as a list of 32-bit integers.
This also becomes confusing when printing lists where the values happen to be within the ascii range:
io:format("~p~n", [[65,66]]).
will print
"AB"
even if you didn't expect a string as a result.
As said previously, there is no string data type in Erlang, it uses the internal representation of an integer list, so
"hello" == [$h,$e,$l,$l,$o] == [104|[101|[108|[108|[111|[]]]]]]
Which are each a valid representation of an integer list.
To make the count of characters, the function use a new Erlang data type: a map. (available only since R17)
A map is a collection of key/value pairs, in your case the keys will be the characters, and the values the occurrence of each characters.
The function is called with an empty map:count_characters(Str, #{}).
Then it goes recursively through the list, and for each head H, 2 cases are posible:
The character H was already found, then the current map X will match with the pattern #{ H => N } telling us that we already found N times H, so we continue the recursion with the rest of the list and a new map where the value associated to H is now N+1: count_characters(T, X#{ H := N+1 }.
The character H is found for the first time, then we continue the recursion with the rest of the list and a new map where the key/value pair H/1 is added: count_characters(T, X#{ H => 1 }).
When the end of the list is reached, simply return the map: count_characters([], X) -> X.
for university I have to implement an algorithm which creates all possibile magic squares for a given edge length and a specific sum. For n=3 the algorithm is working as expected. But when generating all magic squares for n=4 after a while I ran out of memory. This problem was already mentioned in the task description. I already tried to optimize the a code but it is still not working as it should. So I hope someone can give me some advice.
My basic idea is: First I generate all possible rows which I can use with the given numbers and then I'm trying to combine these in a way that the restrictions of a magic square are fullfilled. This happens via backtracking. I think the problem is the function makeRows which consumes too much memory after while for storing all the rows.
If you need some more explanation of the code I can give!
magicSquare(N, Value) ->
Squares = buildSquare(N, makeRows(N, N*N, Value, N)),
io:fwrite("Squares ready"), io:fwrite("~n"),
Result = lists:filter(fun(X) -> testsquare(X, N, Value) end, Squares),
io:write(length(Result)),
Result.
buildSquare(0, _) -> [[]];
buildSquare(Rows, AvailableRows) ->
[ [X|L] || L <- buildSquare(Rows-1, AvailableRows), X <- AvailableRows, onlyUniqueNumbers(lists:flatten([X|L]))].
onlyUniqueNumbers(List) -> erlang:length(List) == sets:size(sets:from_list(List)).
%produces all possible rows with a dimension of Fields and the Numbers from 1 to Numbers and the right sum for each row
makeRows(0,_,_,_) -> [[]];
makeRows(Fields, Numbers, Value, TargetLength) ->
[ [X|L] || X <- makeRows(Fields-1, Numbers, Value, TargetLength), L <- lists:seq(1,Numbers), checkRow([X|L], TargetLength, Value)].
checkRow(Row, Length, Value) when length(Row) < Length -> true;
checkRow(Row, Length, Value) ->
Sum = lists:sum(Row),
if Sum == Value -> true;
true -> false
end.
testsquare(Square, N, Value) -> checkAllDiagonal(Square, Value) andalso checkAllHorizontal(Square, Value) andalso checkAllVertical(Square, N, Value).
checkAllHorizontal([H|T], Value) ->
case checkHorizontal(H, Value, 0) of
true -> checkHorizontal(lists:nth(1, T), Value, 0);
false -> false
end;
checkAllHorizontal([], Value) -> true.
checkHorizontal([H|T], Value, Summe) -> checkHorizontal(T, Value, Summe + H);
checkHorizontal([], Value, Summe) when Summe == Value -> true;
checkHorizontal([], Value, Summe) -> false.
checkAllVertical(Square, N, Value) -> checkAllVertical(Square, N, Value, 1).
checkAllVertical(Square, N, Value, Column) ->
if
Column > N -> true;
true ->
case checkVertical(Square, Value, 0, Column) of
true -> checkAllVertical(Square, N, Value, Column + 1);
false -> false
end
end.
checkVertical([], Value, Summe, Column) when Summe == Value -> true;
checkVertical([], Value, Summe, Column) -> false;
checkVertical([H|T], Value, Summe, Column) -> checkVertical(T, Value, Summe + lists:nth(Column, H), Column).
checkAllDiagonal(Square, Value) ->
case checkDiagonal(Square, Value, 0, 1,1) of
true -> case checkDiagonal(Square, Value, 0, length(lists:nth(1, Square)),-1) of
true -> true;
false -> false
end;
false -> false
end.
checkDiagonal([H|T], Value, Summe, Position, Richtung) -> checkDiagonal(T, Value, Summe + lists:nth(Position, H), Position + Richtung, Richtung);
checkDiagonal([], Value, Summe, Position, Richtung) when Summe == Value -> true;
checkDiagonal([], Value, Summe, Position, Richtung) -> false.
Ok I've tried to add checks for rows and squares earlier in the calculation process. Here are the modified functions.
buildSquare(0, _, _, _) -> [[]];
buildSquare(Rows, AvailableRows, RowLength, Value) ->
[ [X|L] || L <- buildSquare(Rows-1, AvailableRows, RowLength, Value), X <- AvailableRows, validateSquare([X|L], RowLength, Value)].
checkOnlyUniqueNumbers(List) -> erlang:length(lists:flatten(List)) == sets:size(sets:from_list(lists:flatten(List))).
validateSquare(List, RowLength, Value) when length(List) == RowLength -> testsquare(List, RowLength, Value) andalso checkOnlyUniqueNumbers(List);
validateSquare(List, _,_) -> checkOnlyUniqueNumbers(List).
%produces all possible rows with a dimension of Fields and the Numbers from 1 to Numbers
makeRows(0,_,_,_) -> [[]];
makeRows(Fields, Numbers, Value, TargetLength) ->
[ [X|L] || L <- makeRows(Fields-1, Numbers, Value, TargetLength), X <- lists:seq(1,Numbers), checkRow([X|L], TargetLength, Value)].
%Checks if the sum of the row is Value when the row has the needed length Length
checkRow(Row, Length, _) when length(Row) < Length -> checkOnlyUniqueNumbers(Row);
checkRow(Row, _, Value) ->
Sum = lists:sum(Row),
Sum == Value andalso checkOnlyUniqueNumbers(Row).
Well, erlang isn't lazy, so
magicSquare(N, Value) ->
Squares = buildSquare(N, makeRows(N, N*N, Value, N)),
tries to build the list of all 3121348608 possible combinations of four rows, each summing to 34, using all the numbers from 1 to 16 (inclusive) between them, when called with arguments 4 and 34.
Even if each square took only 16 bytes (one for each cell), that would need about 48GB of memory, not counting list overhead.
Your algorithm would work - albeit slowly - in a lazy language. But in a non-lazy language, you need to prune more and earlier, or choose an altogether different algorithm.
You could test whether the verticals and diagonals even have a chance to sum to the target value already in buildSquare, that might push the memory requirement low enough that it fits into memory for a 4×4 magic square (but I'm less than convinced). If you build only (N-1)×N grids and compute the last row from the vertical sums, that would reduce the size of Squares by another factor of N!, that has a better chance of fitting into memory (for N == 4, not really for larger N) together with the earlier pruning.
But you should restructure your algorithm to use the constraints as early as possible. Say you check the first row 1 2 15 16. Then you know that the three numbers below 1 in the left column, and the three remaining numbers on the main diagonal each must sum to 33. So you need a set of six numbers chosen from { 3,4,5,6,7,8,9,10,11,12,13,14} summing to 66. There aren't many choices of these six numbers, since the six largest among them sum to 69 only, so you have
6, 10, 11, 12, 13, 14
7, 9, 11, 12, 13, 14
8, 9, 10, 12, 13, 14
only three possibilities. The two numbers in the bottom corners are also constrained by the right column, and the main north-east diagonal. Considering these constraints together further restricts the search space.
If you consider the possible squares sequentially, one top-row after the other, and don't store the candidates [you could store the magic 4×4 squares, they aren't too many], you can find all magic squares in small memory, and if you handle the constraints in a good way, even relatively quickly.
I have a direction that might prove helpful. I almost have it working, but will not be able to spend any time on it over the next couple of days.
First though, I believe this problem is NP-Complete which would indicate that you are going to use exponential memory or time as the input size increases linearly.
In any event, this was my approach:
If your magic square involves the numbers 1..N, your going to create all permutations for those N numbers. After all, magicSquare(3,15) will be a subset of all possible permutations of 1..15
The trick is to remove each permutation as it is generated if all of the rows that it represents do not sum up to the magic number. In this way you do not store all permutations, only those which are very promising thereby avoiding exponential memory (but not exponential time). In other words, in-line with generating each permutation, only save it if it is possible for it to be a magic square. I used a list comprehension to create the permutations with a qualifier on a generator that did a test to ensure that all of the rows summed correctly
My test function took a parameter that indicated the row length (3 in this case) and was able to examine the permutation of [8,1,6,3,5,7,4,9,2] and determine that each row (each sublist 1-3, 4-6,7-9 summed to 15.
after getting the permutations where at least every row sums to the Magic Number, then filter for the rest of the MN criteria.
Make sure that your algorithm to create the permutations is tail-recursive, by the way.
Again, this seemed to be working for me (except where it wasn't ;)), but I am away from my computer for a few days.
Hopefully this helps.
I'm sure that there is a function for that. I just want to make a list of 1000 numbers, each one of them which should be random.
To generate a 1000-element list with random numbers between 1 and 10:
[rand:uniform(10) || _ <- lists:seq(1, 1000)].
Change 10 and 1000 to appropriate numbers. If you omit the 10 from from the rand:uniform call, you'll get a random floating point number between 0.0 and 1.0.
On Erlang versions below 18.0: Use the random module instead. Caution! You need to run random:seed/3 before using it per process, to avoid getting the same pseudo random numbers.
Make sure to seed appropriately.
> F = fun() -> io:format("~p~n", [[random:uniform(10) || _ <- lists:seq(1, 10)]]) end.
> spawn(F).
[1,5,8,10,6,4,6,10,7,5]
> spawn(F).
[1,5,8,10,6,4,6,10,7,5]
Your intuition is that the results would be different. A random seed in Erlang is process specific. The default seed is fixed though. That's why you get the same result even though there are two processes in the example.
> G = fun() -> {A1,A2,A3} = now(),
random:seed(A1, A2, A3),
io:format("~p~n", [[random:uniform(10) || _ <- lists:seq(1, 10)]])
end.
> spawn(G).
[3,1,10,7,9,4,9,2,8,3]
> spawn(G).
[9,1,4,7,8,8,8,3,5,6]
Note that if the return value of now() is the same in two different processes you end up with the same problem as above. Which is why some people like to use a gen_server for wrapping random number generation. Alternatively you can use better seeds.
i will be more then happy to get also a site that i will be able to
read it there. thanks.
You should check out Learn You Some Erlang which will guide you through the language.
Pseudorandom number generator from crypto module works better crypto:rand_uniform(From, To).
To generate a 1000-element list with random numbers between 1 and 10:
crypto:start(),
[crypto:rand_uniform(1, 10) || _ <- lists:seq(1, 1000)].
From Erlang Central wiki:
http://erlangcentral.org/wiki/index.php?title=Random_Numbers
Where N = no of items, StartVal = minimum value and Lim = maximum value
generate_random_int_list(N,StartVal,Lim) ->
lists:map(fun (_) -> random:uniform(Lim-StartVal) + StartVal end, lists:seq(1,N)).
You need to correctly seed first of all.
_ = rand:seed(exs1024s),
[rand:uniform(100) || _ <- lists:seq(1, 1000)].
am josh in Uganda. i created a mnesia fragmented table (64 fragments), and managed to populate it upto 9948723 records. Each fragment was a disc_copies type, with two replicas.
Now, using qlc (query list comprehension), was too slow in searching for a record, and was returning inaccurate results.
I found out that this overhead is that qlc uses the select function of mnesia which traverses the entire table in order to match records. i tried something else below.
-define(ACCESS_MOD,mnesia_frag).
-define(DEFAULT_CONTEXT,transaction).
-define(NULL,'_').
-record(address,{tel,zip_code,email}).
-record(person,{name,sex,age,address = #address{}}).
match()-> Z = fun(Spec) -> mnesia:match_object(Spec) end,Z.
match_object(Pattern)->
Match = match(),
mnesia:activity(?DEFAULT_CONTEXT,Match,[Pattern],?ACCESS_MOD).
Trying this functionality gave me good results. But i found that i have to dynamically build patterns for every search that may be made in my stored procedures.
i decided to go through the havoc of doing this, so i wrote functions which will dynamically build wild patterns for my records depending on which parameter is to be searched.
%% This below gives me the default pattern for all searches ::= {person,'_','_','_'}
pattern(Record_name)->
N = length(my_record_info(Record_name)) + 1,
erlang:setelement(1,erlang:make_tuple(N,?NULL),Record_name).
%% this finds the position of the provided value and places it in that
%% position while keeping '_' in the other positions.
%% The caller function can use this function recursively until
%% it has built the full search pattern of interest
pattern({Field,Value},Pattern_sofar)->
N = position(Field,my_record_info(element(1,Pattern_sofar))),
case N of
-1 -> Pattern_sofar;
Int when Int >= 1 -> erlang:setelement(N + 1,Pattern_sofar,Value);
_ -> Pattern_sofar
end.
my_record_info(Record_name)->
case Record_name of
staff_dynamic -> record_info(fields,staff_dynamic);
person -> record_info(fields,person);
_ -> []
end.
%% These below,help locate the position of an element in a list
%% returned by "-record_info(fields,person)"
position(_,[]) -> -1;
position(Value,List)->
find(lists:member(Value,List),Value,List,1).
find(false,_,_,_) -> -1;
find(true,V,[V|_],N)-> N;
find(true,V,[_|X],N)->
find(V,X,N + 1).
find(V,[V|_],N)-> N;
find(V,[_|X],N) -> find(V,X,N + 1).
This was working very well though it was computationally intensive.
It could still work even after changing the record definition since at compile time, it gets the new record info
The problem is that when i initiate even 25 processes on a 3.0 GHz pentium 4 processor running WinXP, It hangs and takes a long time to return results.
If am to use qlc in these fragments, to get accurate results, i have to specify which fragment to search in like this.
find_person_by_tel(Tel)->
select(qlc:q([ X || X <- mnesia:table(Frag), (X#person.address)#address.tel == Tel])).
select(Q)->
case ?transact(fun() -> qlc:e(Q) end) of
{atomic,Val} -> Val;
{aborted,_} = Error -> report_mnesia_event(Error)
end.
Qlc was returning [], when i search for something yet when i use match_object/1 i get accurate results. I found that using match_expressions can help.
mnesia:table(Tab,Props).
where Props is a data structure that defines the match expression, the chunk size of return values e.t.c
I got a problem when i tried building match expressions dynamically.
Function mnesia:read/1 or mnesia:read/2 requires that you have the primary key
Now am asking myself, how can i efficiently use QLC to search for records in a large fragmented table? Please help.
I know that using tuple representation of records makes code hard to upgrade. This is why
i hate using mnesia:select/1, mnesia:match_object/1 and i want to stick to QLC. QLC is giving me wrong results in my queries from a mnesia table of 64 fragments even on the same node.
Has anyone ever used QLC to query a fragmented table?, please help
Do you invoke the qlc in the activity context?
tfn_match(Id) ->
Search = #person{address=#address{tel=Id, _ = '_'}, _ = '_'},
trans(fun() -> mnesia:match_object(Search) end).
tfn_qlc(Id) ->
Q = qlc:q([ X || X <- mnesia:table(person), (X#person.address)#address.tel == Id]),
trans(fun() -> qlc:e(Q) end).
trans(Fun) ->
try Res = mnesia:activity(transaction, Fun, mnesia_frag),
{atomic, Res}
catch exit:Error ->
{aborted, Error}
end.