1. Domácí úkol: Eulerova a Carmichaelova funkce
Úvod
Cílem prvního úkolu je seznámit se se základy Julia (podmínky, cykly, metody, atp.), typového systému se dotkneme jen částečně a necháme si ho hlavně na další úkoly. Vypracování tohoto úkolu by vám nemělo zabrat příliš času.
Cvičnými objekty v tomto úkolu pro nás budou Eulerova a Carmichaelova funkce, které se objevují a používají v problémech souvisejících s teorií čísel. V tomto prvním jednodušším úkolu se budeme zabývat jejich implementací v Julia.
Funkce jsou pojmenovány po Leonhardovi Eulerovi (nejen matematik žijící v osmnáctém století, původem ze Švýcarska) a Robertu Carmichaelovi (americký matematik žijící v devatenáctem a dvacátem století).
Teoretický background
Pro kladné celé definujeme hodnotu Eulerovy funkce jakožto počet přirozených čísel mezi a (včetně mezí), která jsou nesoudělná s (dvě celá čísla a jsou nesoudělná, právě když jejich největší společný dělitel je roven , tj. ). Například tedy platí
Pro kladné celé definujeme hodnotu Carmichaelovy funkce jakožto nejmenší kladné celé , pro které platí rovnosti (tj. zbytek po dělení čísla číslem je roven )
pro všechna kladná celá menší než a nesoudělná s . Například tedy platí
Implementační pokyny
V souboru main.jl
doplňte implementaci funkcí euler
(Eulerova funkce ) a carmichael
(Carmichaelova funkce ), které budou přijímat kladná celá čísla nebo vektory kladných celých čísel a počítat odpovídající funkční hodnoty.
Pokud je na vstupu vektor, tak ho naše implementace nebude modifikovat, ale vrátí nový vektor s napočítanými hodnotami.
Například
julia> include("main.jl")
julia> euler(6)
2
julia> euler(7)
6
julia> euler([6, 7])
2-element Vector{Int64}:
2
6
julia> carmichael(big"123456")
5136
julia> carmichael(UInt64[1, 2, 3, 4])
4-element Vector{Int64}:
1
1
2
2
Další ukázky lze nalézt v přiložených testech v adresáři test
.
V případě neceločíselného typu argumentu (např. float nebo řetězec) dojde k vyvolání výjimky MethodError
.
Pokud je argument záporný celočíselný, pak dostaneme výjimku ArgumentError
.
Věnujte péči výpočtu zbytku po dělení mocniny v Carmichaelově funkci (tj. vyhněte se nutnosti explicitně počítat , N.B.: ).
V implementaci můžete použít metodu gcd
pro výpočet nejmenšího společného dělitele, která je dostupná v prostředí Julia a poradí si s mnoha různými datovými typy (vytvářet vlastní implementaci nejmenšího společného dělitele tedy nemusíte).
Metoda musí být typově stabilní.
Tj. pokud dostaneme argument typu např. UInt64
, pak návratová hodnota je také typu UInt64
.
Svou implementaci můžete lokálně snadno otestovat příkazem julia test/runtests.jl
, výstup by měl vypadat přibližně takto:
$ julia test/runtests.jl
┌ Info:
│ Running tests in test_carmichael.jl...
└ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Test Summary: | Pass Total Time
Carmichael's function: types of argument | 4 4 0.2s
Test Summary: | Pass Total Time
Carmichael's function: first few values | 11 11 0.0s
Test Summary: | Pass Total Time
Carmichael's function: vector argument | 2 2 0.1s
Test Summary: | Pass Total Time
Carmichael's function: various data types | 4 4 0.4s
┌ Info:
│ Running tests in test_euler.jl...
└ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Test Summary: | Pass Total Time
Euler's function: types of argument | 4 4 0.0s
Test Summary: | Pass Total Time
Euler's function: first few values | 10 10 0.0s
Test Summary: | Pass Total Time
Euler's function: vector argument | 2 2 0.0s
Test Summary: | Pass Total Time
Euler's function: various data types | 4 4 11.5s
Test Summary: | Pass Total Time
Euler's function: Multiplicativity test | 1 1 0.6s
Tyto testy se spouští i automaticky na Gitlabu.
Součástí vyhodnocení řešení bude porovnání rychlosti i robustnosti vaší implementace s ostatními studentskými řešeními.
Řešení a odevzdání
Opět vytvořte větev odvozenou z větve assignment/01-functions
a nezvěte ji solution/01-functions
.
Do solution/01-functions
vložte své řešení editací souboru main.jl
případně přidáním testů do složky test
.
Až budete se svým řešením spokojeni, vytvořte MR (to můžete i dříve, aspoň uvidíte výsledek testů, pokud je nespouštíte lokálně) a přiřaďte mě k němu jako assignee
.
Tímto aktem úkol odevzdáte.