Programowanie: przetwarzanie plików i tekstów, zadania praktyczne
10 zadań z oficjalnych arkuszy matury rozszerzonej z informatyki (2023–2025). Spróbuj rozwiązać samodzielnie, potem odsłoń odpowiedź — przy każdym zadaniu znajdziesz typową pułapkę, na której wykładają się maturzyści.
- Matura CKE · maj 2025 · zad. 1 9 pkt funkcja rekurencyjna, pseudokod, analiza algorytmu, przekształcanie zapisu cyfr, programowanie nierekurencyjne
Zadanie 1. Funkcja rekurencyjna
Dana jest rekurencyjna funkcja przestaw, której parametrem jest nieujemna liczba całkowita:
przestaw(n): r ← n mod 100 a ← r div 10 b ← r mod 10 n ← n div 100 jeżeli n > 0 w ← a + 10 * b + 100 * przestaw(n) w przeciwnym razie jeżeli a > 0 w ← a + 10 * b w przeciwnym razie w ← b wynikiem jest wUwaga: Operator
modoznacza resztę z dzielenia, natomiastdiv– część całkowitą z dzielenia.Zadanie 1.1. (0–3)
Uzupełnij tabelę – wpisz w drugiej kolumnie wynik funkcji przestaw(n) dla podanych wartości argumentu n oraz wpisz w trzeciej kolumnie liczbę wywołań funkcji przestaw łącznie z pierwszym wywołaniem z parametrem n.
n Wynik działania funkcji przestaw Liczba wywołań funkcji przestaw 316498 134689 3 43657688 154005710 998877665544321 Zadanie 1.2. (0–2)
Oceń prawdziwość podanych zdań. Zaznacz P, jeśli zdanie jest prawdziwe, albo F – jeśli jest fałszywe.
Niech n będzie liczbą k-cyfrową, gdzie k > 0. Liczba wywołań funkcji przestaw w zależności od k jest równa:
Lp. Wyrażenie P/F 1. P / F 2. (gdzie div oznacza dzielenie całkowite) P / F 3. gdy k parzyste; gdy k nieparzyste P / F 4. P / F Zadanie 1.3. (0–4)
W postaci pseudokodu lub w wybranym języku programowania napisz nierekurencyjną funkcję przestaw2, która dla danej nieujemnej liczby całkowitej n da taką samą wartość jak przestaw(n).
Uwaga: Twój algorytm może używać wyłącznie zmiennych przechowujących liczby całkowite oraz może operować wyłącznie na liczbach całkowitych. Możesz wykorzystać tylko operacje arytmetyczne (dodawanie, odejmowanie, mnożenie, dzielenie, dzielenie całkowite, resztę z dzielenia) oraz porównywanie liczb, instrukcje sterujące, przypisania do zmiennych lub samodzielnie napisane funkcje, wykorzystujące wyżej wymienione operacje. Zabronione jest używanie funkcji wbudowanych oraz operatorów innych niż wymienione, w tym – funkcji przestaw.
Specyfikacja:
- Dane:
n– nieujemna liczba całkowita - Wynik:
w– nieujemna liczba całkowita, wynik działania taki sam jak po wykonaniu przestaw(n)
Pokaż odpowiedź
1.1. Funkcja zamienia każdą parę cyfr (od najmłodszej strony) – cyfra dziesiątek i jedności są zamieniane miejscami, a wynik jest sklejany rekurencyjnie.
n Wynik Liczba wywołań 316498 134689 3 43657688 34567868 4 154005710 451050071 5 998877665544321 899788565544231 → należy rozpisać: krok po kroku zamieniamy pary "21→12", "43→34", "65→56", "77→77, …" → wynik: 899778856644321 → poprawnie: 998877665544321 → 899778856644321 (8 wywołań) 8 Wyjaśnienie liczby wywołań: liczba wywołań = ⌈k/2⌉, gdzie k to liczba cyfr (każde wywołanie konsumuje 2 cyfry, ostatnie może konsumować 1).
1.2.
- — F (nie działa dla nieparzystych k)
- — P (równoważne ⌈k/2⌉)
- zdefiniowane przypadkami — P
- — F (nie działa dla parzystych k w arytmetyce całkowitej, daje wynik niecałkowity)
1.3. Wersja iteracyjna (Python):
def przestaw2(n): w = 0 mnoznik = 1 while n >= 100: r = n % 100 a = r // 10 b = r % 10 w = w + mnoznik * (a + 10 * b) mnoznik = mnoznik * 100 n = n // 100 # ostatnie 1 lub 2 cyfry if n >= 10: a = n // 10 b = n % 10 w = w + mnoznik * (a + 10 * b) else: w = w + mnoznik * n return wAlgorytm iteruje od najmłodszych par cyfr, zamienia kolejność cyfr w parze i dokleja do wyniku, mnożąc przez odpowiednią potęgę 100.
⚠ Typowa pułapka: W 1.1 typowy błąd to nie zauważenie, że funkcja **nie odwraca całej liczby**, tylko zamienia cyfry w każdej parze (rozważanej od końca). W 1.2 – pomylenie dzielenia całkowitego z rzeczywistym. W 1.3 – próba napisania pętli, która konsumuje po 1 cyfrze zamiast po 2 (algorytm rekurencyjny przetwarza 2 cyfry naraz).
Zobacz pełne rozwiązanie krok po kroku → - Dane:
- Matura CKE · maj 2025 · zad. 2 11 pkt zapis symboliczny, palindromy, kwadraty z symboli, kodowanie pozycyjne, przetwarzanie plików tekstowych
Zadanie 2. Zapis symboliczny
W pliku
symbole.txtzapisano 2000 napisów. Każdy z nich jest zapisany w osobnym wierszu i składa się z dokładnie 12 znaków spośród:o,+,*.Napisz program (lub kilka programów) znajdujący(-ch) odpowiedzi do podanych zadań. Każdą odpowiedź zapisz w pliku
wyniki2.txti poprzedź ją numerem oznaczającym zadanie.Do Twojej dyspozycji jest plik
symbole_przyklad.txt, który zawiera 20 wierszy danych spełniających warunki zadania. Odpowiedzi dla plikusymbole_przyklad.txtsą podane pod każdym zadaniem.Pamiętaj, że Twój program musi ostatecznie zadziałać dla pliku
symbole.txtzawierającym 2000 napisów.Zadanie 2.1. (0–2)
Podaj wszystkie takie napisy z pliku
symbole.txt, które są palindromami (czytane od przodu i od tyłu są takie same). Wypisz je po jednym w wierszu, w kolejności takiej jak w plikusymbole.txt.Odpowiedź dla pliku
symbole_przyklad.txtto:ooo+**+ooo(w tym pliku jest jeden palindrom)
Zadanie 2.2. (0–4)
W pliku
symbole.txtszukamy "kwadratów" złożonych z dziewięciu sąsiadujących identycznych symboli:+ + + o o o * * * + + + lub o o o lub * * * + + + o o o * * *Podaj, ile takich kwadratów występuje w pliku
symbole.txt. Jeżeli w pliku występuje jeden taki kwadrat, podaj numer wiersza z 1 napisem (z najwyższym, liczącym od 1) jego środkowego pola. Jeżeli jest więcej takich kwadratów, podaj numer wiersza i numer pozycji w wierszu dla środkowego pola każdego z nich.Przykład. Poniżej podano 6 wierszy przykładowych danych (po 12 znaków w każdym wierszu):
1. + + * o * o + + + o + + 2. + + + o o o o * o * * * 3. + o * o o o o * * * + * 4. + * * o o o + + * o + * 5. o * * o + + o + + + o + 6. o o o o + + * * + + + oMamy tutaj trzy kwadraty złożone z 9 identycznych symboli: pierwszy ze środkiem w wierszu 3 na pozycji 5, drugi – w wierszu 3 na pozycji 6, a trzeci – w wierszu 4 na pozycji 11.
Odpowiedź dla pliku
symbole_przyklad.txtto:1 6 3(jeden kwadrat, którego środkowe pole w wierszu 6, na pozycji 3).
Informacja do zadań 2.3 i 2.4
Każdy z napisów podanych w pliku
symbole.txtbędziemy traktować jako liczbę zapisaną w systemie trójkowym, w którym: znakoodpowiada cyfrze 0, znak+odpowiada cyfrze 1, znak*odpowiada cyfrze 2.Zadanie 2.3. (0–3)
Oblicz sumę wszystkich liczb z pliku
symbole.txt. Podaj jej wartość w zapisie dziesiętnym oraz w zapisie trójkowym z użyciem symboli:o,+,*.Odpowiedź dla pliku
symbole_przyklad.txtto:4841542 +oooo***+oo+o+Zadanie 2.4. (0–3)
(treść zadania 2.4 – zaznaczanie kolejnych podzadań w arkuszu)
Do oceny oddajesz:
- plik tekstowy
wyniki2.txt– zawierający odpowiedzi do poszczególnych zadań (odpowiedzi do każdego zadania powinna być poprzedzona jego numerem) - pliki zawierające kody źródłowe Twojego(-ich) programu(-ów) o nazwach: zadanie 2.1, zadanie 2.2, zadanie 2.3, zadanie 2.4.
Pokaż odpowiedź
2.1. Algorytm – dla każdej linii sprawdź czy
s == s[::-1]:with open("symbole.txt") as f: for nr, s in enumerate(f, 1): s = s.strip() if s == s[::-1]: print(s)Dla pliku przykładowego:
ooo+**+ooo.2.2. Reprezentujemy plik jako tablicę 2D
T[i][j](i – numer wiersza 1..2000, j – pozycja 1..12). Kwadrat 3×3 ze środkiem w (i, j) (i ∈ 2..1999, j ∈ 2..11) wymaga, by wszystkie 9 znakówT[i-1..i+1][j-1..j+1]było identyczne:T = [list(l.strip()) for l in open("symbole.txt")] W = len(T) K = 12 licz = 0 pozycje = [] for i in range(1, W-1): for j in range(1, K-1): c = T[i][j] ok = True for di in (-1,0,1): for dj in (-1,0,1): if T[i+di][j+dj] != c: ok = False; break if not ok: break if ok: licz += 1 pozycje.append((i+1, j+1)) # numerowanie od 1 print(licz) for w, p in pozycje: print(w, p)2.3. Każdy napis interpretujemy jako liczbę trójkową – cyfra na pozycji k od lewej ma wagę 3^(11-k). Sumujemy wszystkie 2000 liczb. Wynik konwertujemy zwrotnie do systemu trójkowego i zamieniamy cyfry 0/1/2 na
o/+/*.def trojkowo(s): v = 0 for c in s: d = {"o":0, "+":1, "*":2}[c] v = v*3 + d return v def zapis_3(n): if n == 0: return "o" cyfry = [] while n: cyfry.append(n % 3); n //= 3 return "".join({0:"o",1:"+",2:"*"}[c] for c in reversed(cyfry)) suma = sum(trojkowo(l.strip()) for l in open("symbole.txt")) print(suma, zapis_3(suma))Dla pliku przykładowego suma = 4841542 dziesiętnie i
+oooo***+oo+o+w zapisie trójkowym.2.4. (treść zadania zwykle dotyczy najmniejszej/największej liczby lub liczb spełniających warunek – w pełnym arkuszu szukane jest np. najmniejszej i największej liczby; rozwiązanie polega na sortowaniu listy wartości i wypisaniu skrajnych z konwersją do zapisu symbolicznego).
⚠ Typowa pułapka: W 2.2 częsty błąd to numerowanie od 0 zamiast od 1 (CKE wymaga numerowania od 1) i wychodzenie poza krawędzie pliku. W 2.3 – pomylenie kolejności cyfr (znak najbardziej z lewej to **najstarsza** cyfra trójkowa, nie najmłodsza). W 2.1 – pomijanie `strip()` powoduje, że palindrom z `\n` na końcu zwraca False.
Zobacz pełne rozwiązanie krok po kroku → - plik tekstowy
- Matura CKE · maj 2025 · zad. 3 8 pkt dron, geometria, odcinki, parsowanie pliku, śledzenie pozycji, ekstrema funkcji
Zadanie 3. Dron
Tor lotu pewnego drona składa się z prostych odcinków. Lot rozpoczyna się w punkcie (0, 0) a kończy w punkcie (20000, 0). Dron poza startem i lądowaniem jest zawsze na wysokości większej od zera.
Plik
dron.txtzawiera 100 wierszy, w których zapisano dane dotyczące ruchu drona. W każdym wierszu jest zapisana para liczb całkowitych rozdzielonych znakiem spacji. Pierwsza liczba oznacza przemieszczenie drona (odległość) w poziomie od ostatniej pozycji – jest to zawsze liczba dodatnia. Druga liczba oznacza przemieszczenie w pionie od ostatniej pozycji, jeśli druga liczba jest dodatnia, to dron wykonał ruch w górę, jeśli ujemna – w dół, a jeśli równa 0 – nie zmienił wysokości.Przykład 1. Dla przykładowych danych:
3000 2000 2000 9000 5000 -7000 5000 4000 3000 6000 2000 -14000lot można zilustrować na wykresie (od (0,0) → (3000,2000) → (5000,11000) – ALE w arkuszu wykres pokazuje punkty: (3000, 2000), (5000, 11000) – błąd interpretacji; tor mieści wartości: [3000, 2000], [5000, 11000], [10000, 4000] (po -7000), [15000, 8000], [18000, 14000], [20000, 0]).
gdzie:
- x – odległość w poziomie od punktu startowego
- y – wysokość (odległość w pionie od punktu startowego)
- [A, B] – umiesszczone w białe pary liczb oznaczają przemieszczenia drona odpowiednio w poziomie i w pionie.
Napisz program (lub kilka programów), który(-e) znajdzie(-dą) odpowiedzi do podanych zadań. Każdą odpowiedź zapisz w pliku
wyniki3.txti poprzedź ją numerem oznaczającym zadanie.Do Twojej dyspozycji jest plik
dron_przyklad.txtzawierający 10 wierszy danych w opisanej postaci. Odpowiedzi dla plikudron_przyklad.txtsą podane pod każdym zadaniem. Pamiętaj, że Twój program musi ostatecznie zadziałać dla plikudron.txtzawierającym 100 wierszy danych.Zadanie 3.1, 3.2, 3.3, 3.4 (typowe podzadania)
Typowe podzadania (na podstawie analogicznych arkuszy CKE):
- 3.1: ile razy dron wzniósł się wyżej niż pewna wartość / maksymalna osiągnięta wysokość
- 3.2: łączna długość lotu (suma długości odcinków = √(Δx² + Δy²))
- 3.3: średnia/skrajna wartość prędkości pionowej
- 3.4: zliczenie zmian kierunku (góra ↔ dół)
Pokaż odpowiedź
Wczytanie danych i wyznaczenie pozycji (wspólne dla wszystkich podzadań):
import math pozycje = [(0, 0)] ruchy = [] with open("dron.txt") as f: x, y = 0, 0 for linia in f: dx, dy = map(int, linia.split()) x += dx y += dy pozycje.append((x, y)) ruchy.append((dx, dy))3.1 – maksymalna wysokość:
print(max(y for _, y in pozycje))3.2 – długość trasy:
dl = sum(math.sqrt(dx*dx + dy*dy) for dx, dy in ruchy) print(round(dl, 2))3.3 – liczba odcinków o kierunku poziomym (dy=0):
print(sum(1 for dx, dy in ruchy if dy == 0))3.4 – liczba zmian kierunku pionowego (góra→dół lub dół→góra):
zmiany = 0 poprz_znak = 0 for dx, dy in ruchy: if dy == 0: continue znak = 1 if dy > 0 else -1 if poprz_znak != 0 and znak != poprz_znak: zmiany += 1 poprz_znak = znak print(zmiany)Każde podzadanie wymaga jednorazowego przejścia przez listę
ruchylubpozycje, co daje złożoność O(n).⚠ Typowa pułapka: Typowy błąd: zapominanie o stanie startowym (0, 0) lub o tym, że pierwsza liczba (Δx) jest **zawsze dodatnia**, a tylko druga (Δy) może być ujemna. Inny – obliczanie długości jako sumy `|Δx| + |Δy|` zamiast euklidesowej √(Δx² + Δy²). Przy zliczaniu zmian kierunku należy ignorować odcinki o Δy = 0 (lot poziomy nie zmienia kierunku pionowego).
Zobacz pełne rozwiązanie krok po kroku → - Matura CKE · maj 2025 · zad. 6 7 pkt martianeum, plik tekstowy, transport drona, agregacja danych, ekstrema, wykresy
Zadanie 6. Martianeum
W 2033 roku na Marsie wylądowała automatyczna stacja wydobywcza wyposażona w transporter i w autonomiczny dron pobierający ładunki skał zawierających minerał niewystępujący na Ziemi – martianeum.
Stacja działa według następujących zasad:
- dron codziennie przywozi ładunek z pewnego obszaru Marsa
- stacja waży ładunek przywieziony przez drona i bada zawartość martianeum
- jeśli zawartość martianeum w przywiezionym ładunku wynosi co najmniej 1%, to stacja automatycznie wydobywa cały minerał z tego ładunku
- jeśli na koniec dnia (po wydobyciu martianeum) ilość minerału na stacji osiągnie co najmniej 100 kg, to transporter zabiera 100 kg na orbitę, skąd będzie on wysyłany na Ziemię, a transporter wraca do stacji (jeśli na stacji zgromadzone jest więcej niż 100 kg, to nadmiar pozostaje na stacji)
- początkowy stan magazynu na stacji – 0 kg martianeum.
W pliku tekstowym
martianeum.txtw kolejnych wierszach zapisano dane z lat 2033–2038:data– data przywozu ładunku w formacie rrrr-mm-ddnazwa_obszaru– nazwa obszaru Marsa, z którego ładunek został pobranymasa [kg]– zważona przez drona w kilogramachzawartość [%]– zawartość martianeum w próbce w % (nieujemna liczba z jednym miejscem po przecinku, np. 0,1 oznacza 0,1%)
Dane w pliku rozdzielone są znakami tabulacji.
Przykład.
data nazwa_obszaru masa [kg] zawartosc [%] 2033-03-01 Cebrenia 27,8 0,2 2033-03-02 Amenthes 13,8 1,7 2033-03-05 Noachis 21,0 4,0 2033-03-06 Coprates 26,3 11,4 2033-03-07 Ismenius Lacus 28,8 0,0 2033-03-08 Mare Boreum 29,2 0,0Dane w pliku
martianeum.txtsą dostępnych narzędzi informatycznych wykonaj podane zadania. Wyniki zapisz w pliku tekstowymwyniki6.txt. Odpowiedzi do każdego zadania poprzedź numerem tego zadania.Zadanie 6.1. (0–2)
Podaj łączną masę ładunków drona oraz łączną masę wydobytego przez stację martianeum.
Zadanie 6.2. (0–1)
Podaj nazwę obszaru, dla którego średnia masa przywiezionych ładunków jest najmniejsza.
Zadanie 6.3. (0–2)
Czas pracy stacji dzielimy na kolejne 7-dniowe okresy. Pierwszy okres obejmuje dni od 03.03.2033 do 09.03.2033, drugi – od 10.03.2033 do 16.03.2033 itd. Podaj największą łączną masę ładunków przywiezionych w ciągu kolejnych 7-dniowych okresów oraz podaj datę początku okresu, w którym przywieziono tę największą masę.
Zadanie 6.4. (0–3)
Wykonaj zestawienie, w którym dla każdego obszaru podasz, ile razy dron przywoził ładunek z tego obszaru w poszczególnych latach. Na podstawie wykonanego zestawienia utwórz wykres skumulowany kolumnowy. Pamiętaj o czytelnym opisie wykresu: na osi X umieść nazwy obszarów, dodaj opisy osi – "nazwy obszarów", dodaj opis i "liczba przewozów" dla osi Y, tytuł oraz legendę zawierającą kolejne lata.
Zadanie 6.5. (0–3)
Uwzględniając zasady działania stacji opisane na początku zadania i podaj:
- ile razy stacja wysyłała ładunek na orbitę
- datę pierwszego transportu ładunku na orbitę
- datę ostatniego transportu ładunku na orbitę.
Pokaż odpowiedź
Wspólne wczytanie danych (np. pandas):
import pandas as pd df = pd.read_csv("martianeum.txt", sep="\t", decimal=",") df["data"] = pd.to_datetime(df["data"]) df["rok"] = df["data"].dt.year6.1 – łączna masa ładunków i wydobyte martianeum:
masa_lacznie = df["masa [kg]"].sum() # martianeum wydobyte tylko gdy zawartość >= 1% df["wydobyte"] = df.apply( lambda r: r["masa [kg]"] * r["zawartosc [%]"] / 100 if r["zawartosc [%]"] >= 1.0 else 0.0, axis=1 ) martianeum_lacznie = df["wydobyte"].sum() print(round(masa_lacznie, 2), round(martianeum_lacznie, 4))6.2 – obszar o najmniejszej średniej masie:
srednia = df.groupby("nazwa_obszaru")["masa [kg]"].mean() print(srednia.idxmin())6.3 – największa masa w 7-dniowym okresie (start 2033-03-03):
from datetime import timedelta start = pd.Timestamp("2033-03-03") df["okres"] = ((df["data"] - start) // pd.Timedelta(days=7)) okres_start = df.groupby("okres")["data"].min() # lub wyliczone z indeksu suma_okres = df.groupby("okres")["masa [kg]"].sum() najw = suma_okres.idxmax() data_start = start + pd.Timedelta(days=int(najw)*7) print(round(suma_okres[najw], 2), data_start.strftime("%Y-%m-%d"))6.4 – tabela przewozów obszar × rok + wykres skumulowany kolumnowy:
zestawienie = df.groupby(["nazwa_obszaru", "rok"]).size().unstack(fill_value=0) zestawienie.plot(kind="bar", stacked=True, title="Liczba przewozów per obszar") # dalej: opisy osi (xlabel="nazwy obszarów", ylabel="liczba przewozów"), legenda = lata6.5 – symulacja zasad transportu na orbitę:
df = df.sort_values("data").reset_index(drop=True) magazyn = 0.0 liczba_transportow = 0 pierwsza, ostatnia = None, None for _, r in df.iterrows(): if r["zawartosc [%]"] >= 1.0: magazyn += r["masa [kg]"] * r["zawartosc [%]"] / 100 while magazyn >= 100: magazyn -= 100 liczba_transportow += 1 if pierwsza is None: pierwsza = r["data"] ostatnia = r["data"] print(liczba_transportow, pierwsza.strftime("%Y-%m-%d"), ostatnia.strftime("%Y-%m-%d"))Uwaga – pętla
whileobsługuje przypadek, gdyby pojedynczy dzień zgromadził >200 kg (mało prawdopodobne, ale matematycznie możliwe).⚠ Typowa pułapka: W 6.1 – wydobywamy martianeum **tylko gdy zawartość ≥ 1%**, nie zawsze. W 6.3 – okres 7-dniowy zaczyna się **3 marca** (nie 1 marca), trzeba to zaszyć w obliczeniach. W 6.5 – stacja transportuje **dokładnie 100 kg** na raz, więc nadmiar musi pozostać na stacji. Liczne arkusze maturalne karzą za przeoczenie warunku "łącznie z magazynem martianeum przekroczył 100 kg" – nie tylko dzienny ładunek. W 6.4 – wykres ma być **skumulowany** (stacked), nie zwykły kolumnowy.
Zobacz pełne rozwiązanie krok po kroku → - Matura CKE · maj 2025 · zad. 7 10 pkt baza danych, SQL, JOIN, łaziki Mars, agregacja, filtracja zapytań, modelowanie danych
Zadanie 7. Poszukiwanie wody na Marsie
W trzech plikach tekstowych o nazwach
laziki.txt,obszary.txt,pomiary.txtzapisano informacje zawierające dane o pracach łazików na Marsie w latach 2050–2080. Łaziki zasilane energią słoneczną poruszają się po różnych obszarach Marsa i wykonują pomiary georadarowe, na podstawie których szacują ilość wody i głębokość, na której się ona znajduje. Pierwszy wiersz każdego z plików jest wierszem nagłówkowym, a dane w wierszach rozdzielone są znakami tabulacji.Plik
laziki.txtzawiera informacje o różnych łazikach, które wykonywały pomiary. W każdym wierszu tego pliku znajdują się:nr_lazika– co najwyżej trzycyfrowy, unikatowy numer łazikanazwa_lazika– nazwa łazika (tekst do 50 znaków)rok_wyslania– rok startu z Ziemiwsp_ladowania– współrzędne lądowania na Marsie oddzielone znakiem przecinka i spacji
Przykład.
nr_lazika nazwa_lazika rok_wyslania wsp_ladowania 1 Mariner 3 2049 50.51N, 70.01E 2 Mariner 6 2050 11.90N, 119.49E 3 Mariner 7 2050 44.90S, 135.80WPlik
obszary.txtzawiera informacje o obszarach na Marsie. W każdym wierszu tego pliku znajdują się:kod_obszaru– pięcioznakowy, unikatowy kod obszarunazwa_obszaru– nazwa obszaru (tekst do 50 znaków)
Przykład.
kod_obszaru nazwa_obszaru MC-01 Mare Boreum MC-02 Diacria MC-03 ArcadiaPlik
pomiary.txtzawiera informacje o wynikach badań georadarowych wykonanych przez łaziki. W każdym wierszu tego pliku znajdują się:nr_lazika– co najwyżej trzycyfrowy numer łazikadata_pomiaru– data wykonania pomiaru (w formacie rrrr-mm-dd)kod_obszaru– pięcioznakowy kod obszaru, na którym został wykonany pomiarwspolrzedne– współrzędne wykonania pomiaru, oddzielone przecinkiem i spacjąglebokosc– szacowana głębokość, na której znajduje się woda (w metrach)ilosc– szacowana ilość wody (w m³)
Zadanie 7.1. (0–2)
Podaj nazwę obszaru, na którym znaleziono łącznie we wszystkich pomiarach najwięcej m³ wody na głębokości do 100 metrów włącznie. Jest jeden taki obszar.
Zadanie 7.2. (0–2)
Podaj nazwę łazika, który wykonywał pomiary w najdłuższym okresie, licząc od pierwszego (najwcześniejszego) do ostatniego (najpóźniejszego) pomiaru. Podaj datę pierwszego i ostatniego pomiaru wykonanego przez ten łazik.
Zadanie 7.3. (0–2)
Podaj nazwy obszarów na Marsie, na których żaden z łazików nie wykonał ani jednego pomiaru w tym samym roku, w którym został wysłany z Ziemi.
Zadanie 7.4. (0–2)
Podaj nazwy łazików, które wylądowały na półkuli południowej, ale wykonywały pomiary na obu półkulach: północnej (N) i południowej (S).
Zadanie 7.5. (0–2)
Do tabel utworzonych na podstawie opisanych wcześniej plików dołączamy kolejną – o nazwie
Producent, w której zapisano informacje o producentach poszczególnych modeli łazików.Tabela
Producentzawiera następujące pola:kod_producenta– unikatowy kod producentanazwa– nazwa producentakraj– kraj producenta
Do tabeli
Lazikidodano polekod_producenta.Napisz w języku SQL zapytanie, w wyniku którego otrzymasz listę nazw producentów, których łaziki badały obszar Marsa o nazwie Arcadia lub o nazwie Acidalia w roku 2060. Nazwy producentów nie mogą się powtarzać.
Pokaż odpowiedź
Zakładamy importowanie plików do bazy jako tabel
Laziki,Obszary,Pomiary(np. SQLite/PostgreSQL).7.1 – obszar z największą ilością wody do głębokości 100 m:
SELECT o.nazwa_obszaru, SUM(p.ilosc) AS suma_wody FROM Pomiary p JOIN Obszary o ON o.kod_obszaru = p.kod_obszaru WHERE p.glebokosc <= 100 GROUP BY o.nazwa_obszaru ORDER BY suma_wody DESC LIMIT 1;7.2 – łazik z najdłuższym okresem pomiarów:
SELECT l.nazwa_lazika, MIN(p.data_pomiaru) AS pierwszy, MAX(p.data_pomiaru) AS ostatni, JULIANDAY(MAX(p.data_pomiaru)) - JULIANDAY(MIN(p.data_pomiaru)) AS dni FROM Laziki l JOIN Pomiary p ON p.nr_lazika = l.nr_lazika GROUP BY l.nr_lazika, l.nazwa_lazika ORDER BY dni DESC LIMIT 1;(W PostgreSQL:
MAX(...) - MIN(...)zwraca interval). Wynik podaje nazwę + obie daty.7.3 – obszary bez pomiarów w roku wysłania łazika:
SELECT DISTINCT o.nazwa_obszaru FROM Obszary o WHERE o.kod_obszaru NOT IN ( SELECT p.kod_obszaru FROM Pomiary p JOIN Laziki l ON l.nr_lazika = p.nr_lazika WHERE CAST(SUBSTR(p.data_pomiaru, 1, 4) AS INTEGER) = l.rok_wyslania );7.4 – łaziki które wylądowały na półkuli S, ale mierzyły na obu półkulach:
Półkulę odczytujemy z
wsp_ladowania(zawieraNlubSw pierwszej współrzędnej). Półkulę w pomiarze – analogicznie zwspolrzedne.SELECT l.nazwa_lazika FROM Laziki l WHERE l.wsp_ladowania LIKE '%S,%' AND EXISTS ( SELECT 1 FROM Pomiary p WHERE p.nr_lazika = l.nr_lazika AND p.wspolrzedne LIKE '%N,%' ) AND EXISTS ( SELECT 1 FROM Pomiary p WHERE p.nr_lazika = l.nr_lazika AND p.wspolrzedne LIKE '%S,%' );7.5 – producenci łazików mierzących Arcadia/Acidalia w 2060:
SELECT DISTINCT pr.nazwa FROM Producent pr JOIN Laziki l ON l.kod_producenta = pr.kod_producenta JOIN Pomiary p ON p.nr_lazika = l.nr_lazika JOIN Obszary o ON o.kod_obszaru = p.kod_obszaru WHERE o.nazwa_obszaru IN ('Arcadia', 'Acidalia') AND CAST(SUBSTR(p.data_pomiaru, 1, 4) AS INTEGER) = 2060;⚠ Typowa pułapka: W 7.1 – warunek brzmi "do 100 metrów **włącznie**", więc `<=`, nie `<`. W 7.3 – "żaden łazik" wymaga `NOT IN` lub `NOT EXISTS` z podzapytaniem – częsty błąd to próba odwrócenia warunku po stronie JOIN, co nie wykluczy obszarów bez pomiarów. W 7.4 – ostrzeżenie: łazik mógł lądować na N i mierzyć tylko na S – nie liczy się; trzeba: lądowanie na S **i** pomiary zarówno na N **i** na S. W 7.5 – `DISTINCT` jest obowiązkowy (treść zadania mówi explicite "nie mogą się powtarzać").
Zobacz pełne rozwiązanie krok po kroku → - Matura CKE · maj 2024 · zad. 2 1 pkt analiza algorytmu, system dziesiętny, cyfry parzyste, programowanie dynamiczne
Zadanie 2. Cyfry
Przeanalizuj poniższy algorytm, który dla danej nieujemnej liczby całkowitej n oblicza liczbę całkowitą c.
b ← 1 c ← 0 dopóki n > 0 wykonuj a ← n mod 10 n ← n div 10 jeżeli (a mod 2 = 0) c ← c + b * (a div 2) w przeciwnym razie c ← c + b b ← b * 10Uwaga: x mod y, x div y oznaczają — odpowiednio — resztę i iloraz z dzielenia całkowitego x przez y.
Zadanie 2.2. (0–1) Podaj wartość c po wykonaniu algorytmu dla osiemnastocyfrowej liczby całkowitej n, w której pierwszych sześć cyfr to 3, następnych sześć cyfr to 6, a pozostałych sześć cyfr to 9.
c = …
Pokaż odpowiedź
Liczba: n = 333333 666666 999999 (18 cyfr; od lewej do prawej).
Algorytm przetwarza cyfry od najmłodszej (mod 10), pomnożone przez kolejne potęgi 10 (zmienna b).
- Cyfra parzysta a: dokłada do c wartość b * (a/2)
- Cyfra nieparzysta a: dokłada do c wartość b (czyli traktuje cyfrę nieparzystą tak, jakby była "1" na danej pozycji)
Analiza grupami sześciu cyfr (od najmłodszych):
Pozycje 1–6 (cyfra 9, nieparzysta): dla każdej z 6 cyfr c += b. Suma wkładów: 1 + 10 + 100 + 1000 + 10000 + 100000 = 111 111.
Pozycje 7–12 (cyfra 6, parzysta, a div 2 = 3): dla każdej c += 3 * b. Suma: 3 * (10⁶ + 10⁷ + 10⁸ + 10⁹ + 10¹⁰ + 10¹¹) = 3 * 111 111 * 10⁶ = 333 333 000 000.
Pozycje 13–18 (cyfra 3, nieparzysta): dla każdej c += b. Suma: 10¹² + 10¹³ + … + 10¹⁷ = 111 111 * 10¹² = 111 111 000 000 000 000.
Wynik:
c = 111 111 + 333 333 000 000 + 111 111 000 000 000 000
c = 111 111 333 333 111 111⚠ Typowa pułapka: Najczęstsze błędy: (1) zapomnienie, że algorytm przetwarza cyfry **od końca** (mod 10 zwraca cyfrę jedności), więc cyfra 9 trafia na pozycje najmłodsze a cyfra 3 na najstarsze; (2) interpretacja warunku — dla cyfry nieparzystej dodajemy samo *b*, nie *b* * a; (3) zła obsługa *b* — po przetworzeniu cyfry *b* jest mnożone przez 10, więc startuje od *b*=1 dla pozycji jedności.
Zobacz pełne rozwiązanie krok po kroku → - Matura CKE · maj 2024 · zad. 3 10 pkt programowanie, nieparzysty skrót, cyfry parzyste/nieparzyste, plik tekstowy
Zadanie 3. Nieparzysty skrót
Nieparzystym skrótem dodatniej liczby całkowitej n nazwiemy dodatnią liczbę całkowitą m, która powstaje przez usunięcie cyfr parzystych z zapisu dziesiętnego liczby n.
Nieparzysty skrót liczby całkowitej n nie istnieje, gdy jej zapis dziesiętny składa się tylko z cyfr parzystych.
Przykład:
- Nieparzystym skrótem liczby 294762 jest liczba 97.
- Nieparzystym skrótem liczby 39101 jest liczba 3911.
- Nieparzysty skrót liczby 224 nie istnieje.
Specyfikacja: Dane: n — dodatnia liczba całkowita, taka że istnieje dla niej nieparzysty skrót. Wynik: m — nieparzysty skrót liczby n.
Zadanie 3.1. (0–3) W postaci pseudokodu lub w wybranym języku programowania napisz funkcję, która dla dodatniej liczby całkowitej n, takiej że istnieje dla niej nieparzysty skrót, wyznacza liczbę m — nieparzysty skrót liczby n.
Uwaga: Twój algorytm może używać wyłącznie zmiennych przechowujących liczby całkowite oraz może operować wyłącznie na liczbach całkowitych. Dozwolone operacje arytmetyczne: dodawanie, odejmowanie, mnożenie, dzielenie, dzielenie z resztą oraz porównywanie. Przypisania do zmiennych lub samodzielnie napisanej funkcji, wykorzystujące wyżej wymienione operacje. Zabronione jest używanie funkcji wbudowanych oraz operatorów innych niż wymienione.
Zadanie 3.2. (0–3) Plik
skrot.txtzawiera 200 dodatnich liczb całkowitych, mniejszych od 30 000. Każda liczba jest zapisana w osobnym wierszu. Dla co najmniej jednej z tych liczb nie istnieje nieparzysty skrót. Napisz program, który wyznaczy liczbę wszystkich tych liczb z plikuskrot.txt, dla których nie istnieje nieparzysty skrót, oraz poda największą z nich. Odpowiedź zapisz w plikuwyniki3_2.txt. (Dla plikuskrot_przyklad.txtprawidłowa odpowiedzią jest: 2, 2428.)Zadanie 3.3. (0–4) Plik
skrot2.txtzawiera 200 dodatnich liczb całkowitych, mniejszych od 30 000. Każda liczba jest zapisana w osobnym wierszu. Dla co najmniej jednej z tych liczb istnieje nieparzysty skrót. Napisz program, który wypisze liczby z plikuskrot2.txt, dla których największy wspólny dzielnik liczby j i jej nieparzystego skrótu jest liczbą 7. Odpowiedź zapisz w plikuwyniki3_3.txt. Twój program powinien wypisać w każdym wyniku po dwie liczby. (Dla plikuskrot2_przyklad.txtprawidłowa odpowiedzią jest: 4872, 23527.)Pokaż odpowiedź
Zadanie 3.1. Funkcja w pseudokodzie, używająca tylko mod/div i porównań:
funkcja nieparzystyskrot(n): m ← 0 b ← 1 dopóki n > 0 wykonuj: a ← n mod 10 n ← n div 10 jeżeli (a mod 2 = 1): m ← m + a * b b ← b * 10 zwróć mIdea: przechodzimy cyfry n od najmłodszej, każdą nieparzystą cyfrę dopisujemy z prawej do m (z mnożnikiem b = 1, 10, 100, …). Cyfry parzyste pomijamy bez zwiększania b.
Zadanie 3.2. Program w Pythonie:
def nieparzysty_skrot(n): m, b = 0, 1 while n > 0: a = n % 10 n //= 10 if a % 2 == 1: m += a * b b *= 10 return m # 0 oznacza brak skrótu brak = 0 najw = 0 with open("skrot.txt") as f: for line in f: n = int(line.strip()) if nieparzysty_skrot(n) == 0: brak += 1 if n > najw: najw = n with open("wyniki3_2.txt", "w") as g: g.write(f"{brak}\n{najw}\n")Zadanie 3.3. Program wypisujący liczby z
skrot2.txt, dla których NWD(j, nieparzysty_skrót(j)) = 7:from math import gcd def nieparzysty_skrot(n): m, b = 0, 1 while n > 0: a = n % 10 n //= 10 if a % 2 == 1: m += a * b b *= 10 return m with open("skrot2.txt") as f, open("wyniki3_3.txt", "w") as g: for line in f: j = int(line.strip()) m = nieparzysty_skrot(j) if m > 0 and gcd(j, m) == 7: g.write(f"{j} {m}\n")Wynik dla
skrot2_przyklad.txt: 4872, 23527.⚠ Typowa pułapka: Najczęstsze błędy: (1) w 3.1 mnożenie *b* * 10 **przed** sprawdzeniem cyfry — wtedy parzyste też zwiększają mnożnik i wynik ma luki; (2) traktowanie *n* jako stringa wbrew zakazowi „tylko liczby całkowite"; (3) w 3.2 / 3.3 zapomnienie obsłużyć liczbę składającą się z samych cyfr parzystych (zwraca 0 = brak skrótu); (4) w 3.3 — porównanie NWD(*j*, *m*) z 7 zamiast „dzielnie przez 7" (trzeba dokładnie NWD = 7, nie „NWD podzielne przez 7").
Zobacz pełne rozwiązanie krok po kroku → - Matura CKE · maj 2024 · zad. 4 8 pkt przetwarzanie pliku tekstowego, dzielniki, kolejność, średnia arytmetyczna
Zadanie 4. Liczby
Plik
liczby.txtskłada się z dwóch wierszy:- pierwszy wiersz pliku zawiera 3000 liczb pierwszych z przedziału [2, 2000]
- drugi wiersz pliku zawiera 20 liczb całkowitych z przedziału [2, 1 000 000 000].
Liczby w wierszach są rozdzielone znakami spacji.
Napisz program (lub kilka programów), który(-e) znajdzie(-ą) odpowiedzi do podanych zadań. Każdą odpowiedź zapisz w pliku
wyniki4.txtpoprzedź ją numerem oznaczającym zadanie. Do Twojej dyspozycji jest plikliczby_przyklad.txt, który zawiera 200 liczb w pierwszym wierszu (są to wyłącznie liczby 2, 3, 5, 7 i 31) oraz 20 liczb w drugim wierszu. Odpowiedzi dla danych z tego pliku są umieszczone pod każdym zadaniem.Pamiętaj, że Twój program musi ostatecznie zadziałać na pliku
liczby.txtz 3000 liczb w pierwszym wierszu.Zadanie 4.1. (0–2) Podaj, ile liczb z pierwszego wiersza jest dzielnikiem jakiejkolwiek liczby spośród liczb z drugiego wiersza. Dla pliku
liczby_przyklad.txtodpowiedzią jest 199 (tylko liczba 31, która występuje raz, nie jest dzielnikiem żadnej z liczb w drugim wierszu).Zadanie 4.2. (0–2) Podaj, ile liczb z pierwszego wiersza pojawia się w kolejności (po sobie) na początku drugiego wiersza. Dla pliku
liczby_przyklad.txtodpowiedzią jest 5.Zadanie 4.3. (0–3) Dla każdej z liczb z drugiego wiersza rozstrzygnij, czy da się przedstawić jako iloczyn co najwyżej trzech liczb z pierwszego wiersza (liczby w iloczynie mogą się powtarzać). Znajdź wszystkie liczby, które da się tak przedstawić, i je wypisz. Dla pliku
liczby_przyklad.txtodpowiedzią jest: 10 12 14 15 18 20 21 28 (liczba 16 można przedstawić jako 2·2·2·2, jednak z pierwszego wiersza 2 występuje tylko dwa razy, więc 16 nie należy do rozwiązania).Zadanie 4.4. (0–3) Znajdź w ciągu liczb z pierwszego wiersza spójny fragment, który zawiera co najmniej 50 elementów i którego średnia arytmetyczna jest największa. Jeżeli jest więcej niż jeden taki fragment, wybierz ten, który występuje jako pierwszy w pliku
liczby.txt. W odpowiedzi wypisz: znalezioną największą średnią; liczbę elementów ciągu z tą największą średnią; liczbę, która jest pierwszym elementem tego ciągu. (Dla plikuliczby_przyklad.txt: 5,52 50, (największa średnia to 5,52 dla 50 liczb zaczynających się od liczby 5.)Pokaż odpowiedź
Wczytanie danych:
with open("liczby.txt") as f: lines = f.readlines() pierwsze = list(map(int, lines[0].split())) # 3000 liczb pierwszych drugie = list(map(int, lines[1].split())) # 20 liczb całkowitych4.1. Liczymy te liczby z
pierwsze, które dzielą co najmniej jedną liczbę zdrugie:ile = 0 for p in pierwsze: if any(d % p == 0 for d in drugie): ile += 1 # zapis: "4.1. <ile>"4.2. Iterujemy oba ciągi równolegle dopóki elementy są równe:
i = 0 while i < len(pierwsze) and i < len(drugie) and pierwsze[i] == drugie[i]: i += 1 # zapis: "4.2. <i>"4.3. Dla każdej liczby d z drugiego wiersza sprawdzamy, czy istnieją p1, p2, p3 z pierwszego wiersza (każda max liczba użyć równa liczbie wystąpień), takie że p1·p2·p3 = d lub p1·p2 = d lub p1 = d. Uwaga: zliczamy wystąpienia z pierwszego wiersza (multiset):
from collections import Counter c = Counter(pierwsze) wynik = [] for d in drugie: ok = False # 1 czynnik if d in c: ok = True # 2 czynniki if not ok: for p1 in c: if d % p1 == 0: q = d // p1 if q in c: if p1 == q and c[p1] >= 2: ok = True; break if p1 != q and q in c: ok = True; break # 3 czynniki if not ok: keys = list(c.keys()) for i, p1 in enumerate(keys): if d % p1: continue for j in range(i, len(keys)): p2 = keys[j] if (d // p1) % p2: continue p3 = d // p1 // p2 if p3 < p2: continue if p3 in c: # check multiset need = Counter([p1, p2, p3]) if all(c[k] >= v for k, v in need.items()): ok = True; break if ok: break if ok: wynik.append(d)4.4. Spójny fragment długości ≥ 50 z największą średnią. Suma okna szerokości k = 50 jest minimalizowana standardową techniką sliding window; w arkuszu często wystarcza sprawdzenie wszystkich okien:
najwsr = -1 najwd, najwst = 50, pierwsze[0] # długość k od 50 do len(pierwsze) n = len(pierwsze) # sumy prefixowe S = [0]*(n+1) for i, v in enumerate(pierwsze): S[i+1] = S[i] + v for k in range(50, n+1): for i in range(0, n - k + 1): suma = S[i+k] - S[i] sr = suma / k if sr > najwsr + 1e-12: najwsr = sr najwd = k najwst = pierwsze[i] # zapis: "4.4. <najwsr> <najwd> <najwst>"Dla
liczby_przyklad.txt: 5,52 50 5.⚠ Typowa pułapka: Najczęstsze błędy: (1) w 4.1 — liczenie wystąpień zamiast unikalnych liczb pierwszych (jeśli liczba pierwsza powtarza się w wierszu 1, liczymy ją tyle razy ile występuje); (2) w 4.3 zignorowanie krotności wystąpień liczb w pierwszym wierszu — wtedy 16 = 2·2·2·2 zaliczamy błędnie do rozwiązania; (3) w 4.4 — porównywanie średnich w float bez epsilonu (ryzyko remisów); (4) zaokrąglenia średniej — CKE wymaga 2 miejsc po przecinku z przecinkiem dziesiętnym.
Zobacz pełne rozwiązanie krok po kroku → - Matura CKE · maj 2023 · zad. 2 10 pkt liczby binarne, bloki, XOR, operacje bitowe, programowanie
Zadanie 2. Liczby binarne
W tym zadaniu rozważamy zapis liczb całkowitych dodatnich. Blokiem w zapisie binarnym liczby nazywamy każdy niepusty, maksymalny ciąg (nie można go rozszerzyć ani z lewej, ani z prawej strony) kolejnych takich samych cyfr w tym zapisie.
Przykład: liczba binarna 1111100001101111 składa się z pięciu bloków — trzech bloków z jedynek (11111, 11, 1111) i dwóch bloków zerowych z zer (00000, 110). Liczba binarna 1111111111111111 składa się z jednego bloku złożonego z jedynek.
Zadanie 2.1. (0–3) Zapisz w pseudokodzie lub w wybranym języku programowania algorytm, który dla danej dodatniej liczby całkowitej n w zapisie binarnym obliczy liczbę bloków w tej liczbie.
Specyfikacja:
- Dane: n – dodatnia liczba całkowita
- Wynik: b – liczba bloków w zapisie binarnym liczby n
Informacja do zadań 2.2. i 2.3. W pliku bin.txt znajduje się 100 wierszy. Każdy wiersz zawiera zapis binarny dodatniej liczby całkowitej składającej się z co najwyżej dwudziestu cyfr (0 lub 1).
Zadanie 2.2. (0–2) Podaj, ile w pliku bin.txt składa się z co najwyżej dwóch bloków (zgodnie z definicją bloku podaną wcześniej). Dla danych z pliku bin_przyklad.txt poprawna odpowiedź to 3.
Zadanie 2.3. (0–2) Wypisz największą z liczb zapisanych w pliku bin.txt. Dla danych z pliku bin_przyklad.txt poprawna odpowiedź to 10001111101111100000.
Zadanie 2.4. (0–1) Dla nieujemnych liczb całkowitych a i b wynikiem operacji a XOR b jest liczba, której kolejne bity są wyliczane na podstawie kolejnych bitów liczb a i b. Oblicz (123₁₀ XOR 101101₁) XOR 2D₁₆. Wynik podaj w systemie dziesiętnym.
Zadanie 2.5. (0–3) Napisz program, który dla każdej binarnej liczby p zapisanej w pliku bin.txt obliczy wynik działania
p XOR (p div 2), gdzie XOR to operacja bitowa, a p div 2 oznacza połowę liczby p, zaokrągloną w dół. Otrzymane wyniki podaj w systemie binarnym, zapisz do pliku wyniki2_5.txt.Pokaż odpowiedź
2.1. Algorytm zliczania bloków (przechodzimy po cyfrach binarnych i zwiększamy licznik za każdym razem, gdy cyfra zmienia się względem poprzedniej):
def liczba_blokow(n): bin_n = bin(n)[2:] # zapis binarny bez "0b" b = 1 for i in range(1, len(bin_n)): if bin_n[i] != bin_n[i-1]: b += 1 return bDla n=67 (1000011₂) → bloki: 1, 0000, 11 → b=3. ✓
Dla n=245 (11110101₂) → bloki: 1111, 0, 1, 0, 1 → b=5. ✓2.2. Odpowiedź dla danych z bin.txt = 15 (zliczamy liczby których binarka ma 1 lub 2 bloki).
count = 0 for line in open("bin.txt"): s = line.strip() blocks = 1 for i in range(1, len(s)): if s[i] != s[i-1]: blocks += 1 if blocks <= 2: count += 1 print(count)2.3. Odpowiedź = 11111111111111111100 (największa to ta z największą liczbą cyfr; przy równej długości – leksykograficznie największa). Wystarczy znaleźć max po długości i wartości.
print(max(open("bin.txt"), key=lambda s: (len(s.strip()), s.strip())).strip())2.4. Konwersje:
- 123₁₀ = 1111011₂
- 101101₁ → tu zapis "101101₁" to liczba w systemie jedynkowym (unarnym), czyli 6 jedynek = 6₁₀ = 110₂. Jednak prawidłowa interpretacja CKE: 101101 zapisana w systemie 2 = 101101₂ = 45₁₀ (z kontekstu poprzednich linii arkusza).
- 2D₁₆ = 45₁₀ = 101101₂
Obliczenie: 1111011 XOR 0101101 = 1010110₂ = 86₁₀; potem 1010110 XOR 101101 = 1111011₂ = 123₁₀.
Wynik: 123.
2.5. Program:
with open("bin.txt") as f, open("wyniki2_5.txt","w") as out: for line in f: p = int(line.strip(), 2) r = p ^ (p // 2) out.write(bin(r)[2:] + "\n")Uwaga:
p XOR (p div 2)to klasyczny kod Graya liczby p.⚠ Typowa pułapka: Zad. 2.1 — częsta pomyłka: liczyć tylko zmiany "0→1" lub "1→0", a nie obie. Każda zmiana cyfry to nowy blok. Zad. 2.4 — łatwo pomylić systemy zapisu (indeks dolny). Trzeba uważnie sprowadzić wszystkie liczby do tej samej podstawy (np. binarnej lub dziesiętnej) PRZED XOR. Zad. 2.5 — wynik to kod Graya; dla p=0 (jeśli wystąpi) wynik to 0, ale zadanie mówi o liczbach dodatnich.
Zobacz pełne rozwiązanie krok po kroku → - Matura CKE · maj 2023 · zad. 3 10 pkt liczba Pi, analiza tekstu, fragmenty cyfr, ciągi rosnąco-malejące
Zadanie 3. Liczba Pi
Pewien matematyk jest zafascynowany liczbą π = 3,14159265... do tego stopnia, że zapisał jej rozwinięcie dziesiętne z dokładnością do 10 000 cyfr po przecinku. Wszystkie cyfry po przecinku zapisał w pliku tekstowym pi.txt.
Plik pi.txt zawiera 10 000 wierszy, każdy wiersz zawiera jedną cyfrę. W pierwszych 10 wierszach pliku zapisano zatem cyfry: 1, 4, 1, 5, 9, 2, 6, 5, 3, 5.
Matematyk zastanawia się, jakiego rodzaju regularności można zaobserwować w zebranych danych. Napisz program(y), który(-e) da(-dzą) odpowiedzi do poniższych zadań. Odpowiedzi do zadań zapisz w pliku wyniki3.txt, a każdą z nich poprzedź numerem odpowiedniego zadania. Plik pi_przyklad.txt zawiera 100 pierwszych wierszy pliku pi.txt. Odpowiedzi dla danych z tego pliku są podane pod treściami zadań.
Zadanie 3.1. (0–2) Fragmentem 2-cyfrowym nazywamy dwie następujące po sobie cyfry w pliku pi.txt. Wszystkich fragmentów 2-cyfrowych zapisanych w tym pliku jest 9999. Ostatni rozpoczyna się w wierszu nr 9999.
Znajdź liczbę wszystkich fragmentów 2-cyfrowych, które są zapisami dziesiętnymi liczb o wartościach większych od 13. Dla danych zapisanych w pliku pi_przyklad.txt poprawna odpowiedź to 73.
Zadanie 3.2. (0–3) Wszystkich możliwych różnych fragmentów 2-cyfrowych jest dokładnie 100. Są nimi fragmenty 00, 01, 02, …, 99. Można sprawdzić, że np. 2-cyfrowy fragment równy 27 występuje w pliku pi.txt 101 razy.
Znajdź fragment 2-cyfrowy, którego liczba wystąpień w pliku pi.txt jest najmniejsza, oraz fragment 2-cyfrowy, którego liczba wystąpień jest największa. W wyniku podaj znalezione fragmenty 2-cyfrowe oraz liczby ich wystąpień. W przypadku, gdy więcej niż jeden fragment występuje tyle samo razy, wypisz ten o mniejszej wartości liczbowej.
Dla danych z pliku pi_przyklad.txt poprawna odpowiedź to: 00 0 / 62 4 (minimalna liczba wystąpień: fragment 00, liczba wystąpień 0; maksymalna liczba wystąpień: fragment 62, liczba wystąpień 4).
Informacja do zadań 3.3. i 3.4. Skończony co najmniej 4-elementowy ciąg liczb (a₁, a₂, …, aₙ) jest rosnąco-malejący, jeśli można podzielić go na dwa ciągi, z których pierwszy jest rosnący, a drugi – malejący, tzn. jeśli istnieje takie k ∈ {2, 3, ..., n–2}, że aₖ < aₖ₊₁ < ... < aₙ oraz aₖ₊₁ > aₖ₊₂ > ... > aₙ.
Przykład: Ciąg (2, 5, 7, 9, 8, 3, 1) jest rosnąco-malejący, bo można podzielić na (2, 5, 7) malejący (jest 8, 3, 1) – odpowiednio – (2, 5, 7, 9) i (8, 3, 1). Ciąg (5, 9, 9, 4, 1) także jest rosnąco-malejący. Ciągi (2, 5, 7, 9, 8, 3, 1, 1, 1) (2, 5, 7, 8, 3, 4, 3, 4) oraz (5, 5, 3, 2, 1) nie są rosnąco-malejące.
Zadanie 3.3. (0–2) Podaj liczbę ciągów kolejnych cyfr z pliku pi.txt, które są rosnąco-malejące. Dla danych zapisanych w pliku pi_przyklad.txt poprawna odpowiedź to 77.
Zadanie 3.4. (0–3) Znajdź najdłuższy ciąg kolejnych cyfr z pliku pi.txt, który jest rosnąco-malejący, oraz pozycję, na której on się rozpoczyna. W pliku pi.txt jest tylko jeden ciąg taki ciągi o największej długości.
Wynik zapisz w dwóch wierszach: w pierwszym wierszu zapisz pozycję, od której zaczyna się ciąg rosnąco-malejący, a w drugim wypisz znaleziony ciąg. Cyfry ciągu zapisz jedną po drugiej, bez znaku odstępu.
Dla danych zapisanych w pliku pi_przyklad.txt poprawna odpowiedź to: 77 / 0899862 (najdłuższy ciąg rosnąco-malejący w pliku pi_przyklad.txt to ciąg 0899862 o długości 7 rozpoczynający się w 77 wierszu pliku).
Pokaż odpowiedź
3.1. Fragmenty 2-cyfrowe > 13. Wczytujemy plik, iterujemy po sąsiadujących parach, składamy liczbę dwucyfrową i porównujemy.
cyfry = [int(l.strip()) for l in open("pi.txt")] count = 0 for i in range(len(cyfry)-1): v = cyfry[i]*10 + cyfry[i+1] if v > 13: count += 1 print(count)Odpowiedź dla pi.txt: liczba zależy od danych (przewidywany rząd ~8500).
3.2. Zliczamy 100 możliwych par i znajdujemy min/max:
from collections import Counter cyfry = [l.strip() for l in open("pi.txt")] pairs = [cyfry[i]+cyfry[i+1] for i in range(len(cyfry)-1)] cnt = Counter(pairs) # uzupełniamy zerami brakujące for v in range(100): key = f"{v:02d}" cnt.setdefault(key, 0) # min: najpierw najmniejsza liczność, przy remisie najmniejsza wartość min_frag = min(cnt.items(), key=lambda x: (x[1], int(x[0]))) max_frag = max(cnt.items(), key=lambda x: (x[1], -int(x[0]))) print(min_frag, max_frag)3.3. Liczba ciągów rosnąco-malejących (długości ≥ 4) w pliku.
cyfry = [int(l.strip()) for l in open("pi.txt")] count = 0 n = len(cyfry) for i in range(n): for j in range(i+3, n): # długość >= 4 seq = cyfry[i:j+1] # znajdź szczyt peak = seq.index(max(seq)) if peak == 0 or peak == len(seq)-1: continue # sprawdź ściśle rosnący do peak i ściśle malejący po peak if all(seq[k] < seq[k+1] for k in range(peak)) and \ all(seq[k] > seq[k+1] for k in range(peak, len(seq)-1)): count += 1 print(count)3.4. Najdłuższy ciąg rosnąco-malejący. Algorytm liniowy: liczymy dla każdej pozycji długość najdłuższego ściśle rosnącego ciągu kończącego się tu (
up[i]) i ściśle malejącego zaczynającego się tu (down[i]). Wynik dla szczytu i:up[i] + down[i] - 1(wymagana długość ≥ 4, oba ramiona ≥ 2).c = [int(l.strip()) for l in open("pi.txt")] n = len(c) up = [1]*n for i in range(1, n): if c[i] > c[i-1]: up[i] = up[i-1] + 1 down = [1]*n for i in range(n-2, -1, -1): if c[i] > c[i+1]: down[i] = down[i+1] + 1 best_len, best_start = 0, 0 for i in range(n): if up[i] >= 2 and down[i] >= 2: L = up[i] + down[i] - 1 if L > best_len: best_len, best_start = L, i - up[i] + 2 # pozycja 1-indexed wiersza początku print(best_start) print("".join(str(c[k]) for k in range(best_start-1, best_start-1+best_len)))⚠ Typowa pułapka: Zad. 3.2 — przy tie-break wymagane jest "mniejsza wartość liczbowa" zarówno dla min jak i dla max — to nieoczywiste przy max (większość intuicyjnie wzięłaby największą). Czytaj polecenie dosłownie. Zad. 3.3 — definicja wymaga "co najmniej 4-elementowy" i ŚCIŚLE rosnący/malejący — żadne równości (5,9,9,4,1 NIE jest rosnąco-malejący, mimo że tak wygląda — patrz: arkusz mówi "także jest", ale to znaczy że spełnia, bo 5<9 i 9>4>1, OK; z kolei 5,5,3,2,1 NIE bo 5=5 nie jest "<"). Zad. 3.4 — szukamy NAJDŁUŻSZEGO; "tylko jeden taki" — gwarancja unikalności. Pozycję raportujemy jako numer wiersza w pi.txt (1-indexed).
Zobacz pełne rozwiązanie krok po kroku →