R1PE57JCHTD5V
Obrazek przedstawia dane zgromadzone w plikach na dyskach oraz w chmurze

PY_I_R_W13A_M08 Pliki na maturze

Grafika wygenerowana przez sztuczną inteligencją Leonardo.ai
Źródło: domena publiczna.

Zadanie 1. Piksele

Zadanie zostało opracowane przez Centralną Komisję Egzaminacyjną i pojawiło się na egzaminie maturalnym z informatyki w maju 2017 roku (poziom rozszerzony, egzamin w tzw. nowej formule). Cały arkusz można znaleźć na stronie internetowej CKE. Omówimy tu rozwiązania dwóch podpunktów tego zadania.

W pliku dane.txt znajduje się 200 wierszy. Każdy wiersz zawiera 320 liczb naturalnych z przedziału od 0 do 255, oddzielonych znakami pojedynczego odstępu (spacjami). Przedstawiają one jasności kolejnych pikseli czarno‑białego obrazu o wymiarach 320 na 200 pikseli (od 0 – czarny do 255 – biały).

Napisz program(y), który(e) da(dzą) odpowiedzi do poniższych zadań. Odpowiedzi zapisz w pliku wyniki6.txt, a każdą odpowiedź poprzedź numerem oznaczającym odpowiednie zadanie.

Uwaga: plik przyklad.txt zawiera dane przykładowe spełniające warunki zadania (obraz ma takie same rozmiary). Odpowiedzi dla danych z pliku przyklad.txt są podane pod poleceniami.

Plik przyklad.txt:

R11dFVCOytFZv

Przycisk do pobrania pliku TXT z treścią zadania.

Plik TXT o rozmiarze 126.21 KB w języku polskim

Plik dane.txt:

R1SoEVmFcg11G

Przycisk do pobrania pliku TXT z treścią zadania.

Plik TXT o rozmiarze 223.62 KB w języku polskim

Rozwiązanie przedstawiamy w formie pseudokodu. Twoim zadaniem będzie jego implementacja w języku Python.

Zadanie 1.1

Podaj jasność najjaśniejszego i jasność najciemniejszego piksela.

Dla danych z pliku przyklad.txt wynikiem jest 255 (najjaśniejszy) i 0 (najciemniejszy).

Do oceny oddajesz:

  • plik wyniki6.txt zawierający odpowiedź (numer zadania, wartości najjaśniejszego i najciemniejszego piksela, zapisane w osobnych liniach),

  • plik(i) z komputerową realizacją zadania (kodem programu).

Rozwiąż zadanie dla kompletnych danych wejściowych załączonych powyżej. Rozwiązanie przedstaw w wybranym języku programowania, dostępnym na egzaminie maturalnym: C++Java lub Python. Zadbaj o prawidłowe wczytanie danych z pliku tekstowego do programu. Odpowiedź do zadania znajdziesz w osobnym pliku, umieszczonym pod omówieniem rozwiązania.

Rozwiązanie

Zaczniemy od wczytania danych z pliku  listy list (Python).

Ważne!

Przedstawione fragmenty kodu pokazują, jak wczytać dane z podanego pliku wiersz po wierszu i zmienić je na liczby całkowite. W rozwiązaniu dodaliśmy instrukcje wypisujące wczytane liczby na standardowym wyjściu.

W języku  Python dane z pliku czytamy wiersz po wierszu, liczby z każdego odczytanego wiersza otrzymujemy w postaci tablicy lub listy zwracanej za pomocą funkcji split(), która dzieli podany ciąg znaków za pomocą podanego separatora.

W języku Python nie używa się tablic o określonym z góry rozmiarze, struktury służące do przechowywania wielu elementów, np. listy, są dynamiczne. W podanym niżej rozwiązaniu ciągi znaków zwrócone przez metodę split() przekształcamy na liczby całkowite w wyrażeniu listowym, a uzyskaną listę zapisujemy w liście dane.

Linia 1. dane znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy kratka lista do zapisania list z odczytanymi liczbami. Linia 2. with open otwórz nawias okrągły cudzysłów dane kropka txt cudzysłów przecinek cudzysłów r cudzysłów przecinek encoding znak równości cudzysłów utf minus 8 cudzysłów zamknij nawias okrągły as plik dwukropek. Linia 3. for wiersz in plik dwukropek. Linia 4. dane kropka append otwórz nawias okrągły otwórz nawias kwadratowy int otwórz nawias okrągły liczba zamknij nawias okrągły for liczba in wiersz kropka split otwórz nawias okrągły cudzysłów cudzysłów zamknij nawias okrągły zamknij nawias kwadratowy zamknij nawias okrągły. Linia 5. kratka wypisanie wczytanych liczb. Linia 7. for liczby in dane dwukropek. Linia 8. print otwórz nawias okrągły otwórz nawias ostrokątny em zamknij nawias ostrokątny liczby zamknij nawias okrągły otwórz nawias ostrokątny prawy ukośnik em zamknij nawias ostrokątny.

Znalezienie piksela o najmniejszej wartości (najciemniejszego) i o największej wartości (najjaśniejszego)

Linia 1. MIN ← dane otwórz nawias kwadratowy 0 zamknij nawias kwadratowy otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 2. MAX ← dane otwórz nawias kwadratowy 0 zamknij nawias kwadratowy otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 4. dla i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 199 wykonuj. Linia 5. dla j znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 319 wykonuj. Linia 6. jeżeli dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy zamknij nawias ostrokątny MAX. Linia 7. MAX ← dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 8. jeżeli dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny MIN. Linia 9. MIN ← dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy.

Najpierw ustalamy początkowe wartości zmiennych MINMAX. W obu przypadkach będzie to wartość pierwszego elementu tablicy.

Następnie iterujemy po tablicy dwuwymiarowej dane[200][320] i w przypadku, gdy znajdziemy wartość większą od wartości MAX, nadpisujemy wartość zmiennej MAX, nadając jej wartość równą dane[i][j].

Szukanie najciemniejszego piksela jest bardzo podobne. Sprawdzamy, czy aktualnie iterowany element tablicy dwuwymiarowej jest mniejszy od MIN – jeżeli tak, nadpisujemy wartość zmiennej MIN (nadajemy jej wartość dane[i][j])

Oto cały pseudokod:

Linia 1. dane otwórz nawias kwadratowy 0 kropka kropka 199 zamknij nawias kwadratowy otwórz nawias kwadratowy 0 kropka kropka 319 zamknij nawias kwadratowy. Linia 3. dla i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 199 wykonuj. Linia 4. wczytaj kolejną linię z pliku. Linia 5. dla j znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 319 wykonuj. Linia 6. dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy ← wczytaj kolejną liczbę z linii. Linia 8. MIN ← dane otwórz nawias kwadratowy 0 zamknij nawias kwadratowy otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 9. MAX ← dane otwórz nawias kwadratowy 0 zamknij nawias kwadratowy otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 11. dla i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 199 wykonuj. Linia 12. dla j znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 319 wykonuj. Linia 13. jeżeli dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy zamknij nawias ostrokątny MAX. Linia 14. MAX ← dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 15. jeżeli dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny MIN. Linia 16. MIN ← dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy.

Schemat punktowania

  • 2 pkt – za prawidłową odpowiedź, w tym:

    • 1 pkt – za podanie wartości najjaśniejszego piksela

    • 1 pkt – za podanie wartości najciemniejszego piksela

  • 0 pkt – za odpowiedź błędną albo za brak odpowiedzi

Poprawna odpowiedź

Wartość najjaśniejszego piksela 221.

Wartość najciemniejszego piksela 7.

Prawidłowa odpowiedź do zadania 1.1 dla danych zapisanych w pliku dane.txt tekstowym znajduje się w załączniku:

REAz8DjOxRzy6

Przycisk do pobrania pliku TXT z wynikiem zadania.

Plik TXT o rozmiarze 9.00 B w języku polskim

Zadanie 1.2

Podaj, ile wynosi najmniejsza liczba wierszy, które należy usunąć, żeby obraz miał pionową oś symetrii. Obraz ma pionową oś symetrii, jeśli w każdym wierszu i‑ty piksel od lewej strony przyjmuje tę samą wartość, co i‑ty piksel od prawej strony, dla dowolnego 1 ≤ i ≤ 320. Dla danych z pliku przyklad.txt wynikiem jest 3.

Do oceny oddajesz:

  • plik wyniki6.txt zawierający odpowiedź (numer zadania i liczba wierszy do usunięcia w osobnych wierszach, dopisane do pliku utworzonego w zadaniu 1.1),

  • plik(i) z komputerową realizacją zadania (kodem programu).

Rozwiąż zadanie dla kompletnych danych wejściowych, znajdujących się w pliku załączonym powyżej. Rozwiązanie przedstaw w wybranym języku programowania, dostępnym na egzaminie maturalnym: C++Java lub Python. Zadbaj o prawidłowe wczytanie danych z pliku tekstowego do programu. Odpowiedź do zadania znajdziesz w osobnym pliku umieszczonym pod omówieniem rozwiązania.

Rozwiązanie

Operujemy na tablicy dwuwymiarowej dane[200][320], do której zostały zapisane dane z pliku tekstowego (wczytanie danych przedstawione jest w rozwiązaniu zadania 1.1).

Linia 1. doUsuniecia ← 0. Linia 3. dla i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 199 wykonuj. Linia 4. k ← 319. Linia 5. dla j znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek 159 wykonuj. Linia 6. jeżeli dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy ≠ dane otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy k zamknij nawias kwadratowy. Linia 7. doUsuniecia ← doUsuniecia plus 1. Linia 8. wyjdź z pętli. Linia 9. k ← k minus 1.

Deklarujemy zmienną doUsuniecia, która będzie zliczać linie niespełniające kryterium pionowej osi symetrii. Jako wartość początkową nadajemy jej wartość 0.

Następnie w pętli zewnętrznej przeglądamy kolejne wiersze tablicy dwuwymiarowej dane[200][320]. W pętli wewnętrznej sprawdzamy symetryczność analizowanego wiersza pikseli. Oznacza to, że musimy sprawdzić symetryczność par pikseli równoodległych od badanej pionowej osi symetrii, czyli zweryfikować, czy te wiersze są palindromami. Liczba par do sprawdzenia jest równa połowie rozmiaru wiersza, co wyznacza również ograniczenie wartości iteratora pętli.

  • element o indeksie 0 z elementem o indeksie 319;

  • element o indeksie 1 z elementem o indeksie 318;

  • element o indeksie 3 z elementem o indeksie 317;

...

  • element o indeksie 159 z elementem o indeksie 160.

Jeżeli wykryjemy, że elementy porównywane nie są równe, oznacza to, że dana para zaburza oś symetrii i cały wiersz jest do usunięcia. Wówczas dokonujemy inkrementacji zmiennej doUsuniecia oraz wychodzimy z pętli (ponieważ w danym wierszu nie ma już potrzeby, aby sprawdzać inne wartości pikseli).

Schemat punktowania

  • 2 pkt – za poprawną odpowiedź

  • 0 pkt – za odpowiedź błędną lub brak odpowiedzi

Uwaga: Nie przyznaje się 1 pkt.

Poprawna odpowiedź

149

Dla zainteresowanych

Przekierowanie standardowego wejścia i wyjścia

Oprócz przedstawionych rozwiązań możliwe jest również przekierowanie standardowego wejścia i wyjścia na wskazane pliki podczas uruchamianiu kodu z poziomu linii poleceń. Operatorem przekierowania standardowego wejścia jest operator <, natomiast operatorem przekierowania standardowego wyjścia jest operator >.

W języku Python można dane czytać ze standardowego strumienia wejścia sys.stdin, jednak kiedy dane znajdują się w pliku, lepiej użyć modułu fileinput i metody input():

Linia 1. import fileinput. Linia 3. dane znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy kratka lista do przechowywania list z odczytanymi liczbami. Linia 4. for wiersz in fileinput kropka input otwórz nawias okrągły zamknij nawias okrągły dwukropek. Linia 5. dane kropka append otwórz nawias okrągły otwórz nawias kwadratowy int otwórz nawias okrągły liczba zamknij nawias okrągły for liczba in wiersz kropka split otwórz nawias okrągły cudzysłów cudzysłów zamknij nawias okrągły zamknij nawias kwadratowy zamknij nawias okrągły. Linia 6. kratka wypisanie wczytanych liczb. Linia 8. for liczby in dane dwukropek. Linia 9. print otwórz nawias okrągły otwórz nawias ostrokątny em zamknij nawias ostrokątny liczby zamknij nawias okrągły otwórz nawias ostrokątny prawy ukośnik em zamknij nawias ostrokątny.

Polecenie uruchomienia skryptu z wejściem przekierowanym na plik dane.txt, a wyjściem na plik wyniki.txt wydajemy w terminalu:

Linia 1. python3 kropka prawy ukośnik plik podkreślnik z podkreślnik kodem kropka py otwórz nawias ostrokątny dane kropka txt zamknij nawias ostrokątny wyniki kropka txt.

W systemie Windows po standardowej instalacji interpreter Pythona wywoływany jest przez polecenie python, a nie python3.

Do pliku wyniki.txt zapisane zostaną wszystkie komunikaty z instrukcji print().

Słownik

inkrementacja
inkrementacja

zwiększenie danej wartości o jeden

oś symetrii
oś symetrii

prosta, względem której dane dwie figury są symetryczne

piksel
piksel

(ang. pixel) najmniejsza jednolita część obrazu wyświetlanego na ekranie monitora, drukowanego lub wyświetlanego przy użyciu specjalistycznych urządzeń (aparatów cyfrowych i tym podobnych)