Kurzusok
/
Elixir
Elixir
/
Feladatok
/
Festés számok szerint
Festés számok szerint

Festés számok szerint

Tanulófeladat

Bevezetés

Bitstringek

A bináris adatokkal való munka minden nyelvben fontos fogalom, és az Elixir elegáns szintaxist kínál a bináris adatok írásához, illesztéséhez és felépítéséhez.

Az Elixirben a bináris adatokat bitstring típusnak nevezik. A bináris adat típusa (amit nem szabad összekeverni a bináris adatokkal általában) a bitstring egy speciális formája, amelyről egy későbbi feladatban lesz szó.

A bitstring literálokat a <<>> speciális formával definiáljuk. Amikor egy bitstring literált definiálunk, az szegmensekben épül fel. Minden szegmensnek van értéke és típusa, amelyeket a :: operátor választ el egymástól. A típus határozza meg, hogy hány bitet használunk az érték kódolására. A típus teljesen elhagyható, ilyenkor alapértelmezés szerint egy 8 bites egész értéket kapunk.

# This defines a bitstring with three segments of a single bit each
<<0::1, 1::1, 0::1>>

A ::1 típus megadása rövidítése a ::size(1) írásmódnak. Ha a bitméret egy változóból származik, a hosszabb szintaxist kell használnod.

Bináris

Amikor bináris egész literálokat írunk, közvetlenül 2-es alapú jelöléssel is leírhatjuk őket, ha a literál elé 0b-t teszünk. Ne feledd, hogy ezek ettől függetlenül tízes számrendszerbeli számként jelennek meg, amikor a tesztek eredményében vagy az iexben kiíródnak.

<<0b1011::4>> == <<11::4>>
# => true

Csonkolás

Ha a szegmens értéke meghaladja a szegmens típusának kapacitását, akkor az érték balról csonkolódik.

<<0b1011::3>> == <<0b0011::3>>
# => true

Elé és mögé fűzés

A speciális formával egy meglévő bitstring elé és mögé is fűzhetsz. Ha a meglévő bitstring mérete ismeretlen, akkor a ::bitstring típust kell használnod rajta.

value = <<0b110::3, 0b001::3>>
new_value = <<0b011::3, value::bitstring, 0b000::3>>
# => <<120, 8::size(4)>>

Összefűzés

A speciális formával összefűzhetjük a változókban tárolt bitstringeket. Két ismeretlen méretű bitstring összefűzésekor a ::bitstring típust kell használni.

first = <<0b110::3>>
second = <<0b001::3>>
concatenated = <<first::bitstring, second::bitstring>>
# => <<49::size(6)>>

Mintaillesztés

A speciális formából mintaillesztéssel is kinyerhetsz értékeket. Minden egyes kimenteni kívánt darabhoz tudnod kell a bitek számát, egyetlen kivétellel: a ::bitstring típus használható ismeretlen méretű bitstringre való mintaillesztésre, de ez csak az utolsó darabnál alkalmazható.

<<value::4, rest::bitstring>> = <<0b01101001::8>>
value == 0b0110
# => true

Bitstringek vizsgálata

Note

A bitstringek a létrehozásukhoz használt formátumtól eltérő formátumban is megjelenhetnek (a tesztfuttató vagy az iex által kiírva). Ez gyakran zavart okoz, amikor az ember éppen a bitstringeket tanulja.

Alapértelmezés szerint a bitstringek 8 bites (egy byte-os) darabokban jelennek meg, még akkor is, ha más méretű darabokkal hoztad létre őket.

<<2011::11>>
# => <<251, 3::size(3)>>

Ha olyan bitstringet hozol létre, amely egy nyomtatható UTF-8 kódolású stringet reprezentál, az stringként jelenik meg.

<<>>
# => ""

<<65, 66, 67>>
# => "ABC"

Utasítások

A számfestés (más néven színezés számok alapján) olyan fekete-fehér képek, amelyeket színezésre szántak. A kép különböző területeit különböző számok jelölik, a számok egy előre meghatározott színpaletta adott színeinek felelnek meg. A cél, hogy a területeket a megfelelő színekkel töltsd ki, és a végén egy gyönyörű, színes kép táruljon fel. Ez egy pihentető tevékenység gyerekeknek és felnőtteknek egyaránt.

Az a feladatod, hogy írj egy számfestő alkalmazást Elixirben. Azt szeretnéd, hogy az alkalmazásod egy egyedi adatformátumban tudjon képeket importálni és exportálni. Úgy döntöttél, hogy bináris fájlokban tárolod a képeid adatait.

Note

Ez a feladat feltételezi, hogy ismered a bináris számokat, és érted, milyen elvek alapján lehet a bináris számokat tízes számrendszerbeli számokká és a tízes számrendszerbeli számokat bináris számokká alakítani.

Képzeljük el, hogy van egy képed egy mosolygó arcról, mint amilyen lentebb látható. A kép háttere fehér. A mosolygó arcnak fekete a körvonala, és sárga a kitöltő színe.

Ez a kép 3 színt használ. Rendeljünk indexeket ezekhez a színekhez:

  • 0 (bináris: 0b00) a fehérhez,
  • 1 (bináris: 0b01) a feketéhez,
  • 2 (bináris: 0b10) a sárgához.

Ezekkel a színindexekkel most már ábrázolhatjuk az egyes pixelek színét.

Mosolygó arc Mosolygó arc színindexekkel

1. A paletta bitméretének kiszámítása

Valósítsd meg a PaintByNumber.palette_bit_size/1 függvényt. A palettában lévő színek számát kapja meg, és adja vissza, hogy hány bitre van szükség ennyi színindex bináris számként való ábrázolásához. A színindexek mindig 0-tól kezdődnek, és folytonos, növekvő egész számok.

Például 13 különböző szín ábrázolásához 4 bitre van szükség. 4 biten legfeljebb 16 színindex tárolható (2^4). 3 bit nem lenne elég, mert 3 biten csak legfeljebb 8 színindex tárolható (2^3).

PaintByNumber.palette_bit_size(13)
# => 4

Megjegyzés: az Elixir standard könyvtárában nincs log2 függvény. Később megtanulod, hogyan használhatod az Erlang-könyvtárakat Elixirből, ahol megtalálod ezt a függvényt. Most viszont rekurzióval és a hatványoperátorral ** oldd meg ezt a feladatot.

2. Üres kép létrehozása

Valósítsd meg a PaintByNumber.empty_picture/0 függvényt. Egy üres bitstringgel kell visszatérnie.

3. Tesztkép létrehozása

Az alkalmazásod alapfunkcióinak manuális teszteléséhez egy előre meghatározott tesztképet fogunk használni. A tesztkép 4 pixelből áll, 4 különböző színnel.

Valósítsd meg a PaintByNumber.test_picture/0 függvényt. Egy 4 szegmensből álló bitstringgel kell visszatérnie. Minden szegmens bitmérete 2 legyen. A szegmensek értéke 0, 1, 2 és 3 legyen.

4. Egy pixel hozzáadása a kép elejéhez

Valósítsd meg a PaintByNumber.prepend_pixel/3 függvényt. Három argumentumot kap: egy bitstringet azzal a képpel, amelynek az elejére fűzünk, a paletta színeinek számát, valamint az új pixel színének indexét. Egy bitstringgel kell visszatérnie, amely azt a képet tartalmazza, amelynek az elejére hozzáadtuk az új pixelt.

picture = <<2::4, 0::4>>
color_count = 13
pixel_color_index = 11

PaintByNumber.prepend_pixel(picture, color_count, pixel_color_index)
# => <<178, 0::size(4)>>
# (which is equal to <<11::4, 2::4, 0::4>>)

5. Az első pixel kiolvasása egy képből

Valósítsd meg a PaintByNumber.get_first_pixel/2 függvényt. Két argumentumot kap: egy bitstringet azzal a képpel, amelyből olvasunk, és a paletta színeinek számát. A megadott kép első pixelének színindexével kell visszatérnie. Üres kép esetén nil-t kell visszaadnia.

picture = <<19::5, 2::5, 18::5>>
color_count = 20

PaintByNumber.get_first_pixel(picture, color_count)
# => 19

6. Az első pixel eltávolítása egy képből

Valósítsd meg a PaintByNumber.drop_first_pixel/2 függvényt. Két argumentumot kap: egy bitstringet azzal a képpel, amelyből eltávolítunk egy pixelt, és a paletta színeinek számát. A képpel kell visszatérnie, de az első pixel nélkül. Üres kép esetén üres képpel kell visszaadnia.

picture = <<2::3, 5::3, 5::3, 0::3>>
color_count = 6

PaintByNumber.drop_first_pixel(picture, color_count)
# => <<180, 0::size(1)>>
# (which is equal to <<5::3, 5::3, 0::3>>)

7. Két kép összefűzése

Valósítsd meg a PaintByNumber.concat_pictures/2 függvényt. Két argumentumot kap, két bitstringet. Azzal a bitstringgel kell visszatérnie, amely az első argumentumnak a második elé fűzésének eredménye.

picture1 = <<52::6, 51::6>>
picture2 = <<0::6, 34::6, 12::6>>

PaintByNumber.concat_pictures(picture1, picture2)
# => <<211, 48, 34, 12::size(6)>>
# (which is equal to <<52::6, 51::6, 0::6, 34::6, 12::6>>)
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Elixir Exercism

Készen állsz elkezdeni a(z) Festés számok szerint feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Elixir nyelvet 58 fogalom168 feladat segítségével, valódi emberi mentorálással, mindez ingyen.