Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/RoyiAvital/Julia100Exercises

A set of introductory exercises for Julia. Based on [100 NumPy Exercises](https://github.com/rougier/numpy-100).
https://github.com/RoyiAvital/Julia100Exercises

exercise julia questions-and-answers self-learning self-study

Last synced: about 1 month ago
JSON representation

A set of introductory exercises for Julia. Based on [100 NumPy Exercises](https://github.com/rougier/numpy-100).

Lists

README

        

[![Visitors](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FRoyiAvital%2FStackExchangeCodes&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=Visitors+%28Daily+%2F+Total%29&edge_flat=false)](https://github.com/RoyiAvital/Julia100Exercises)

# 100 Julia Exercises with Solutions

A set of introductory exercises for Julia. Based on [100 NumPy Exercises](https://github.com/rougier/numpy-100).

In order to generate this file:
1. Clone the repository (Or download).
2. Activate and instantiate the project.
3. Run:
```Julia
using Literate;
Literate.markdown("Julia100Exercises.jl", name = "README", execute = true, flavor = Literate.CommonMarkFlavor());
```

**Remark**: Tested with Julia `1.8.2`.

**To Do**:
1. Reevaluate the difficulty level of each question.

````julia
using Literate;
using LinearAlgebra;
using Statistics;
using Dates;
using DelimitedFiles;
using UnicodePlots;
using Random;
using Tullio;
using StaticKernels;
````

## Question 001
Import the `LinearAlgebra` package under the name `LA`. (★☆☆)

````julia
import LinearAlgebra as LA;
````

## Question 002
Print the version of Julia. (★☆☆)

````julia
println(VERSION);
````

````
1.8.2

````

## Question 003
Create a non initialized vector of size 10 of `Float64`. (★☆☆)

````julia
vA = Vector{Float64}(undef, 10)
````

````
10-element Vector{Float64}:
0.0
1.314224183e-315
1.314224183e-315
0.0
1.314248214e-315
1.31427351e-315
0.0
1.314248214e-315
1.314106556e-315
0.0
````

Which is equivalent of

````julia
vA = Array{Float64, 1}(undef, 10)
````

````
10-element Vector{Float64}:
0.0
1.314248214e-315
1.314106556e-315
0.0
1.314248214e-315
1.314106556e-315
0.0
1.314248214e-315
1.314106556e-315
0.0
````

## Question 004
Find the memory size of any array. (★☆☆)

````julia
sizeof(vA)
````

````
80
````

## Question 005
Show the documentation of the `+` (Add) method. (★☆☆)

````julia
@doc +
````

```
+(x, y...)
```

Addition operator. `x+y+z+...` calls this function with all arguments, i.e. `+(x, y, z, ...)`.

# Examples

```jldoctest
julia> 1 + 20 + 4
25

julia> +(1, 20, 4)
25
```

```
dt::Date + t::Time -> DateTime
```

The addition of a `Date` with a `Time` produces a `DateTime`. The hour, minute, second, and millisecond parts of the `Time` are used along with the year, month, and day of the `Date` to create the new `DateTime`. Non-zero microseconds or nanoseconds in the `Time` type will result in an `InexactError` being thrown.

## Question 006
Create a vector of zeros of size 10 but the fifth value which is 1. (★☆☆)

````julia
vA = zeros(10);
vA[5] = 1.0;
vA
````

````
10-element Vector{Float64}:
0.0
0.0
0.0
0.0
1.0
0.0
0.0
0.0
0.0
0.0
````

## Question 007
Create a vector with values ranging from 7 to 12. (★☆☆)

````julia
vA = 7:12
````

````
7:12
````

The above is efficient type. In order to explicitly create a vector:

````julia
vA = collect(7:12)
````

````
6-element Vector{Int64}:
7
8
9
10
11
12
````

## Question 008
Reverse a vector (first element becomes last). (★☆☆)

````julia
vA = collect(1:3);
vB = vA[end:-1:1];
vB
````

````
3-element Vector{Int64}:
3
2
1
````

Alternative 001:

````julia
vB = reverse(vA);
````

Alternative 002 (In place):

````julia
reverse!(vA);
vA
````

````
3-element Vector{Int64}:
3
2
1
````

## Question 009
Create a `3x3` matrix with values ranging from 0 to 8. (★☆☆)

````julia
mA = reshape(0:8, 3, 3)
````

````
3×3 reshape(::UnitRange{Int64}, 3, 3) with eltype Int64:
0 3 6
1 4 7
2 5 8
````

Another way would be:

````julia
mA = Matrix{Float64}(undef, 3, 3);
mA[:] = 0:8;
````

## Question 010
Find indices of non zero elements from `[1, 2, 0, 0, 4, 0]`. (★☆☆)

````julia
findall(!iszero, [1, 2, 0, 0, 4, 0])
````

````
3-element Vector{Int64}:
1
2
5
````

## Question 011
Create a 3x3 identity matrix. (★☆☆)

````julia
mA = I(3)
````

````
3×3 LinearAlgebra.Diagonal{Bool, Vector{Bool}}:
1 ⋅ ⋅
⋅ 1 ⋅
⋅ ⋅ 1
````

An alternative method (Explicit matrix) would be:

````julia
mA = Matrix(I, 3, 3) # NaN
````

````
false
````

````julia
NaN - NaN
````

````
NaN
````

````julia
NaN in [NaN]
````

````
false
````

````julia
0.3 == 3 * 0.1
````

````
false
````

## Question 018
Create a `5x5` matrix with values `[1, 2, 3, 4]` just below the diagonal. (★☆☆)

````julia
mA = diagm(5, 5, -1 => 1:4)
````

````
5×5 Matrix{Int64}:
0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 3 0 0
0 0 0 4 0
````

## Question 019
Create a `8x8` matrix and fill it with a checkerboard pattern. (★☆☆)

````julia
mA = zeros(8, 8);
mA[2:2:end, 1:2:end] .= 1;
mA[1:2:end, 2:2:end] .= 1;
mA
````

````
8×8 Matrix{Float64}:
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
````

By Tomer Arnon (https://github.com/tomerarnon):

````julia
mA = Int[isodd(ii + jj) for ii in 1:8, jj in 1:8];
````

## Question 020
Convert the linear index 100 to a _Cartesian Index_ of a size `(6,7,8)`. (★☆☆)

````julia
mA = rand(6, 7, 8);
cartIdx = CartesianIndices(mA)[100]; # ((x > 3) && (x < 8)) ? -x : x, vA, vA)
````

````
8-element Vector{Int64}:
-6
3
1
-4
3
-4
-5
-4
````

Julia allows Math like notation as well (See `Q0027`):

````julia
vA = rand(1:10, 8);
map!(x -> 3 < x < 8 ? -x : x, vA, vA)
````

````
8-element Vector{Int64}:
-7
-6
-4
1
-6
10
8
-5
````

Using logical indices one could use:

````julia
vA[3 .< vA .< 8] .*= -1;
````

## Question 026
Sum the array `1:4` with initial value of -10. (★☆☆)

````julia
sum(1:4, init = -10)
````

````
0
````

## Question 027
Consider an integer vector `vZ` validate the following expressions. (★☆☆)
```julia
vZ .^ vZ
2 << vZ >> 2
vZ <- vZ
1im * vZ
vZ / 1 / 1
vZ < Z > Z
```

````julia
vZ = rand(1:10, 3);
````

````julia
vZ .^ vZ
````

````
3-element Vector{Int64}:
387420489
387420489
46656
````

````julia
try
2 << vZ >> 2
catch e
println(e)
end
````

````
MethodError(<<, (2, [9, 9, 6]), 0x0000000000007f1f)

````

````julia
vZ <- vZ
````

````
false
````

````julia
1im * vZ
````

````
3-element Vector{Complex{Int64}}:
0 + 9im
0 + 9im
0 + 6im
````

````julia
vZ / 1 / 1
````

````
3-element Vector{Float64}:
9.0
9.0
6.0
````

````julia
vZ < vZ > vZ
````

````
false
````

## Question 028
Evaluate the following expressions. (★☆☆)

````julia
[0] ./ [0]
````

````
1-element Vector{Float64}:
NaN
````

````julia
try
[0] .÷ [0]
catch e
println(e)
end
````

````
DivideError()

````

````julia
try
convert(Float, convert(Int, NaN))
catch e
println(e)
end
````

````
InexactError(:Int64, Int64, NaN)

````

## Question 029
Round away from zero a float array. (★☆☆)

````julia
vA = randn(10);
map(x -> x > 0 ? ceil(x) : floor(x), vA)
````

````
10-element Vector{Float64}:
1.0
-1.0
-1.0
-1.0
2.0
-1.0
2.0
2.0
2.0
1.0
````

## Question 030
Find common values between two arrays. (★☆☆)

````julia
vA = rand(1:10, 6);
vB = rand(1:10, 6);

vA[findall(in(vB), vA)]
````

````
2-element Vector{Int64}:
7
5
````

## Question 031
Suppress Julia's warnings. (★☆☆)

One could use [Suppressor.jl](https://github.com/JuliaIO/Suppressor.jl).

## Question 032
Compare `sqrt(-1)` and `sqrt(-1 + 0im)`. (★☆☆)

````julia
try
sqrt(-1)
catch e
println(e)
end
````

````
DomainError(-1.0, "sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).")

````

````julia
sqrt(-1 + 0im)
````

````
0.0 + 1.0im
````

## Question 033
Display yesterday, today and tomorrow's date. (★☆☆)

````julia
println("Yesterday: $(today() - Day(1))");
println("Today: $(today())");
println("Tomorrow: $(today() + Day(1))");
````

````
Yesterday: 2022-10-26
Today: 2022-10-27
Tomorrow: 2022-10-28

````

## Question 034
Display all the dates corresponding to the month of July 2016. (★★☆)

````julia
collect(Date(2016,7,1):Day(1):Date(2016,7,31))
````

````
31-element Vector{Dates.Date}:
2016-07-01
2016-07-02
2016-07-03
2016-07-04
2016-07-05
2016-07-06
2016-07-07
2016-07-08
2016-07-09
2016-07-10
2016-07-11
2016-07-12
2016-07-13
2016-07-14
2016-07-15
2016-07-16
2016-07-17
2016-07-18
2016-07-19
2016-07-20
2016-07-21
2016-07-22
2016-07-23
2016-07-24
2016-07-25
2016-07-26
2016-07-27
2016-07-28
2016-07-29
2016-07-30
2016-07-31
````

## Question 035
Compute `((mA + mB) * (-mA / 2))` in place. (★★☆)

````julia
mA = rand(2, 2);
mB = rand(2, 2);
mA .= ((mA .+ mB) .* (.-mA ./ 2))
````

````
2×2 Matrix{Float64}:
-0.35038 -0.685683
-0.510546 -0.444504
````

Using the dot macro:

````julia
@. mA = ((mA + mB) * (-mA / 2));
````

## Question 036
Extract the integer part of a random array of positive numbers using 4 different methods. (★★☆)

````julia
mA = 5 * rand(3, 3);
````

Option 1:

````julia
floor.(mA)
````

````
3×3 Matrix{Float64}:
0.0 0.0 4.0
2.0 3.0 4.0
0.0 3.0 3.0
````

Option 2:

````julia
round.(mA .- 0.5) # [hypot(vX[1], vX[2]), atan(vX[2], vX[1])]

mB = [ConvToPolar(vX) for vX in eachrow(mA)]
````

````
10-element Vector{Vector{Float64}}:
[0.9505364569557584, 0.031648622825633764]
[0.704392126760974, 0.5147716023358581]
[0.29679995764188105, 1.201649642883764]
[0.637435149299262, 0.02987122275134911]
[0.933745980010277, 0.7244055260446777]
[0.9187482092583683, 0.36651502794834323]
[1.0164226188075605, 0.9581226557842126]
[0.5946171056720952, 1.4392243895565575]
[0.7889136757232136, 0.2964469880257975]
[1.044698619009772, 0.8754548962664869]
````

In order to have the same output size:

````julia
mC = reduce(hcat, mB)';
````

## Question 045
Create random vector of size 10 and replace the maximum value by 0. (★★☆)

````julia
vA = randn(10);
````

In case of a single maximum or all different values:

````julia
vA[argmax(vA)] = 0;
vA
````

````
10-element Vector{Float64}:
0.15593661212531384
0.8177229521444311
-1.4850097210409072
0.0
0.8552383451908633
1.476127811761641
0.2407698166125247
-0.6363509339561092
-0.5514594178114751
0.8756142494364301
````

General solution:

````julia
maxVal = maximum(vA);
vA .= (valA == maxVal ? 0 : valA for valA in vA); # ([x for _ in vY, x in vX], [y for y in vY, _ in vX]);

mX, mY = MeshGrid(vX, vY); # abs(y - inputVal), vA);
end

ClosestValue(vA, inputVal)
````

````
0.5023858297186229
````

## Question 051
Create a structured array representing a position `(x, y)` and a color `(r, g, b)`. (★★☆)

````julia
struct sPosColor
x::Int
y::Int
R::UInt8;
G::UInt8;
B::UInt8;
A::UInt8;
end

numPixels = 10;
maxVal = typemax(UInt32);
vMyColor = [sPosColor(rand(1:maxVal, 2)..., rand(UInt8, 4)...) for _ in 1:numPixels];
````

## Question 052
Consider a random vector with shape `(5, 2)` representing coordinates, find the distances matrix `mD`: $ {D}_{i, j} = {\left\| {x}_{i} - {x}_{j} \right\|}_{2} $. (★★☆)

````julia
mX = rand(5, 2);
vSumSqr = sum(vX -> vX .^ 2, mX, dims = 2);
mD = vSumSqr .+ vSumSqr' - 2 * (mX * mX');
mD # x[colIdx]);
````

## Question 060
Tell if a given 2D array has null (All zeros) columns. (★★☆)

````julia
mA = rand(0:1, 3, 9);
any(all(iszero.(mA), dims = 1))
````

````
false
````

## Question 061
Find the 2nd nearest value from a given value in an array. (★★☆)

````julia
inputVal = 0.5;
vA = rand(10);

vA[sortperm(abs.(vA .- inputVal))[2]]
````

````
0.5947029703004421
````

Alternative way (More efficient)

````julia
closeFirst = Inf;
closeSecond = Inf;
closeFirstIdx = 0;
closeSecondIdx = 0;

# Using `global` for scope in Literate
for (elmIdx, elmVal) in enumerate(abs.(vA .- inputVal))
if (elmVal < closeFirst)
global closeSecond = closeFirst;
global closeFirst = elmVal;
global closeSecondIdx = closeFirstIdx;
global closeFirstIdx = elmIdx;
elseif (elmVal < closeSecond)
global closeSecond = elmVal;
global closeSecondIdx = elmIdx;
end
end

vA[closeSecondIdx] == vA[sortperm(abs.(vA .- inputVal))[2]]
````

````
true
````

By [Tomer Arnon](https://github.com/tomerarnon):

````julia
vA[partialsortperm(abs.(vA .- inputVal), 2)]
````

````
0.5947029703004421
````

## Question 062
Considering two arrays with shape `(1, 3)` and `(3, 1)`, Compute their sum using an iterator. (★★☆)

````julia
vA = rand(1, 3);
vB = rand(3, 1);

sum(aVal + bVal for aVal in vA, bVal in vB)
````

````
11.149909948305584
````

## Question 063
Create an array class that has a name attribute. (★★☆)

One could use `NamedArrays.jl` or `AxisArrays.jl`.

## Question 064
Given a vector, add `1` to each element indexed by a second vector (Be careful with repeated indices). (★★★)

````julia
vA = rand(1:10, 5);
vB = rand(1:5, 3);

println(vA);

# Julia is very efficient with loops
for bIdx in vB
vA[bIdx] += 1;
end

println(vA);
````

````
[1, 6, 2, 6, 2]
[3, 7, 2, 6, 2]

````

## Question 065
Accumulate elements of a vector `X` to an array `F` based on an index list `I`. (★★★)

````julia
vX = rand(1:5, 10);
vI = rand(1:15, 10);

numElements = maximum(vI);
vF = zeros(numElements);

for (ii, iIdx) in enumerate(vI)
vF[iIdx] += vX[ii];
end

println("vX: $vX");
println("vI: $vI");
println("vF: $vF");
````

````
vX: [5, 4, 3, 5, 2, 5, 2, 5, 5, 1]
vI: [3, 2, 6, 11, 12, 10, 5, 11, 12, 2]
vF: [0.0, 5.0, 5.0, 0.0, 2.0, 3.0, 0.0, 0.0, 0.0, 5.0, 10.0, 7.0]

````

One could also use `counts()` from `StatsBase.jl`.

## Question 066
Considering an image of size `w x h x 3` image of type `UInt8`, compute the number of unique colors. (★★☆)

````julia
mI = rand(UInt8, 1000, 1000, 3);

numColors = length(unique([reinterpret(UInt32, [iPx[1], iPx[2], iPx[3], 0x00])[1] for iPx in eachrow(reshape(mI, :, 3))])); # 1, vF[ii] / vN[ii], vF[ii]);
end

println("vX: $vX");
println("vI: $vI");
println("vF: $vF");
````

````
vX: [5, 5, 4, 2, 1, 1, 3, 5, 3, 2]
vI: [14, 7, 8, 10, 5, 10, 14, 2, 7, 13]
vF: [0.0, 5.0, 0.0, 0.0, 1.0, 0.0, 4.0, 4.0, 0.0, 1.5, 0.0, 0.0, 2.0, 4.0]

````

## Question 069
Get the diagonal of a matrix product. (★★★)

````julia
mA = rand(5, 7);
mB = rand(7, 4);

numDiagElements = min(size(mA, 1), size(mB, 2));
vD = [dot(mA[ii, :], mB[:, ii]) for ii in 1:numDiagElements]
````

````
4-element Vector{Float64}:
1.8937792321469207
1.035584608236753
2.0251852803210024
2.2065505485118653
````

Alternative way:

````julia
vD = reshape(sum(mA[1:numDiagElements, :]' .* mB[:, 1:numDiagElements], dims = 1), numDiagElements)
````

````
4-element Vector{Float64}:
1.8937792321469207
1.035584608236753
2.0251852803210024
2.2065505485118653
````

## Question 070
Consider the vector `[1, 2, 3, 4, 5]`, build a new vector with 3 consecutive zeros interleaved between each value. (★★★)

````julia
vA = 1:5;

# Since Julia is fast with loops, it would be the easiest choice

numElements = (4 * length(vA)) - 3;
vB = zeros(Int, numElements);

for (ii, bIdx) in enumerate(1:4:numElements)
vB[bIdx] = vA[ii];
end
println(vB);

# Alternative (MATLAB style) way:

mB = [reshape(collect(vA), 1, :); zeros(Int, 3, length(vA))];
vB = reshape(mB[1:(end - 3)], :);
println(vB);
````

````
[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5]
[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5]

````

## Question 071
Consider an array of dimension `5 x 5 x 3`, mulitply it by an array with dimensions `5 x 5` using broadcasting. (★★★)

````julia
mA = rand(5, 5, 3);
mB = rand(5, 5);

mA .* mB # [2], [2] -> [3], [3] -> [1])
mC = [sort!([vC[mod1(ii, end)], vC[mod1(ii + 1, end)]]) for ii in 1:(size(mA, 2) + 1), vC in eachrow(mA)][:] # w[-1, -1] + w[-1, 0] + w[-1, 1] + w[0, -1] + w[0, 1] + w[1, -1] + w[1, 0] + w[1, 1];
gofNumLives = round(Int, 0.05 * numRows * numCols);
gofNumGenerations = 50;

vI = randperm(numRows * numCols)[1:gofNumLives];

mG = zeros(UInt8, numRows, numCols);
mG[vI] .= UInt8(1);
mB = similar(mG);

heatmap(mG) #= 3) || ((mB[ii] > 0) && (mB[ii] == 2))); #= vA.vX[end])
return vA.vY[end];
end
if (ii <= vA.vX[1])
return vA.vY[1];
end

rightIdx = findfirst(vA.vX .>= ii);
leftIdx = rightIdx - 1;

tt = (ii - vA.vX[leftIdx]) / (vA.vX[rightIdx] - vA.vX[leftIdx]);

return ((1 - tt) * vA.vY[leftIdx]) + (tt * vA.vY[rightIdx]);

end
function Base.setindex!(vA::LinearInterpolator1D, valX, valY, ii::Int, jj::Int)
setindex!(sLinInterp.vX, valX, ii);
setindex!(sLinInterp.vY, valY, ii);
end

vXInt = LinearInterpolator1D(vR, vX);
vYInt = LinearInterpolator1D(vR, vY);

vXSegment = [vXInt[intIdx] for intIdx in vRSegment];
vYSegment = [vYInt[intIdx] for intIdx in vRSegment];

hP = lineplot(vX, vY, canvas = DotCanvas, name = "Samples");
lineplot!(hP, vXSegment, vYSegment, name = "Interpolated");
hP
````

````
┌────────────────────────────────────────┐
10 │ ..:│ Samples
│ ...'' │ Interpolated
│ .:'' │
│ .: │
│ .: │
│ .:''' │
│ :' │
│ ..:' │
│ :'' │
│ ....: │
│ ..: │
│ :'''' │
│ .:'' │
│ .:' │
0 │..:' │
└────────────────────────────────────────┘
0 10
````

**Remark**: In order to be mathematically accurate the resolution of `vRSegment` must be high enough to be an integer factor of each segment.
It can be done if the resolution is `1 / (prod(vR))` which is easily infeasible with `Float64`. So this is a good enough approximation.

## Question 099
Given an integer `n` and a 2D array `mA`, find the rows which can be interpreted as draws from a multinomial distribution with `n` (Rows which only contain integers and which sum to `n`). (★★★)

````julia
mA = rand([0, 0.5, 1, 2, 3], 15, 3);
sumVal = 4;
vI = [all(vA .== round.(vA)) && sum(vA) == sumVal for vA in eachrow(mA)];
````

## Question 100
Compute bootstrapped `95%` confidence intervals for the mean of a 1D array `vA`. Namely, resample the elements of an array with replacement `N` times, compute the mean of each sample and then compute percentiles over the means. (★★★)

````julia
numTrials = 10000;
numSamples = 1000;
μ = 0.5;

vA = μ .+ randn(numSamples);
tM = (mean(vA[rand(1:numSamples, numSamples)]) for _ in 1:numTrials);
quantile(tM, [0.025, 0.975])
````

````
2-element Vector{Float64}:
0.4620914889349693
0.5830619321705541
````

---

*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*