Sage gyakorlat
Kezelőfelület:
Segítség a parancsokhoz:
1 |
[69, 59, 88, 45, 15] |
[15, 45, 59, 69, 88] |
Régóta megoldatlan sejtés, hogy a következő szabályok ismétlésével minden egész számból indítva el az 1-hez jutunk:
- ha a szám páros, akkor osszuk el 2-vel
- ha a szám páratlan, akkor szorozzuk meg 3-mal és adjunk hozzá egyet.
Írjunk egy harom(n) nevű függvényt, amely egy listában visszaadja a megtett lépéseket egészen 1-ig.
|
[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1] |
|
True |
|
11010111 |
Az all parancs egy listát kér paraméterként és akkor tér vissza True-val, ha a kapott lista minden eleme logikailag igaz, egyébként False eredményt ad.
True |
False |
Az any parancs akkor ad vissza True értékkel, ha a paraméterként adott lista legalább egyik eleme True, különben False értéket ad vissza.
True |
A str(123) eredménye '123' lesz. A stringen a for ciklus karakterenként megy végig:
1 2 3 |
A csupanullaegy(n) függvény rövidebb megírása (True-val tér vissza, ha n minden számjegye 0 vagy 1):
|
True |
False |
A permutations(l) az l listának az összes lehetséges permutációit adja vissza.
A combinations(l,k) az l lista összes k-asával tér vissza.
[[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3], [1, 2, 3, 0], [1, 3, 0, 2], [1, 3, 2, 0], [2, 0, 1, 3], [2, 0, 3, 1], [2, 1, 0, 3], [2, 1, 3, 0], [2, 3, 0, 1], [2, 3, 1, 0], [3, 0, 1, 2], [3, 0, 2, 1], [3, 1, 0, 2], [3, 1, 2, 0], [3, 2, 0, 1], [3, 2, 1, 0]] |
[[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 1, 5], [0, 2, 3], [0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [0, 4, 5], [1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]] |
A nyolc királynő problémát szeretnénk megoldani rövidebb kóddal, mint az elődáson tettük. Ehhez tekintsük a range(8) lista permutációit, például az x=[6,3,4,1,5,2,7,0] elemet. Ehhez az x-hez rendeljünk hozzá a bábuk egy állását: az i-edik oszlopban lévő királynőt tegyük az x[i]-edik sorba. Természetesen most a sorokat és az oszlopokat is 0-tól kezdjük sorszámozni.
Szeretnénk meghatározni a királynők összes jó lepakolását. Mindegyik oszlopban egy királynő lesz (az i. oszlopban az x[i]. sorban), így az oszlopok rendben lesznek. Egy soron belül sem lehet két királynő, mivel a [0,1,2,3,4,5,6,7] halmaz egy permutációját nézzük. Már csak az átlók helyességét kell megnéznünk.
Két királynő átlóban akkor üti egymást, ha az oszlopuk sorszámának abszolútértékes különbsége megegyezik a soraik sorszámának abszolútértékes különbségével. Ezt egyszerűen tudjuk ellenőrizni: i-vel és j-vel is végigmegyünk az összes oszlopon (ez összesen 8*8=64 lehetőség), és ha abs(i-j) != abs(x[i]-x[j]), akkor az i. és j. oszlopban lévő királynők nem ütik egymást.
Arra kell még figyelnünk, hogy i==j esetén nincs mit vizsgálnunk az átlókkal kapcsolatban. Azon eseteket íratjuk ki, ahol az összes i,j párosra teljesül a feltétel:
[0, 4, 7, 5, 2, 6, 1, 3] [0, 5, 7, 2, 6, 3, 1, 4] [0, 6, 3, 5, 7, 1, 4, 2] [0, 6, 4, 7, 1, 3, 5, 2] [1, 3, 5, 7, 2, 0, 6, 4] [1, 4, 6, 0, 2, 7, 5, 3] [1, 4, 6, 3, 0, 7, 5, 2] [1, 5, 0, 6, 3, 7, 2, 4] [1, 5, 7, 2, 0, 3, 6, 4] [1, 6, 2, 5, 7, 4, 0, 3] [1, 6, 4, 7, 0, 3, 5, 2] [1, 7, 5, 0, 2, 4, 6, 3] [2, 0, 6, 4, 7, 1, 3, 5] [2, 4, 1, 7, 0, 6, 3, 5] [2, 4, 1, 7, 5, 3, 6, 0] [2, 4, 6, 0, 3, 1, 7, 5] [2, 4, 7, 3, 0, 6, 1, 5] [2, 5, 1, 4, 7, 0, 6, 3] [2, 5, 1, 6, 0, 3, 7, 4] [2, 5, 1, 6, 4, 0, 7, 3] [2, 5, 3, 0, 7, 4, 6, 1] [2, 5, 3, 1, 7, 4, 6, 0] [2, 5, 7, 0, 3, 6, 4, 1] [2, 5, 7, 0, 4, 6, 1, 3] [2, 5, 7, 1, 3, 0, 6, 4] [2, 6, 1, 7, 4, 0, 3, 5] [2, 6, 1, 7, 5, 3, 0, 4] [2, 7, 3, 6, 0, 5, 1, 4] [3, 0, 4, 7, 1, 6, 2, 5] [3, 0, 4, 7, 5, 2, 6, 1] [3, 1, 4, 7, 5, 0, 2, 6] [3, 1, 6, 2, 5, 7, 0, 4] [3, 1, 6, 2, 5, 7, 4, 0] [3, 1, 6, 4, 0, 7, 5, 2] [3, 1, 7, 4, 6, 0, 2, 5] [3, 1, 7, 5, 0, 2, 4, 6] [3, 5, 0, 4, 1, 7, 2, 6] [3, 5, 7, 1, 6, 0, 2, 4] [3, 5, 7, 2, 0, 6, 4, 1] [3, 6, 0, 7, 4, 1, 5, 2] [3, 6, 2, 7, 1, 4, 0, 5] [3, 6, 4, 1, 5, 0, 2, 7] [3, 6, 4, 2, 0, 5, 7, 1] [3, 7, 0, 2, 5, 1, 6, 4] [3, 7, 0, 4, 6, 1, 5, 2] [3, 7, 4, 2, 0, 6, 1, 5] [4, 0, 3, 5, 7, 1, 6, 2] [4, 0, 7, 3, 1, 6, 2, 5] [4, 0, 7, 5, 2, 6, 1, 3] [4, 1, 3, 5, 7, 2, 0, 6] [4, 1, 3, 6, 2, 7, 5, 0] [4, 1, 5, 0, 6, 3, 7, 2] [4, 1, 7, 0, 3, 6, 2, 5] [4, 2, 0, 5, 7, 1, 3, 6] [4, 2, 0, 6, 1, 7, 5, 3] [4, 2, 7, 3, 6, 0, 5, 1] [4, 6, 0, 2, 7, 5, 3, 1] [4, 6, 0, 3, 1, 7, 5, 2] [4, 6, 1, 3, 7, 0, 2, 5] [4, 6, 1, 5, 2, 0, 3, 7] [4, 6, 1, 5, 2, 0, 7, 3] [4, 6, 3, 0, 2, 7, 5, 1] [4, 7, 3, 0, 2, 5, 1, 6] [4, 7, 3, 0, 6, 1, 5, 2] [5, 0, 4, 1, 7, 2, 6, 3] [5, 1, 6, 0, 2, 4, 7, 3] [5, 1, 6, 0, 3, 7, 4, 2] [5, 2, 0, 6, 4, 7, 1, 3] [5, 2, 0, 7, 3, 1, 6, 4] [5, 2, 0, 7, 4, 1, 3, 6] [5, 2, 4, 6, 0, 3, 1, 7] [5, 2, 4, 7, 0, 3, 1, 6] [5, 2, 6, 1, 3, 7, 0, 4] [5, 2, 6, 1, 7, 4, 0, 3] [5, 2, 6, 3, 0, 7, 1, 4] [5, 3, 0, 4, 7, 1, 6, 2] [5, 3, 1, 7, 4, 6, 0, 2] [5, 3, 6, 0, 2, 4, 1, 7] [5, 3, 6, 0, 7, 1, 4, 2] [5, 7, 1, 3, 0, 6, 4, 2] [6, 0, 2, 7, 5, 3, 1, 4] [6, 1, 3, 0, 7, 4, 2, 5] [6, 1, 5, 2, 0, 3, 7, 4] [6, 2, 0, 5, 7, 4, 1, 3] [6, 2, 7, 1, 4, 0, 5, 3] [6, 3, 1, 4, 7, 0, 2, 5] [6, 3, 1, 7, 5, 0, 2, 4] [6, 4, 2, 0, 5, 7, 1, 3] [7, 1, 3, 0, 6, 4, 2, 5] [7, 1, 4, 2, 0, 6, 3, 5] [7, 2, 0, 5, 1, 4, 6, 3] [7, 3, 0, 2, 5, 1, 6, 4] CPU time: 2.93 s, Wall time: 3.00 s |
|
|
A következőkben egy négyzet alakú pályán megpróbálunk eljutni a start mezőről a cel mezőre. A szabály a következő: a négy szomszédos mezők valamelyikére léphetünk, ha ott nem X áll. (X jelképezi a falat.) Azt fogjuk megválaszolni, hogy mennyi a legrövidebb út start és cel között.
A pálya:
|
A join függvény egy szövegekből álló listát vár, eredményül a sztringek egymás után fűzését adja vissza. Második paraméterként megadhatjuk a szeparáló szöveget is, ami alapértelmezés szerint egy space.
'a bb' |
'abb' |
'a---b---cc' |
Szeretnénk a pályát jól ábrázolni, ebben lesz segítségünkre a kiir függvény. A későbbiekben szeretnénk meghívni olyan listával, amely tartalmaz számokat is, ezért nem print join(x) -szel írjuk ki az x sort, hanem str-rel átkonvertáljuk stringgé az összes elemet:
|
0 X . . . X . X . . X . . . . . |
A start koordináta (ez a [0,0] lesz) pozíciójába 0-t fogunk írni, mivel ez a mező 0 lépés után elérhető. A k értéke legyen 0, mivel eddig 0 a legnagyobb kitöltött számjegy.
A lépés legyen a következő: megkeressük az összes olyan mezőt, ahol '.' áll és van k-t tartalmazó szomszédja. Az ilyen mezőkre k+1-et írunk. Ezt valósítja meg a lepes(l,k) függvény.
Első lépésként készítünk a listánkból egy másolatot, mivel nem szeretnénk az l listát módosítani az algoritmus során.
|
Az előző függvényben egy érdekes dolog történt: (i+1<n and r[i+1][j] ==k) rész kiértékelésénél érvényesül a lusta kiértékelés. A python nem számol ki olyan dolgot, amit nem kell. Ha kíváncsi az A and B értékére, és kiszámolta, hogy A hamis, akkor nem fogja B-t kiszámolni (hiszen az értéke úgysem befolyásolna semmit). Itt is ezt használjuk: ha i+1<n nem teljesül, akkor r[i+1][j] ==k nem értékelődik ki (még jó, mert n. eleme az r listának már nem lenne, és hibát kapnánk).
l[0][0] értékét ideiglenes 0-ra állítjuk, hogy lássuk az algoritmus futásának eredményét:
0 X . . 1 X . X . . X . . . . . |
l értékét visszaállítom:
|
A következő folyam(s,start,cel) függvényben kiszámoljuk az l által meghatározott térképben start és cél távolságát. Először is készítünk s-ről egy másolatot l-be, majd beállítjuk a kezdő pozíciót 0-ra. Ezután addig iteráljuk a lepes függvényt, amíg különbözőt listát ad vissza. Ha már ugyanazt adja vissza, akkor a lépésekkel eljutottunk mindenhova. A kiir függvénnyel kiírjuk a végső pályát és visszaadjuk a cel által meghatározott helyen lévő elemet. Ez vagy az a szám, ahány lépésből elérhető a start pontból, vagy '.', ha nem elérhető.
|
0 X . . 1 X . X 2 3 X 7 3 4 5 6 7 |
|
|
Az önhasonló halmazokat meg lehet adni a hasonlóságukat meghatározó iterált függvényrendszerükkel, illetve minden kontraktív iterált függvényrendszerhez tartozik egy egyértelmű nem üres kompakt (most itt ezek korlátos és zárt) halmaz. A lényeg: tekintsük a következő 3 leképezést:
(x,y) -> (x/2,y/2)
(x,y) -> (x/2+1/2,y/2)
(x,y) -> (x/2,y/2+1/2)
A káosz játékot fogjuk játszani. Induljunk ki egy tetszőleges pontból, majd válasszunk véletlenszerűen a leképezések közül. A bejárt pontokat megjelenítjük.
|
|
|
A véletlen "garantálja", hogy a fraktál így kirajzolódjon. Ha mindig az első függvényt választottuk volna, akkor nem kapnánk ilyen szép képet.
A Koch-görbe függvényrendszere már kicsit bonyolultabb. Az s változót előre definiálom (bár ilyet nem szoktunk csinálni) azért, hogy ne számolja ki minden egyes alkalommal a cos(pi/6) értékét. Azért használok n() függvényt, hogy lebegőpontos értékekkel számoljon végig.
|
|
|