In a previous post, we tackled the FizzBuzz challenge. If you're anything like me, you've already had some experience using vectorised functions in R or via Python's

Vectorised functions are great as they reduce the clutter often associated with for loops. For example if we have a numeric vector called

Here's an example of how we can do this in a non-vectorised form (via a for loop):

`numpy`

library. Let's see how we can use Julia similarly.Vectorised functions are great as they reduce the clutter often associated with for loops. For example if we have a numeric vector called

`a`

and we want to add 1 to each element, we don't want to loop trough each element of `a`

and add 1 to them.Here's an example of how we can do this in a non-vectorised form (via a for loop):

julia> a = [1,2,3]; julia> for i in 1:length(a) a[i] += 1 end julia> print(a) [2, 3, 4]

It get's the job done, but it's not the prettiest and makes the code harder to read. Here's how we can do the same thing via vectorisation:

julia> a = [1,2,3]; julia> a .+ 1; julia> print(a) [1, 2, 3]

The

After this short intro to vectorised operators, I want to have a go at the FizzBuzz challenge again and see how we can solve the same problem but with vectorised functions.

First, let's rephase the problem a little bit. Instead of printing the numbers, Fizzes and Buzzes, we'll return all of them together as a vector. I'll break down the problem the same way as before, so if you haven't seen the previous posts, now would be a good time to check it out!

First, let's return the numbers up until

`.`

tells Julia to broadcast the operator to each element of the object. So we're adding 1 to each and every element of `a`

.After this short intro to vectorised operators, I want to have a go at the FizzBuzz challenge again and see how we can solve the same problem but with vectorised functions.

First, let's rephase the problem a little bit. Instead of printing the numbers, Fizzes and Buzzes, we'll return all of them together as a vector. I'll break down the problem the same way as before, so if you haven't seen the previous posts, now would be a good time to check it out!

First, let's return the numbers up until

`n`

as a vector:julia> function fizzbuzz(n) return collect(1:n) end fizzbuzz (generic function with 1 method) julia> fizzbuzz(5) 5-element Array{Int64,1}: 1 2 3 4 5

This works. Let's see if we can print Fizz for each number that's divisible by 3. We can do this by replacing all places that are divisble by 3 with a

`Fizz`

string.julia> function fizzbuzz(n) numbers = 1:n # first we convert the numbers to strings result = string.(numbers) result[mod.(numbers, 3) .== 0] = "Fizz" return result end fizzbuzz (generic function with 1 method) julia> fizzbuzz(7) 7-element Array{String,1}: "1" "2" "Fizz" "4" "5" "Fizz" "7"

Just to give a bit more explanation here, we're first converting our numbers to strings. We don't necessarily have to do this, but it's neater to have same types in an array. We do this by applying the

The next step is to replace the numbers divisible by 3 with

Let's add the

`string()`

function elementvise (`.`

) to all elements of numbers.The next step is to replace the numbers divisible by 3 with

`Fizz`

. We calculate all the modulos of the numbers with `mod.()`

. Having the reminders we can then compare each of those remainders and get a boolean indexing array that says `true`

at each index divisible by 3 and `false`

otherwise. One can use boolean indexing to select specific places in the array. So we only replace every 3rd element in our array with `Fizz`

. Feel free to break these steps down and try them in your own Julia REPL!Let's add the

`Buzz`

es now!julia> function fizzbuzz(n) numbers = 1:n # first we convert the numbers to strings result = string.(numbers) result[mod.(numbers, 3) .== 0] = "Fizz" result[mod.(numbers, 5) .== 0] = "Buzz" return result end fizzbuzz (generic function with 1 method) julia> fizzbuzz(7) 7-element Array{String,1}: "1" "2" "Fizz" "4" "Buzz" "Fizz" "7"

And finaly the

`FizzBuzz`

elements:julia> function fizzbuzz(n) numbers = 1:n # first we convert the numbers to strings result = string.(numbers) result[mod.(numbers, 3) .== 0] = "Fizz" result[mod.(numbers, 5) .== 0] = "Buzz" result[(mod.(numbers, 3) .== 0) .* (mod.(numbers, 5) .== 0)] = "FizzBuzz" return result end fizzbuzz (generic function with 1 method) julia> fizzbuzz(16) 16-element Array{String,1}: "1" "2" "Fizz" "4" "Buzz" "Fizz" "7" "8" "Fizz" "Buzz" "11" "Fizz" "13" "14" "FizzBuzz" "16"

We used

The above certainly achieves what we want, but it's not exactly the prettiest. Let's clean it up a little bit.

`.*`

to "multiply" two boolean arrays. You can think of `*`

as a boolean `AND`

in this case.The above certainly achieves what we want, but it's not exactly the prettiest. Let's clean it up a little bit.

julia> function fizzbuzz(n) numbers = 1:n result = string.(numbers) fizzers = mod.(numbers,3) .== 0 buzzers = mod.(numbers,5) .== 0 result[fizzers] = "Fizz" result[buzzers] = "Buzz" result[fizzers .* buzzers] = "FizzBuzz" return result end fizzbuzz (generic function with 1 method) julia> fizzbuzz(16) 16-element Array{String,1}: "1" "2" "Fizz" "4" "Buzz" "Fizz" "7" "8" "Fizz" "Buzz" "11" "Fizz" "13" "14" "FizzBuzz" "16"

And that's it. This concludes our little tutorial on vectorised functions. Hope you enjoed this example. If you have any questions or requests let me know in the comments.

I'd also recommend that you check out my previous post on FizzBuzz and compare the solution of that with this new fancy vectorised one!

I'd also recommend that you check out my previous post on FizzBuzz and compare the solution of that with this new fancy vectorised one!

## Comments

## Post a Comment