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).
- Host: GitHub
- URL: https://github.com/RoyiAvital/Julia100Exercises
- Owner: RoyiAvital
- License: unlicense
- Created: 2022-03-29T17:43:13.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-12-07T18:01:03.000Z (over 1 year ago)
- Last Synced: 2024-02-09T18:04:19.793Z (5 months ago)
- Topics: exercise, julia, questions-and-answers, self-learning, self-study
- Language: Julia
- Homepage:
- Size: 245 KB
- Stars: 105
- Watchers: 9
- Forks: 17
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Lists
- awesome-100-knock - GitHub - RoyiAvital/Julia100Exercises: A set of introductory exercises for Julia
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
25julia> +(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);
endClosestValue(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;
endnumPixels = 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
endvA[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;
endprintln(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];
endprintln("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]);
endprintln("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];
endrightIdx = 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);
endvXInt = 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).*