Globálne nastavenie Chunkov

V nižšie uvedenom Chunku je urobené základné globálne nastavenie Chunkov v celom Notebooku.

  • echo nastavuje, či chceme v Notebooku vypisovať jednotlivé kódy R
  • message je nastavený na FALSE, čo znamená, že sa budú potláčať pracovné výstupy z R, t.j. napríklad výsledok otvárania knižníc, a niektoré iné výstupy, ktoré ale pre celkový Notebook nemajú takmer žiaden význam a sú vhodné skôr pri ladení kódov.
  • warning nastavený na FALSE potláča zobrazenie chybových hlášok
knitr::opts_chunk$set(
  echo = TRUE,
  message = FALSE,
  warning = FALSE
)
Error in loadNamespace(x) : there is no package called ‘knitr’

Úvod k základným operáciám v R

Tento notebook demonštruje základné operácie v jazyku R so:

  • skalárnymi číslami (t.j. 1 číslo),
  • textovými (znakovými) reťazcami,
  • logickými (boolovskými) hodnotami a premennými,
  • (numerickými) vektormi,
  • maticami.

Tam, kde je to užitočné, sú zahrnuté malé cvičenia.


Skaláre (jednočíselné hodnoty)

Numerické skaláre

Poznámky

  • ^ operátor umocňovania.
  • %% je modulo, teda zbytok po delení,
  • round(x, digits = 0) zaokrúhľovanie na určitý počet desatinných miest (digits=). ak digits = 0, potom ide o celočíselné zaokrúhľovanie

Malé cvičenie

Vypočítajte:

\[\frac{(15^2-4)}{7}\]


Text

Vytváranie textovými premennými a práca s nimi

Dĺžka textového reťazca, podreťazec

Tip: Knižnica stringr mnohé zaujímavé možnosti práce s textami, ale implicitné knižnice R pokrývajú väčšinu bežných potrieb páce s textami.


Logické (boolovské) hodnoty a premenné

Základy

Logický výsledok porovnávania

Zložitejšie logické operácie

Zlučovanie viacerých log. premenných do vektora


Numerické vektory

Generovanie vektorov

Aritmetické operácie s vektormi

Matematické operácie s 2 vektormi rovnakého rozmeru

Indexovanie a výber niektorych prvkov vektora

Práca s chýbajúcimi hodnotami

Základné štatistiky a usporiadanie prvkov vektora podľa veľkosti

Malé cvičenie

Vytvorte vektor w s číslami 1..20 a vypočítajte sumu všetkých párnych čísel.


Matice

Vytvorenie matíc

Rozmery matice

Adresovanie prvkov matice

Maticové operácie

Zlučovanie vektorov do matíc

Vypočítanie zvolenej štatistiky po riadkoch (stĺpcoch) matice

Malé cvičenie

Vytvorte maticu 5x5 s hodnotami po riadkoch 1..25, vypočítajte stĺpcové sumy a súčin matíc \(M^t M\).


Príklad 1 – Skaláre a matematické operácie

definovanie premennych

a <- 12 b <- 5

zakladne operacie

sum_ab <- a + b diff_ab <- a - b prod_ab <- a * b quot_ab <- a / b mod_ab <- a %% b

matematicky vyraz

result <- (a^2 + b^2) / (a - b)

sum_ab diff_ab prod_ab quot_ab mod_ab result

Príklad 2 – Text a logické operácie

textove premenne

meno <- “Martin” priezvisko <- “Novak”

spojenie textu

cele_meno <- paste(meno, priezvisko)

dlzka textu

nchar(cele_meno)

prvych 5 znakov

substr(cele_meno, 1, 5)

logicke porovnanie

meno == “Peter”

Príklad 3 – Vektory a matice

vektor

v <- 1:10

parne cisla

even_numbers <- v[v %% 2 == 0]

suma parnych cisel

sum(even_numbers)

vytvorenie matice

M <- matrix(1:9, nrow = 3)

suma riadkov

apply(M, 1, sum)

M

LS0tCnRpdGxlOiAiWsOha2xhZG7DqSBvcGVyw6FjaWUgdiBSIgphdXRob3I6ICJWbGFkaW3DrXIgR2F6ZGEgIDxicj4KKHMgdnl1xb5pdMOtbSBDaGF0R1BUKSIKZGF0ZTogIlNlcHRlbWJlciAyMDI1IgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdGhlbWU6IHVuaXRlZAogICAgaGlnaGxpZ2h0OiB0YW5nbwplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogNzIKLS0tCgojIEdsb2LDoWxuZSBuYXN0YXZlbmllIENodW5rb3YKClYgbmnFvsWhaWUgdXZlZGVub20gQ2h1bmt1IGplIHVyb2JlbsOpIHrDoWtsYWRuw6kgZ2xvYsOhbG5lIG5hc3RhdmVuaWUgQ2h1bmtvdiB2IGNlbG9tIE5vdGVib29rdS4gCgotICoqZWNobyoqIG5hc3RhdnVqZSwgxI1pIGNoY2VtZSB2IE5vdGVib29rdSB2eXBpc292YcWlIGplZG5vdGxpdsOpIGvDs2R5IFIKLSAqKm1lc3NhZ2UqKiBqZSBuYXN0YXZlbsO9IG5hICpGQUxTRSosIMSNbyB6bmFtZW7DoSwgxb5lIHNhIGJ1ZMO6IHBvdGzDocSNYcWlIHByYWNvdm7DqSB2w71zdHVweSB6IFIsIHQuai4gbmFwcsOta2xhZCB2w71zbGVkb2sgb3R2w6FyYW5pYSBrbmnFvm7DrWMsIGEgbmlla3RvcsOpIGluw6kgdsO9c3R1cHksIGt0b3LDqSBhbGUgcHJlIGNlbGtvdsO9IE5vdGVib29rIG5lbWFqw7ogdGFrbWVyIMW+aWFkZW4gdsO9em5hbSBhIHPDuiB2aG9kbsOpIHNrw7RyIHByaSBsYWRlbsOtIGvDs2Rvdi4KLSAqKndhcm5pbmcqKiBuYXN0YXZlbsO9IG5hIEZBTFNFIHBvdGzDocSNYSB6b2JyYXplbmllIGNoeWJvdsO9Y2ggaGzDocWhb2sKCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1UUlVFLGVjaG89VFJVRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UKKQpgYGAKCiMgw5p2b2QgayB6w6FrbGFkbsO9bSBvcGVyw6FjacOhbSB2IFIKClRlbnRvIG5vdGVib29rIGRlbW9uxaF0cnVqZSAqKnrDoWtsYWRuw6kgb3BlcsOhY2llKiogdiBqYXp5a3UgUiBzbzoKCi0gc2thbMOhcm55bWkgxI3DrXNsYW1pICh0LmouIDEgxI3DrXNsbyksCi0gdGV4dG92w71taSAoem5ha292w71taSkgcmXFpWF6Y2FtaSwKLSBsb2dpY2vDvW1pIChib29sb3Zza8O9bWkpIGhvZG5vdGFtaSBhIHByZW1lbm7DvW1pLAotIChudW1lcmlja8O9bWkpIHZla3Rvcm1pLAotIG1hdGljYW1pLgoKVGFtLCBrZGUgamUgdG8gdcW+aXRvxI1uw6ksIHPDuiB6YWhybnV0w6kgbWFsw6kgY3ZpxI1lbmlhLgoKLS0tCgojIFNrYWzDoXJlIChqZWRub8SNw61zZWxuw6kgaG9kbm90eSkKCiMjIE51bWVyaWNrw6kgc2thbMOhcmUKCmBgYHtyfQojIFByaXJhZGVuaWUga29uxaF0YW50eSBkbyBwcmVtZW5uZWoKYSA8LSA3CmIgPC0gMy41CgojIEFyaXRobWV0aWMKc3VtX2FiICAgICAgPC0gYSArIGIgICAgICAgICMgc3VjZXQKZGlmZl9hYiAgICAgPC0gYSAtIGIgICAgICAgICMgcm96ZGllbApwcm9kX2FiICAgICA8LSBhICogYiAgICAgICAgIyBuw6Fzb2JlbmllCnF1b3RfYWIgICAgIDwtIGEgLyBiICAgICAgICAjIGRlbGVuaWUKcG93ZXJfYWIgICAgPC0gYSBeIGIgICAgICAgICMgdW1vY8WIb3ZhbmllCm1vZF9hYiAgICAgIDwtIGEgJSUgMyAgICAgICAjIHpieXRvayBwbyBkZWxlbsOtIHRyb21pICh0enYgbW9kdWxvKQoKCiMgUm91bmRpbmcKcm91bmRfYiAgIDwtIHJvdW5kKGIpICAgICAgICMgemFva3J1aGxvdmFuaWUgc21lcm9tIGsgbmFqYmxpenNpZW11IGNlbGVtdSBjaXNsdQpjZWlsX2IgICAgPC0gY2VpbGluZyhiKSAgICAgIyBuYWpibGl6c2llIHZ5c3NpZSBjZWxlIGNpc2xvCmZsb29yX2IgICA8LSBmbG9vcihiKSAgICAgICAjIG5hamJsaXpzaWUgbml6c2llIGNlbGUgY2lzbG8KCmE7IGIKc3VtX2FiOyBkaWZmX2FiOyBwcm9kX2FiOyBxdW90X2FiOyBwb3dlcl9hYjsgbW9kX2FiOyBpbnRfZGl2X2FiCnJvdW5kX2I7IGNlaWxfYjsgZmxvb3JfYgpgYGAKCioqUG96bsOhbWt5KioKCi0gYF5gIG9wZXLDoXRvciB1bW9jxYhvdmFuaWEuCi0gYCUlYCBqZSBtb2R1bG8sIHRlZGEgemJ5dG9rIHBvIGRlbGVuw60sIAotIGByb3VuZCh4LCBkaWdpdHMgPSAwKWAgemFva3LDumjEvm92YW5pZSBuYSB1csSNaXTDvSBwb8SNZXQgZGVzYXRpbm7DvWNoIG1pZXN0IChkaWdpdHM9KS4gYWsgZGlnaXRzID0gMCwgcG90b20gaWRlIG8gY2Vsb8SNw61zZWxuw6kgemFva3LDumjEvm92YW5pZQoKCiMjIE1hbMOpIGN2acSNZW5pZQoKPiBWeXBvxI3DrXRhanRlOgoKJCRcZnJhY3soMTVeMi00KX17N30kJAoKYGBge3J9CigxNV4yIC0gNCkgLyA3CmBgYAoKLS0tCgojIFRleHQgCgojIyBWeXR2w6FyYW5pZSB0ZXh0b3bDvW1pIHByZW1lbm7DvW1pIGEgcHLDoWNhIHMgbmltaQoKYGBge3J9CmZpcnN0IDwtICJWbGFkaW1pciIgICAgICAgICAgICAgICAgICAgICAgICMgZGVmaW5vdmFuaWUgb2JzYWh1IHRleHRvdmVqIHByZW1lbm5laiBmaXJzdApsYXN0ICA8LSAiR2F6ZGEiICAgICAgICAgICAgICAgICAgICAgICAgICAjIGRlZmlub3ZhbmllIG9ic2FodSB0ZXh0LiBwcmVtZW5uZWogbGFzdApmdWxsICA8LSBwYXN0ZShmaXJzdCwgbGFzdCkgICAgICAgICAgICAgICAjIHNwb2plbmllIGR2b2NoIHRleHQuIHByZW1lbm55Y2ggZG8gamVkbmVqIChzIG1lZHplcm91KQpmdWxsX25vc3BhY2UgPC0gcGFzdGUwKGZpcnN0LCBsYXN0KSAgICAgICAjIHNwb2plbmllIGJleiBtZWR6ZXJ5CmNzdl9saW5lIDwtIHBhc3RlKCJhcHBsZSIsICJiYW5hbmEiLCAicGVhciIsIHNlcCA9ICIsIikgICMgc3BvamVuaWUgdGV4dG92IHMgb2RkZWxvdmFjb20gLApmaXJzdDsgbGFzdDsgZnVsbDsgZnVsbF9ub3NwYWNlOyBjc3ZfbGluZSAgICMgYm9ka2/EjWlhcmthIHR1IG5haHJhZHp1amUgb2Rza29rIG5hIG5vdnkgcmlhZG9rIApgYGAKCiMjIETEusW+a2EgdGV4dG92w6lobyByZcWlYXpjYSwgcG9kcmXFpWF6ZWMKCmBgYHtyfQp4IDwtICJSIGlzIGdyZWF0ISIKbmNoYXIoeCkgICAgICAgICAgICAgICAgICMgcG/EjWV0IHpuYWtvdiAgdiByZXRhemNpICJSIGlzIGdyZWF0ISIKc3Vic3RyKHgsIDEsIDUpICAgICAgICAgICMgcG9kcmXFpWF6ZWMgb2QgMS4gZG8gNS4gem5ha3UKYGBgCgoKPiBUaXA6IEtuacW+bmljYSAqKnN0cmluZ3IqKiBtbm9ow6kgemF1asOtbWF2w6kgbW/Fvm5vc3RpIHByw6FjZSBzIHRleHRhbWksIGFsZSBpbXBsaWNpdG7DqSBrbmnFvm5pY2UgUiBwb2tyw712YWrDuiB2w6TEjcWhaW51IGJlxb5uw71jaCBwb3RyaWViIHDDoWNlIHMgdGV4dGFtaS4KCi0tLQoKIyBMb2dpY2vDqSAoYm9vbG92c2vDqSkgaG9kbm90eSBhIHByZW1lbm7DqQoKIyMgWsOha2xhZHkKCmBgYHtyfQpwIDwtIFRSVUUKcSA8LSBGQUxTRQohcCAgICAgICAgICAgICAgICAgIyBOT1QKcCAmIHEgICAgICAgICAgICAgICMgQU5ECnAgfCBxICAgICAgICAgICAgICAjIE9SCnhvcihwLCBxKSAgICAgICAgICAjIGV4Y2x1c2l2ZSBPUiAtIHBsYXTDrSBsZW4gamVkbm8geiBwLGFsZWJvIHEKYGBgCgojIyBMb2dpY2vDvSB2w71zbGVkb2sgcG9yb3Zuw6F2YW5pYQoKYGBge3J9CjMgPCA1CjcgPj0gNwoiY2F0IiA9PSAiY2F0IgoiY2F0IiAhPSAiZG9nIiAgICMgdnlrcmljbmlrIGplIHR1IHYgem15c2xlIG5lZ2FjaWUuIE5hcHIuOiAgICE9LCAhPiwgITwsICFUUlVFCiFUUlVFCmBgYAoKIyMgWmxvxb5pdGVqxaFpZSBsb2dpY2vDqSBvcGVyw6FjaWUKCmBgYHtyfQp4IDwtIDEwCnggPiA1ICYgeCA8IDIwICAgICAgIyBhIHN1Y2FzbmUgLSBsb2dpY2t5IHByaWVuaWsgKHN1Y2luKQp4IDwgMCB8IHggPiAxMDAgICAgICMgYWxlYm8gLSBsb2dpY2tlIHpqZWRub3RlbmllIChzdWNldCkKICAgICAgICAgICAgICAgICAgICAjIHByaSB6bG96aXRlanNpY2ggdnp0YWhvY2ggcG91eml2YWp0ZSB6YXR2b3JreSAoKQpgYGAKCiMjIFpsdcSNb3ZhbmllIHZpYWNlcsO9Y2ggbG9nLiBwcmVtZW5uw71jaCBkbyB2ZWt0b3JhCgpgYGB7cn0KdmFscyA8LSBjKFRSVUUsIEZBTFNFLCBUUlVFLCBUUlVFKSAgICMgZGVmaW5pY2lhIHZla3RvcmEgcyBsb2dpY2t5bWkgaG9kbm90YW1pCmBgYAoKLS0tCgojIE51bWVyaWNrw6kgdmVrdG9yeQoKIyMgR2VuZXJvdmFuaWUgdmVrdG9yb3YKCmBgYHtyfQp2MSA8LSBjKDIsIDQsIDYsIDgpCnYyIDwtIDE6NSAgICAgICAgICAgICAgICAgICMgcG9zdHVwbm9zdCAxLDIsMyw0LDUKdjMgPC0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGJ5ID0gMC4yNSkgICMgcG9zdHVwbm9zdCBzIGtyb2tvbSAwLjI1CnY0IDwtIHJlcCgzLCB0aW1lcyA9IDUpICAgICMgMywzLDMsMywzICAjIDUgY2xlbm5hIHBvc3R1cG5vc3QgdHJvamFrCnY1IDwtIHJ1bmlmKDUpICAgICAgICAgICAgICMgZ2VuZXJvdmFuaWUgcm92bm9tZXJuZSByb3pkZWxlbnljaCBwcmVtZW5ueWNoIHYgaW50ZXJ2YWxlIFswLDFdCnY2IDwtIHJub3JtKDUpICAgICAgICAgICAgICMgZ2VuZXJvdmFuaWUgbm9ybWFsbmUgcm96ZGVsZW55Y2ggcHJlbWVubnljaAp2MTsgdjI7IHYzOyB2NDsgdjUKYGBgCgojIyBBcml0bWV0aWNrw6kgb3BlcsOhY2llIHMgdmVrdG9ybWkKCmBgYHtyfQp2IDwtIGMoMSwgMiwgMywgNCkKdiArIDEwICAgICAgICAgICAjIGthemR5IHBydm9rIHZla3RvcmEgenZhY3NpbWUgbyAxMAp2ICogMiAgICAgICAgICAgICMga2F6ZHkgcHJ2b2sgdmVrdG9yYSBwcmVuYXNvYmltZSAyCih2ICsgMSkgLyAyCmV4cCh2KSAgICAgICAgICAgIyBleHBvbmVuY2lhbG5hIGZ1bmtjaWEgeiBrYXpkZWhvIHBydmt1IHZla3RvcmEKc3VtKGMoMSwyLDMpLGMoMSwxLDEpKSAgICAgICAgICAjIHNrYWxhcm55IHN1Y2luIC0gdnlzbGVkb2sgamUgc2thbGFyCmNyb3NzcHJvZChjKDEsMiwzKSxjKDEsMSwxKSkgICAgIyBza2FsYXJueSBzdWNpbiAtIHZ5c2xlZG9rIGplIG1hdGljYSAxeDEKYygxLDIsMykqYygxLDEsMSkgICAgICAgICAgICAgICAjIEhhZGFtYXJkb3Ygc3VjaW4gKHN1Y2luIHpvZHBvdmVkYWp1Y2ljaCBwcnZrb3YgdmVrdG9yYSkKYGBgCgojIyBNYXRlbWF0aWNrw6kgb3BlcsOhY2llIHMgMiB2ZWt0b3JtaSByb3ZuYWvDqWhvIHJvem1lcnUKCmBgYHtyfQpsZW5ndGgoYygxLDIsMyw0LDUpKQpsZW5ndGgodjUpICAgICAgICAgICAgI3Zla3RvciB2NSBqZSBkZWZpbm92YW55IHZ5c3NpZQpjKDEsMiwzLDQsNSkgKyB2NSAgICAgIyBwb3pvciwgb2JhIHZla3RvcnkgbXVzaWEgbWF0IHJvdm5ha3kgcm96bWVyCmBgYAoKIyMgSW5kZXhvdmFuaWUgYSB2w71iZXIgbmlla3RvcnljaCBwcnZrb3YgdmVrdG9yYQoKYGBge3J9CnggPC0gYyg1LCAxMiwgMywgMTgsIDcsIDAsIDIxKQp4WzFdICAgICAgICAgICAjIGluZGV4b3ZhbmllIC0gbm92eSBqZWRuby1wcnZrb3Z5IHZla3RvciAtIHBydnkgcHJ2b2sgdmVrdG9yYSB4CnhbMjo0XSAgICAgICAgICMgbm92eSB2ZWt0b3IgcyBkcnVoeW0gYXogc3R2cnR5bSBwcnZrb20gdmVrdG9yYSB4CnhbLTFdICAgICAgICAgICMgbm92eSB2ZWt0b3IgLSB2c2V0a3kgcHJ2a3kgdmVrdG9yYSB4IG9rcmVtIHBydsOpaG8KeFt4ID4gMTBdICAgICAgIyBub3Z5IHZla3RvciBkZWZpbm92YW55IHBydmthbWkgeCB2YWNzaW1pIGFrbyAxMAp3aGljaCh4ID4gMTApICAjIGt0b3JlIHBydmt5IHpvZHBvdmVkYWp1IHBvZG1pZW5rZSB2YWNzaWVobyBha28gMTA/CmBgYAoKIyMgUHLDoWNhIHMgY2jDvWJhasO6Y2ltaSBob2Rub3RhbWkKCmBgYHtyfQp5IDwtIGMoMSwgTkEsIDMsIE5BLCA1KQppcy5uYSh5KQptZWFuKHkpICAgICAgICAgICAgICAgICAjIE5BCm1lYW4oeSwgbmEucm0gPSBUUlVFKSAgICMgcmVtb3ZlIE5BcwpgYGAKCiMjIFrDoWtsYWRuw6kgxaF0YXRpc3Rpa3kgYSB1c3BvcmlhZGFuaWUgcHJ2a292IHZla3RvcmEgcG9kxL5hIHZlxL5rb3N0aQoKYGBge3J9CnogPC0gYygxMCwgMywgNSwgOCwgMikKbWVhbih6KSAgICAgICAgICAgICAgICAgIyBwcmllbWVybmEgaG9kbm90YQpzZCh6KSAgICAgICAgICAgICAgICAgICMgc3RhbmRhcmRuYSBvZGNoeWxrYQptYXgoeikgICAgICAgICAgICAgICAgICAjIG1heGltYWxuYSBob2Rub3RhCnN1bW1hcnkoeikgICAgICAgICAgICAgICMgcnljaGx5IHByZWhsYWQgemFrbGFkbnljaCBzdGF0aXN0aWsgbyB2ZWt0b3JlCnNvcnQoeikgICAgICAgICAgICAgICAgICMgcmFzdHVjZSB1c3BvcmlhZGFuaWUgCnNvcnQoeiwgZGVjcmVhc2luZyA9IFRSVUUpICAjIGtsZXNhanVjZQpgYGAKCiMjIE1hbMOpIGN2acSNZW5pZQo+IFZ5dHZvcnRlIHZla3RvciBgd2AgcyDEjcOtc2xhbWkgMS4uMjAgYSB2eXBvxI3DrXRhanRlIHN1bXUgdsWhZXRrw71jaCBww6FybnljaCDEjcOtc2VsLgoKYGBge3J9CncgPC0gMToyMApzdW0od1t3ICUlIDIgPT0gMF0pCmBgYAoKLS0tCgojIE1hdGljZQoKIyMgVnl0dm9yZW5pZSBtYXTDrWMKCmBgYHtyfQptIDwtIG1hdHJpeCgxOjEyLCBucm93ID0gMywgbmNvbCA9IDQpICAgICAgICAgICAgIyBob2Rub3R5IHPDuiB6YWRhdmFuZSBwbyBzdGxwY29jaAptX2J5cm93IDwtIG1hdHJpeCgxOjEyLCBucm93ID0gMywgYnlyb3cgPSBUUlVFKSAgIyBob2Rub3R5IHN1IHphZGF2YW5lIHBvIHJpYWRrb2NoCm07IG1fYnlyb3cKYGBgCgojIyBSb3ptZXJ5IG1hdGljZQoKYGBge3J9CmRpbShtKSAgICAgICAgICAgICAgICAgICAjIChyb3dzLCBjb2xzKQptCmBgYAoKIyMgQWRyZXNvdmFuaWUgcHJ2a292IG1hdGljZQoKYGBge3J9Cm1bMSwgMl0gICAgICAjIHJpYWRvayAxLCBzdGxwZWMgMgptWyAsIDNdICAgICAgIyB2c2V0a3kgcHJ2a3kgdiB0cmV0b20gc3RscGNpIC0gdnlzbGVkb2sgbWF0aWNhIDN4MQptWzIsIF0gICAgICAgIyB2c2V0a3kgcHJ2a3kgdiBkcnVob20gcmlhZGt1IC0gdnlzbGVkb2sgbWF0aWNhIDEqMwptWzE6MiwgMjozXSAgIyBwb2RtYXRpY2EgdHZvcmVuYSByaWFka2FtaSAxLCAyIGEgc3RscGNhbWkgMiwgMwpgYGAKCiMjIE1hdGljb3bDqSBvcGVyw6FjaWUKCmBgYHtyfQpBIDwtIG1hdHJpeChjKDEsMiwzLDQpLCBucm93ID0gMikKQiA8LSBtYXRyaXgoYyg1LDYsNyw4KSwgbnJvdyA9IDIpCgpBICsgQiAgICAgICAgIyBzY2l0YW5pZSBtYXRpYwpBICogQiAgICAgICAgIyBIYWRhbWFyZCBwcm9kdWN0IC0gbmFzb2JlbmllIHBvIHpvZHBvdmVkYWp1Y2ljaCBwcnZrb2NoCkEgJSolIEIgICAgICAjIG5hc29iZW5pZSBtYXRpYwp0KEEpICAgICAgICAgIyB0cmFuc3BvemljaWEgbWF0aWNlIEEgLSB2eW1lbmEgcmlhZGtvdiBhIHN0bHBjb3YKZGV0KEEpICAgICAgICMgZGV0ZXJtaW5hbnQgbWF0aWNlCnNvbHZlKEEpICAgICAjIGludmVyemlhIG1hdGljZSAoYWsgamUgbWF0aWNhIHJlZ3VsYXJuYSAtIHRlZGEgaW52ZXJ6aWEgc2EgZGEgc3BvY2l0YXQpCmBgYAoKIyMgWmx1xI1vdmFuaWUgdmVrdG9yb3YgZG8gbWF0w61jIAoKYGBge3J9CkMgPC0gY2JpbmQoMTozLCA0OjYpICAgIyAgLSBwbyBzdGxwY29jaCAKRCA8LSByYmluZCgxOjMsIDQ6NikgICAjICAtIHBvIHJpYWRrb2NoIApDOyBECmBgYAoKIyMgVnlwb8SNw610YW5pZSB6dm9sZW5laiDFoXRhdGlzdGlreSBwbyByaWFka29jaCAoc3TEunBjb2NoKSBtYXRpY2UKCmBgYHtyfQpNIDwtIG1hdHJpeCgxOjksIG5yb3cgPSAzKQpNCmFwcGx5KE0sIDEsIHN1bSkgICAjIHN1bWEgcG8gcmlhZGtvY2gKYXBwbHkoTSwgMiwgbWVhbikgICMgcHJpZW1lcnkgcG8gc3TEunBjb2NoCmBgYAoKIyMgTWFsw6kgY3ZpxI1lbmllCgo+IFZ5dHZvcnRlIG1hdGljdSA1eDUgcyBob2Rub3RhbWkgcG8gcmlhZGtvY2ggMS4uMjUsIHZ5cG/EjcOtdGFqdGUgc3TEunBjb3bDqSBzdW15IGEgc8O6xI1pbiBtYXTDrWMgXChNXnQgTVwpLgoKYGBge3J9Ck0yIDwtIG1hdHJpeCgxOjI1LCBucm93ID0gNSwgYnlyb3cgPSBUUlVFKQpjb2xTdW1zKE0yKQp0KE0yKSAlKiUgTTIKYGBgCgotLS0KCiMjIFByw61rbGFkIDEg4oCTIFNrYWzDoXJlIGEgbWF0ZW1hdGlja8OpIG9wZXLDoWNpZQoKIyBkZWZpbm92YW5pZSBwcmVtZW5ueWNoCmEgPC0gMTIKYiA8LSA1CgojIHpha2xhZG5lIG9wZXJhY2llCnN1bV9hYiA8LSBhICsgYgpkaWZmX2FiIDwtIGEgLSBiCnByb2RfYWIgPC0gYSAqIGIKcXVvdF9hYiA8LSBhIC8gYgptb2RfYWIgPC0gYSAlJSBiCgojIG1hdGVtYXRpY2t5IHZ5cmF6CnJlc3VsdCA8LSAoYV4yICsgYl4yKSAvIChhIC0gYikKCnN1bV9hYgpkaWZmX2FiCnByb2RfYWIKcXVvdF9hYgptb2RfYWIKcmVzdWx0CgojIyBQcsOta2xhZCAyIOKAkyBUZXh0IGEgbG9naWNrw6kgb3BlcsOhY2llCgojIHRleHRvdmUgcHJlbWVubmUKbWVubyA8LSAiTWFydGluIgpwcmllenZpc2tvIDwtICJOb3ZhayIKCiMgc3BvamVuaWUgdGV4dHUKY2VsZV9tZW5vIDwtIHBhc3RlKG1lbm8sIHByaWV6dmlza28pCgojIGRsemthIHRleHR1Cm5jaGFyKGNlbGVfbWVubykKCiMgcHJ2eWNoIDUgem5ha292CnN1YnN0cihjZWxlX21lbm8sIDEsIDUpCgojIGxvZ2lja2UgcG9yb3ZuYW5pZQptZW5vID09ICJQZXRlciIKCiMjIFByw61rbGFkIDMg4oCTIFZla3RvcnkgYSBtYXRpY2UKCiMgdmVrdG9yCnYgPC0gMToxMAoKIyBwYXJuZSBjaXNsYQpldmVuX251bWJlcnMgPC0gdlt2ICUlIDIgPT0gMF0KCiMgc3VtYSBwYXJueWNoIGNpc2VsCnN1bShldmVuX251bWJlcnMpCgojIHZ5dHZvcmVuaWUgbWF0aWNlCk0gPC0gbWF0cml4KDE6OSwgbnJvdyA9IDMpCgojIHN1bWEgcmlhZGtvdgphcHBseShNLCAxLCBzdW0pCgpNCgoK