Piotrek pracuje w porcie kosmicznym Bajtolandu. Jego głównym zadaniem jest odbieranie i tłumaczenie wiadomości pochodzących z innych planet, zamieszkałych przez rasę Xoniwruków, między innymi Galwax oraz X‑77.
W tym tygodniu po raz pierwszy odebrał informację z planety Tryton, której mieszkańcy używają systemu binarnego do komunikacji. Informacja ma być przekazana na planetę KRFL, posługującą się systemem szesnastkowym.
W pliku informacja.txt znajduje się 100 wierszy, każdy z nich zawiera jedną liczbę w postaci binarnej składającą się maksymalnie z 98 cyfr.
Napisz program, który w pliku informacja.txt znajdzie liczby binarne zawierające w systemie szesnastkowym cyfrę A i zapisze je do pliku przekaz.txt w systemie szesnastkowym.
Do oceny oddajesz:
plik przekaz.txt z odpowiedzią (liczbami z pliku informacja.txt zapisanymi w systemie szesnastkowym, które zawierają cyfrę A),
plik(i) z komputerową realizacją zadania (kodem programu).
Przedstaw rozwiązanie w postaci programu w wybranym języku (C++, Java lub Python). Odpowiedź znajdziesz w osobnym pliku umieszczonym pod omówieniem pseudokodu.
Rozwiązanie
Rozwiązanie zadania przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można korzystać z wybranego języka programowania: C++, Java lub Python.
Na początku wczytamy dane z pliku. Następnie każdą liczbę z pliku konwertujemy z systemu binarnego do szesnastkowego. Wybieramy metodę wykorzystującą bazy skojarzone, ponieważ przy okazji konwersji każdej czwórki cyfr będziemy mieli możliwość sprawdzenia, czy liczba po konwersji zawiera cyfrę A.
Wewnątrz pętli, przechodzącej po każdej liczbie z pliku, zadeklarujmy zmienną liniaHex przechowującą przekonwertowaną liczbę. Podobnie jak każda liczba z pliku jest ona łańcuchem znaków, więc na początku powinna przyjąć wartość pustego łańcucha. Inicjujemy również zmienną warunek, która będzie informować, czy liczba zawiera cyfrę A. Początkowo przypisujemy jej wartość FAŁSZ:
Linia 1. linie ← wczytaj dane z pliku cudzysłów informacja kropka txt cudzysłów.
Linia 3. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek 99 wykonuj dwukropek.
Linia 4. liniaHex ← cudzysłów cudzysłów.
Linia 5. warunek ← FAŁSZ.
linie ← wczytaj dane z pliku "informacja.txt"
dla i = 0, 1, ..., 99 wykonuj:
liniaHex ← ""
warunek ← FAŁSZ
Następnie, jeśli długość liczby nie jest podzielna przez 4, dopisujemy na jej początku odpowiednią liczbę zer. Skorzystamy z funkcji długość() zwracającej długość łańcucha znaków. Jej implementacja jest dostępna w każdym z języków programowania używanych na egzaminie maturalnym:
Linia 1. linie ← wczytaj dane z pliku cudzysłów informacja kropka txt cudzysłów.
Linia 3. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek 99 wykonuj dwukropek.
Linia 4. liniaHex ← cudzysłów cudzysłów.
Linia 5. warunek ← FAŁSZ.
Linia 7. dopóki długość otwórz nawias okrągły linie otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły procent 4 wykrzyknik znak równości 0 przecinek wykonuj dwukropek.
Linia 8. linie otwórz nawias kwadratowy i zamknij nawias kwadratowy ← cudzysłów 0 cudzysłów plus linie otwórz nawias kwadratowy i zamknij nawias kwadratowy.
linie ← wczytaj dane z pliku "informacja.txt"
dla i = 0, 1, ..., 99 wykonuj:
liniaHex ← ""
warunek ← FAŁSZ
dopóki długość(linie[i]) % 4 != 0, wykonuj:
linie[i] ← "0" + linie[i]
Następnie przechodzimy do konwersji – każda cyfra szesnastkowa zapisana jest na czterech bitach, zatem będziemy po kolei sprawdzać czteroznakowe fragmenty liczby binarnej i zamieniać je na postać szesnastkową.
Skorzystamy w tym celu z funkcji fragment() zwracającej interesujący nas fragment liczby oraz funkcji postaćHex(), która przekonwertuje go z systemu binarnego na szesnastkowy. Obie implementacje przedstawimy po omówieniu głównej części programu.
Po przeprowadzeniu konwersji czteroznakowego fragmentu liczby binarnej możemy sprawdzić, czy nie uzyskaliśmy cyfry A – jeśli tak, to aktualizujemy zmienną warunek. Następnie dopisujemy przekonwertowany fragment do zmiennej liniaHex oraz przechodzimy do kolejnej czwórki cyfr:
Linia 1. linie ← wczytaj dane z pliku cudzysłów informacja kropka txt cudzysłów.
Linia 3. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek 99 wykonuj dwukropek.
Linia 4. liniaHex ← cudzysłów cudzysłów.
Linia 5. warunek ← FAŁSZ.
Linia 7. dopóki długość otwórz nawias okrągły linie otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły procent 4 wykrzyknik znak równości 0 przecinek wykonuj dwukropek.
Linia 8. linie otwórz nawias kwadratowy i zamknij nawias kwadratowy ← cudzysłów 0 cudzysłów plus linie otwórz nawias kwadratowy i zamknij nawias kwadratowy.
Linia 10. j ← 0.
Linia 11. dla j znak równości 0 przecinek 4 przecinek kropka kropka kropka przecinek długość otwórz nawias okrągły linie otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły minus 4 dwukropek.
Linia 12. cyfra ← postaćHex otwórz nawias okrągły fragment otwórz nawias okrągły linie otwórz nawias kwadratowy i zamknij nawias kwadratowy przecinek j przecinek 4 zamknij nawias okrągły zamknij nawias okrągły.
Linia 13. jeżeli cyfra znak równości apostrof A apostrof dwukropek.
Linia 14. warunek ← PRAWDA.
Linia 15. liniaHex ← liniaHex plus cyfra.
linie ← wczytaj dane z pliku "informacja.txt"
dla i = 0, 1, ..., 99 wykonuj:
liniaHex ← ""
warunek ← FAŁSZ
dopóki długość(linie[i]) % 4 != 0, wykonuj:
linie[i] ← "0" + linie[i]
j ← 0
dla j = 0, 4, ..., długość(linie[i]) - 4:
cyfra ← postaćHex(fragment(linie[i], j, 4))
jeżeli cyfra = 'A':
warunek ← PRAWDA
liniaHex ← liniaHex + cyfra
Po zakończeniu konwersji całej liczby sprawdzamy, czy w liczbie wystąpiła cyfra A. Jeżeli tak (wartość zmiennej warunek to PRAWDA), zapisujemy przekonwertowaną liczbę do pliku wynikowego przekaz.txt. Po sprawdzeniu wszystkich liczb zamykamy pliki:
Linia 1. linie ← wczytaj dane z pliku cudzysłów informacja kropka txt cudzysłów.
Linia 3. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek 99 wykonuj dwukropek.
Linia 4. liniaHex ← cudzysłów cudzysłów.
Linia 5. warunek ← FAŁSZ.
Linia 7. dopóki długość otwórz nawias okrągły linie otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły procent 4 wykrzyknik znak równości 0 przecinek wykonuj dwukropek.
Linia 8. linie otwórz nawias kwadratowy i zamknij nawias kwadratowy ← cudzysłów 0 cudzysłów plus linie otwórz nawias kwadratowy i zamknij nawias kwadratowy.
Linia 10. j ← 0.
Linia 11. dla j znak równości 0 przecinek 4 przecinek kropka kropka kropka przecinek długość otwórz nawias okrągły linie otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły minus 4 dwukropek.
Linia 12. cyfra ← postaćHex otwórz nawias okrągły fragment otwórz nawias okrągły linie otwórz nawias kwadratowy i zamknij nawias kwadratowy przecinek j przecinek 4 zamknij nawias okrągły zamknij nawias okrągły.
Linia 13. jeżeli cyfra znak równości apostrof A apostrof dwukropek.
Linia 14. warunek ← PRAWDA.
Linia 15. liniaHex ← liniaHex plus cyfra.
Linia 17. jeżeli warunek znak równości PRAWDA dwukropek.
Linia 18. dopisz liniaHex na koniec pliku cudzysłów przekaz kropka txt cudzysłów.
Linia 19. zamknij plik cudzysłów informacja kropka txt cudzysłów.
Linia 20. zamknij plik cudzysłów przekaz kropka txt cudzysłów.
linie ← wczytaj dane z pliku "informacja.txt"
dla i = 0, 1, ..., 99 wykonuj:
liniaHex ← ""
warunek ← FAŁSZ
dopóki długość(linie[i]) % 4 != 0, wykonuj:
linie[i] ← "0" + linie[i]
j ← 0
dla j = 0, 4, ..., długość(linie[i]) - 4:
cyfra ← postaćHex(fragment(linie[i], j, 4))
jeżeli cyfra = 'A':
warunek ← PRAWDA
liniaHex ← liniaHex + cyfra
jeżeli warunek = PRAWDA:
dopisz liniaHex na koniec pliku "przekaz.txt"
zamknij plik "informacja.txt"
zamknij plik "przekaz.txt"
Przejdźmy do funkcji pomocniczych. Funkcja postaćHex() ma jeden parametr, przyjmuje łańcuch znaków o długości 4 oznaczający liczbę w postaci binarnej i zwraca łańcuch znaków oznaczający jej odpowiednik w postaci szesnastkowej. Możemy zatem zapisać serię instrukcji jeżeli:
Linia 1. funkcja postaćHex otwórz nawias okrągły liczba zamknij nawias okrągły.
Linia 2. jeżeli liczba znak równości cudzysłów 0000 cudzysłów dwukropek.
Linia 3. zwróć cudzysłów 0 cudzysłów.
Linia 4. jeżeli liczba znak równości cudzysłów 0001 cudzysłów dwukropek.
Linia 5. zwróć cudzysłów 1 cudzysłów.
Linia 6. jeżeli liczba znak równości cudzysłów 0010 cudzysłów dwukropek.
Linia 7. zwróć cudzysłów 2 cudzysłów.
Linia 8. jeżeli liczba znak równości cudzysłów 0011 cudzysłów dwukropek.
Linia 9. zwróć cudzysłów 3 cudzysłów.
Linia 10. jeżeli liczba znak równości cudzysłów 0100 cudzysłów dwukropek.
Linia 11. zwróć cudzysłów 4 cudzysłów.
Linia 12. jeżeli liczba znak równości cudzysłów 0101 cudzysłów dwukropek.
Linia 13. zwróć cudzysłów 5 cudzysłów.
Linia 14. jeżeli liczba znak równości cudzysłów 0110 cudzysłów dwukropek.
Linia 15. zwróć cudzysłów 6 cudzysłów.
Linia 16. jeżeli liczba znak równości cudzysłów 0111 cudzysłów dwukropek.
Linia 17. zwróć cudzysłów 7 cudzysłów.
Linia 18. jeżeli liczba znak równości cudzysłów 1000 cudzysłów dwukropek.
Linia 19. zwróć cudzysłów 8 cudzysłów.
Linia 20. jeżeli liczba znak równości cudzysłów 1001 cudzysłów dwukropek.
Linia 21. zwróć cudzysłów 9 cudzysłów.
Linia 22. jeżeli liczba znak równości cudzysłów 1010 cudzysłów dwukropek.
Linia 23. zwróć cudzysłów A cudzysłów.
Linia 24. jeżeli liczba znak równości cudzysłów 1011 cudzysłów dwukropek.
Linia 25. zwróć cudzysłów B cudzysłów.
Linia 26. jeżeli liczba znak równości cudzysłów 1100 cudzysłów dwukropek.
Linia 27. zwróć cudzysłów C cudzysłów.
Linia 28. jeżeli liczba znak równości cudzysłów 1101 cudzysłów dwukropek.
Linia 29. zwróć cudzysłów D cudzysłów.
Linia 30. jeżeli liczba znak równości cudzysłów 1110 cudzysłów dwukropek.
Linia 31. zwróć cudzysłów E cudzysłów.
Linia 32. jeżeli liczba znak równości cudzysłów 1111 cudzysłów dwukropek.
Linia 33. zwróć cudzysłów F cudzysłów.
funkcja postaćHex(liczba)
jeżeli liczba = "0000":
zwróć "0"
jeżeli liczba = "0001":
zwróć "1"
jeżeli liczba = "0010":
zwróć "2"
jeżeli liczba = "0011":
zwróć "3"
jeżeli liczba = "0100":
zwróć "4"
jeżeli liczba = "0101":
zwróć "5"
jeżeli liczba = "0110":
zwróć "6"
jeżeli liczba = "0111":
zwróć "7"
jeżeli liczba = "1000":
zwróć "8"
jeżeli liczba = "1001":
zwróć "9"
jeżeli liczba = "1010":
zwróć "A"
jeżeli liczba = "1011":
zwróć "B"
jeżeli liczba = "1100":
zwróć "C"
jeżeli liczba = "1101":
zwróć "D"
jeżeli liczba = "1110":
zwróć "E"
jeżeli liczba = "1111":
zwróć "F"
Funkcja fragment() przyjmuje trzy argumenty: napis – łańcuch znaków, z którego fragment chcemy uzyskać, indeks – oznaczający, od którego indeksu łańcucha znaków ma zaczynać się fragment, oraz długość – oznaczający długość fragmentu. Zwraca ona część napisu zaczynającą się na podanym indeksie oraz mającą podaną długość:
Linia 1. funkcja fragment otwórz nawias okrągły napis przecinek indeks przecinek długość zamknij nawias okrągły.
Linia 2. nowyNapisz ← cudzysłów cudzysłów.
Linia 3. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek długość minus 1 wykonuj dwukropek.
Linia 4. nowyNapis ← nowyNapis plus napis otwórz nawias kwadratowy indeks plus i zamknij nawias kwadratowy.
Linia 5. zwróć nowyNapis.
funkcja fragment(napis, indeks, długość)
nowyNapisz ← ""
dla i = 0, 1, ..., długość - 1 wykonuj:
nowyNapis ← nowyNapis + napis[indeks + i]
zwróć nowyNapis
Odpowiedź do zadania
Prawidłowy wynik znajduje się w pliku przekaz.txt.
RXdtdH1i1A4Em
Przycisk do pobrania pliku TXT z wynikiem zadania.
(liczba szesnastkowa) liczba zapisana w systemie pozycyjnym o podstawie 16; nazwa pochodzi od angielskiego słowa hexadecimal, oznaczającego „szesnastkowy”; do zapisu tej liczby wykorzystywane są cyfry od 0 do 9 oraz litery od A do F (odpowiadające liczbom od 10 do 15)
najmniej znaczący bit
najmniej znaczący bit
bit o najmniejszej wadze; w zapisie binarnym jest to pierwszy bit licząc od prawej strony liczby
systemy o bazach skojarzonych
systemy o bazach skojarzonych
dwa systemy liczbowe, w przypadku których podstawa jednego jest potęgą podstawy drugiego