I'm learning Erlang and I was asking myself what is the best way to turn the time() output into a formatted time string (HH:MM:SS).
The code I came up with is:
my_time() ->
{H, M, S} = time(),
integer_to_list(H) ++ ":" ++ integer_to_list(M) ++ ":" ++ integer_to_list(S).
This code won't do the trick exactly as it won't pad with zeros the minutes or seconds. It also uses the ++ operator to concatenate lists which isn't recommended.
What is the correct way of implementing this trivial task in Erlang?
A correct, easy-to-understand implementation uses format (which is like printf):
my_time() ->
{H, M, S} = time(),
io_lib:format('~2..0b:~2..0b:~2..0b', [H, M, S]).
~2..0b is a placeholder for an integer to be printed in base 10, taking up at least 2 characters, and padded on the left with the character 0.
References:
http://www.erlang.org/doc/man/io_lib.html#format-2 (the function that you're calling)
http://www.erlang.org/doc/man/io.html#fwrite-1 (the place where the format is documented)
You should only worry about performance if you're calling your function in a tight loop, and if profiling benchmarks show that your function is actually a bottleneck.
I don't know why you think concatenating list with length 8 can be any problem but if you want be really fast you can do:
my_time() ->
{H, M, S} = time(),
[$0 + H div 10, $0 + H rem 10, $:, $0 + M div 10, $0 + M rem 10, $:, $0 + S div 10, $0 + S rem 10].
There are not correct ways, there are faster or slower, more or less memory consuming and more or less concise solutions.
Edit: If you like more concise but same performance:
-define(DEC(X), $0 + X div 10, $0 + X rem 10).
my_time() ->
{H, M, S} = time(),
[?DEC(H), $:, ?DEC(M), $:, ?DEC(S)].
I like Dave Harveys dh_date module. The only "fix" required is that format/2 only take now() or datetime(). Easily fixed as in the example below.
4> dh_date:format("H:i:s",{{0,0,0},time()}).
"07:23:58"
Related
Reading chapter 2 of Hacker's Delight and trying ti implement bit manipulation in Erlang.
I'm stuck on this one:
Use the following formula to create a word with 0's at the positions of the trailing 1's in x, and 1's elsewhere, producing all 1's if none (e.g. 10100111 => 11111000):
¬ x | (x + 1)
Here is what I tried:
(bnot X) bor (X + 2#01)
But the result is -1000 for some reason, and not 2#11111000.
What's strange is that not 2#10100111 is -10101000 (base 2).
Any idea what's going on?
You have to limit the width oh the numbers manipulated (problem of sign, problem of bignum and integer representation).
The next example use 8 bits but it would work the same with 128 bits, in this case the result would be 340282366920938463463374607431768211448 instead of 248 for your test case.
1> Msk = fun(X) -> X band 2#11111111 end. % limit to 8 bits
#Fun<erl_eval.6.52032458>
2> Op = fun(X) -> Msk(bnot(X)) bor Msk(X+1) end.
#Fun<erl_eval.6.52032458>
3> Op(2#10100111).
248
4> 2#11111000.
248
my task is to parse that list
(100 30 5 . 50 6)
to number 135.56
format of input list is always the same
and I've wrote:
(reduce
'string-concat
(mapcar
(lambda (x) (remove #\0 x))
(mapcar
'write-to-string
l
)
)
)
and output I've "135|.|56"
and then read-from-string does'n read it, so...
have You any idea how I can do this parsing?
using or not code above
Your approach does not look particular robust. Also it is kind of difficult to understand what the input list is. Is the dot a symbol, like in |.|? The vertical bars are escaping the name, so that it does not collide with the built-in usage of the dot character in Lisp. It is used in dotted pairs, which stand for cons cells: (a . b).
If it is a symbol, then you can write the symbol without escaping to a string. First, with escaping:
CL-USER 5 > (write-to-string '|.|)
"\\."
Next, without:
CL-USER 6 > (princ-to-string '|.|)
"."
Your list (100 30 5 . 50 6) isn't a valid list structure in Common Lisp. A "dotted pair" must have only one element after the dot. If you want to know more about it, look at your favorite Common Lisp Book how lists are build from cons cells. (For example Peter Seibels "Practical Common Lisp")
So you cannot parse this string as a list as such - you need to have a pre-processing step.
(defun pre-processing (str)
(let ((idx (position #\. str)))
(list (read-from-string (concatenate 'string (subseq str 0 idx) ")"))
(read-from-string (concatenate 'string "(" (subseq str (1+ idx)))))))
This function splits your string in two lists that you can process the way you want to.
CL-USER 1 > (pre-processing "(100 30 5 . 50 6)")
((100 30 5) (50 6))
I am little bit confusing about ">>" in scala. Daniel said in Scala parser combinators parsing xml? that it could be used to parameterize the parser base on result from previous parser. Could someone give me some example/hint ? I already read scaladoc but still not understand it.
thanks
As I said, it serves to parameterize a parser, but let's walk through an example to make it clear.
Let's start with a simple parser, that parses a number follow by a word:
def numberAndWord = number ~ word
def number = "\\d+".r
def word = "\\w+".r
Under RegexParsers, this will parse stuff like "3 fruits".
Now, let's say you also want a list of what these "n things" are. For example, "3 fruits: banana, apple, orange". Let's try to parse that to see how it goes.
First, how do I parse "N" things? As it happen, there's a repN method:
def threeThings = repN(3, word)
That will parse "banana apple orange", but not "banana, apple, orange". I need a separator. There's repsep that provides that, but that won't let me specify how many repetitions I want. So, let's provide the separator ourselves:
def threeThings = word ~ repN(2, "," ~> word)
Ok, that words. We can write the whole example now, for three things, like this:
def listOfThings = "3" ~ word ~ ":" ~ threeThings
def word = "\\w+".r
def threeThings = word ~ repN(2, "," ~> word)
That kind of works, except that I'm fixing "N" in 3. I want to let the user specify how many. And that's where >>, also known as into (and, yes, it is flatMap for Parser), comes into. First, let's change threeThings:
def things(n: Int) = n match {
case 1 => word ^^ (List(_))
case x if x > 1 => word ~ repN(x - 1, "," ~> word) ^^ { case w ~ l => w :: l }
case x => err("Invalid repetitions: "+x)
}
This is slightly more complicated than you might have expected, because I'm forcing it to return Parser[List[String]]. But how do I pass a parameter to things? I mean, this won't work:
def listOfThings = number ~ word ~ ":" ~ things(/* what do I put here?*/)
But we can rewrite that like this:
def listOfThings = (number ~ word <~ ":") >> {
case n ~ what => things(n.toInt)
}
That is almost good enough, except that I now lost n and what: it only returns "List(banana, apple, orange)", not how many there ought to be, and what they are. I can do that like this:
def listOfThings = (number ~ word <~ ":") >> {
case n ~ what => things(n.toInt) ^^ { list => new ~(n.toInt, new ~(what, list)) }
}
def number = "\\d+".r
def word = "\\w+".r
def things(n: Int) = n match {
case 1 => word ^^ (List(_))
case x if x > 1 => word ~ repN(x - 1, "," ~> word) ^^ { case w ~ l => w :: l }
case x => err("Invalid repetitions: "+x)
}
Just a final comment. You might have wondered asked yourself "what do you mean flatMap? Isn't that a monad/for-comprehension thingy?" Why, yes, and yes! :-) Here's another way of writing listOfThings:
def listOfThings = for {
nOfWhat <- number ~ word <~ ":"
n ~ what = nOfWhat
list <- things(n.toInt)
} yield new ~(n.toInt, new ~(what, list))
I'm not doing n ~ what <- number ~ word <~ ":" because that uses filter or withFilter in Scala, which is not implemented by Parsers. But here's even another way of writing it, that doesn't have the exact same semantics, but produce the same results:
def listOfThings = for {
n <- number
what <- word
_ <- ":" : Parser[String]
list <- things(n.toInt)
} yield new ~(n.toInt, new ~(what, list))
This might even give one to think that maybe the claim that "monads are everywhere" might have something to it. :-)
The method >> takes a function that is given the result of the parser and uses it to contruct a new parser. As stated, this can be used to parameterize a parser on the result of a previous parser.
Example
The following parser parses a line with n + 1 integer values. The first value n states the number of values to follow. This first integer is parsed and then the result of this parse is used to construct a parser that parses n further integers.
Parser definition
The following line assumes, that you can parse an integer with parseInt: Parser[Int]. It first parses an integer value n and then uses >> to parse n additional integers which form the result of the parser. So the initial n is not returned by the parser (though it's the size of the returned list).
def intLine: Parser[Seq[Int]] = parseInt >> (n => repN(n,parseInt))
Valid inputs
1 42
3 1 2 3
0
Invalid inputs
0 1
1
3 42 42
I found that there is a || in list manipulation. What does the || mean? Are there any examples about ||?
lists:sum([A*B || {A, B} <- Foo]).
It is used in List comprehensions. List comprehensions is a shorter way to create lists without having to use funs, maps or filters.
From Programming Erlang:
If we have a list L:
L = [1,2,3,4,5].
And we want to double every element, we can do:
lists:map(fun(X) -> 2*X end, L).
But with List comprehensions we can do:
[2*X || X <- L].
Nomenclature most likely comes from mathematical notion of sets, where || means "such that".
e.g. copied from Wikipedia
F = {n2 − 4 : n is an integer; and 0 ≤ n ≤ 19}
In this notation, the colon (":") means "such that", and the description can be interpreted as "F is the set of all numbers of the form n2 − 4, such that n is a whole number in the range from 0 to 19 inclusive." Sometimes the vertical bar ("|") is used instead of the colon.
Applying same thing to
lists:sum([A*B || {A, B} <- Foo]).
means:- generate A*B such that A and B belong to list of tuples "Foo"
I would like convolve a discrete signal with a discrete filter. The signal and filter is sequences of float in F#.
The only way I can figure out how to do it is with two nested for loops and a mutable array to store the result, but it does not feel very functional.
Here is how I would do it non-functional:
conv = double[len(signal) + len(filter) - 1]
for i = 1 to len(signal)
for j = 1 to len(filter)
conv[i + j] = conv[i + j] + signal(i) * filter(len(filter) - j)
I don't know F#, but I'll post some Haskell and hopefully it will be close enough to use. (I only have VS 2005 and an ancient version of F#, so I think it would be more confusing to post something that works on my machine)
Let me start by posting a Python implementation of your pseudocode to make sure I'm getting the right answer:
def convolve(signal, filter):
conv = [0 for _ in range(len(signal) + len(filter) - 1)]
for i in range(len(signal)):
for j in range(len(filter)):
conv[i + j] += signal[i] * filter[-j-1]
return conv
Now convolve([1,1,1], [1,2,3]) gives [3, 5, 6, 3, 1]. If this is wrong, please tell me.
The first thing we can do is turn the inner loop into a zipWith; we're essentially adding a series of rows in a special way, in the example above: [[3,2,1], [3,2,1], [3,2,1]]. To generate each row, we'll zip each i in the signal with the reversed filter:
makeRow filter i = zipWith (*) (repeat i) (reverse filter)
(Note: according to a quick google, zipWith is map2 in F#. You might have to use a list comprehension instead of repeat)
Now:
makeRow [1,2,3] 1
=> [3,2,1]
makeRow [1,2,3] 2
=> [6,4,2]
To get this for all i, we need to map over signal:
map (makeRow filter) signal
=> [[3,2,1], [3,2,1], [3,2,1]]
Good. Now we just need a way to combine the rows properly. We can do this by noticing that combining is adding the new row to the existing array, except for the first element, which is stuck on front. For example:
[[3,2,1], [6,4,2]] = 3 : [2 + 6, 1 + 4] ++ [2]
// or in F#
[[3; 2; 1]; [6; 4; 2]] = 3 :: [2 + 6; 1 + 4] # [2]
So we just need to write some code that does this in the general case:
combine (front:combinable) rest =
let (combinable',previous) = splitAt (length combinable) rest in
front : zipWith (+) combinable combinable' ++ previous
Now that we have a way to generate all the rows and a way to combine a new row with an existing array, all we have to do is stick the two together with a fold:
convolve signal filter = foldr1 combine (map (makeRow filter) signal)
convolve [1,1,1] [1,2,3]
=> [3,5,6,3,1]
So that's a functional version. I think it's reasonably clear, as long as you understand foldr and zipWith. But it's at least as long as the imperative version and like other commenters said, probably less efficient in F#. Here's the whole thing in one place.
makeRow filter i = zipWith (*) (repeat i) (reverse filter)
combine (front:combinable) rest =
front : zipWith (+) combinable combinable' ++ previous
where (combinable',previous) = splitAt (length combinable) rest
convolve signal filter = foldr1 combine (map (makeRow filter) signal)
Edit:
As promised, here is an F# version. This was written using a seriously ancient version (1.9.2.9) on VS2005, so be careful. Also I couldn't find splitAt in the standard library, but then I don't know F# that well.
open List
let gen value = map (fun _ -> value)
let splitAt n l =
let rec splitter n l acc =
match n,l with
| 0,_ -> rev acc,l
| _,[] -> rev acc,[]
| n,x::xs -> splitter (n - 1) xs (x :: acc)
splitter n l []
let makeRow filter i = map2 ( * ) (gen i filter) (rev filter)
let combine (front::combinable) rest =
let combinable',previous = splitAt (length combinable) rest
front :: map2 (+) combinable combinable' # previous
let convolve signal filter =
fold1_right combine (map (makeRow filter) signal)
Try this function:
let convolute signal filter =
[|0 .. Array.length signal + Array.length filter - 1|] |> Array.map (fun i ->
[|0 .. i|] |> Array.sum_by (fun j -> signal.[i] * filter.[Array.length filter - (i - j) - 1]))
It's probably not the nicest function solution, but it should do the job. I doubt there exists a purely functional solution that will match the imperative one for speed however.
Hope that helps.
Note: The function is currently untested (though I've confirmed it compiles). Let me know if it doesn't quite do what it should. Also, observe that the i and j variables do not refer to the same things as is your original post.
Indeed, you generally want to avoid loops (plain, nested, whatever) and anything mutable in functional programming.
There happens to be a very simple solution in F# (and probably almost every other functional language):
let convolution = Seq.zip seq1 seq2
The zip function simply combines the two sequences into one of pairs containing the element from seq1 and the element from seq2. As a note, there also exist similar zip functions for the List and Array modules, as well as variants for combining three lists into triples (zip3). If you want tom ore generally zip (or "convolute") n lists into a list of n-tuples, then you'll need to write your own function, but it's pretty straightforward.
(I've been going by this description of convolution by the way - tell me if you mean something else.)
In principle, it should be possible to use the (Fast) Fourier Transform, or the related (Discrete) Cosine Transform, to calculate the convolution of two functions reasonably efficiently. You calculate the FFT for both functions, multiply them, and apply the inverse FFT on the result.
mathematical background
That's the theory. In practice you'd probably best find a math library that implements it for you.