{"id":"informatyka-2016-maj-matura-rozszerzona/zad/6.1","paper_id":"informatyka-2016-maj-matura-rozszerzona","number":"6.1","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2016,"month":"maj","level":"rozszerzona","text":"Zadanie 6. Szyfr Cezara\n\nPodstawieniowy szyfr Cezara z przesunięciem (kluczem) k polega na zastąpieniu każdego znaku jawnego znakiem leżącym w alfabecie o k pozycji w prawo od zastępowanego znaku. Przykład: znak 'B' po zakodowaniu kluczem k=3 zastąpiony zostanie znakiem 'E'.\n\nPrzy szyfrowaniu znaku należy postępować w sposób cykliczny: jawny znak 'X' kluczem k=3 → 'A', 'Y' → 'B', 'Z' → 'C'.\n\nW tym zadaniu rozpatrujemy tylko słowa zbudowane z wielkich liter alfabetu angielskiego (ASCII 65-90), długości ≤ 30 znaków.\n\nW pliku dane_6_1.txt znajduje się 100 słów (każde w osobnym wierszu). Fragment:\nINTERPRETOWANIE\nROZWESELANIE\nKONSERWOWANIE\n\nUwaga: Dla pierwszego słowa z pliku (INTERPRETOWANIE) wynikiem jest słowo LQWHUSUHWRZDQLH (k=3? - w treści k=107).\n\nNapisz program, który zaszyfruje słowa z pliku dane_6_1.txt z użyciem klucza k = 107. Wynik zapisz do pliku wyniki_6_1.txt, każde słowo w osobnym wierszu, w porządku odpowiadającym kolejności słów z pliku z danymi.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Ostatnie wiersze pliku wyniki_6_1.txt:**\n\n| Nr | Tekst jawny | Zaszyfrowany |\n| 97 | INWOKACJA | LQZRNDFMD |\n| 98 | INWESTOWANIE | LQZHVWRZDQLH |\n| 99 | ROZSZERZANIE | URCVCHUCDQLH |\n| 100 | ARYSTOTELES | DUBVWRWHOHV |\n\n## Sposób 1 - szyfr Cezara z modulo 26\n\n**Idea:** dla klucza k = 107, faktyczne przesunięcie = `k mod 26 = 107 mod 26 = 3` (bo 26·4 = 104, 107 - 104 = 3).\n\n**Wzór szyfrowania**:\nzaszyfrowane(c) = ((ord(c) - ord('A') + k) mod 26) + ord('A')\n\n## Sposób 2 - implementacja Python\n\n```python\ndef szyfruj_cezara(slowo, k):\nwynik = []\nfor znak in slowo:\npozycja = ord(znak) - ord('A') # 0 25\nnowa = (pozycja + k) % 26\nwynik.append(chr(ord('A') + nowa))\nreturn ''.join(wynik)\n\nk = 107\nz_wejscia = open('dane_6_1.txt', encoding='utf-8').read().splitlines()\nz_wyjscia = [szyfruj_cezara(s.strip(), k) for s in z_wejscia if s.strip()]\n\nwith open('wyniki_6_1.txt', 'w', encoding='utf-8') as f:\nfor s in z_wyjscia:\nf.write(s + '\\n')\n\n# Sprawdzenie ostatnich:\nfor i, (jawne, szyfr) in enumerate(zip(z_wejscia, z_wyjscia), 1):\nif i >= 97:\nprint(f\"{i} {jawne} -> {szyfr}\")\n\n**Wynik:**\n97 INWOKACJA -> LQZRNDFMD\n98 INWESTOWANIE -> LQZHVWRZDQLH\n99 ROZSZERZANIE -> URCVCHUCDQLH\n100 ARYSTOTELES -> DUBVWRWHOHV\n\n## Sposób 3 - C++\n\n```cpp\n#include <iostream>\n#include <fstream>\n#include <string>\nusing namespace std;\n\nstring szyfruj(const string& s, int k) {\nstring wynik = s;\nfor (char& c : wynik) {\nint p = c - 'A';\nc = 'A' + (p + k) % 26;\n}\nreturn wynik;\n}\n\nint main() {\nifstream fin(\"dane_6_1.txt\");\nofstream fout(\"wyniki_6_1.txt\");\nstring s;\nint k = 107;\nwhile (fin >> s) fout << szyfruj(s, k) << \"\\n\";\nreturn 0;\n}\n\n## Sposób 4 - Pascal\n\n```pascal\nprogram Cezar61;\nvar fin, fout: TextFile; s: String; i: Integer;\n\nfunction Szyfruj(s: String; k: Integer): String;\nvar i, p: Integer;\nbegin\nfor i := 1 to Length(s) do begin\np := Ord(s[i]) - Ord('A');\ns[i] := Chr(Ord('A') + (p + k) mod 26);\nend;\nSzyfruj := s;\nend;\n\nbegin\nAssignFile(fin, 'dane_6_1.txt'); Reset(fin);\nAssignFile(fout, 'wyniki_6_1.txt'); Rewrite(fout);\nwhile not Eof(fin) do begin\nReadln(fin, s);\nWriteln(fout, Szyfruj(s, 107));\nend;\nCloseFile(fin); CloseFile(fout);\nend.\n\n## Reference informatyczny - szyfr Cezara\n\n> Reference - Szyfr Cezara:\n> - **Najstarszy szyfr podstawieniowy** (Juliusz Cezar, ok. 50 p.n.e.).\n> - Klucz k przesuwa każdą literę o k pozycji w prawo.\n> - **Cykliczność** - modulo długość alfabetu (26 dla angielskiego).\n> - **Klucz efektywny** = `k mod 26`. Klucze różniące się o wielokrotność 26 dają **ten sam wynik**.\n> - **Deszyfrowanie**: użyj klucza `26 - k` lub `-k mod 26`.\n>\n> Reference - Operacje na znakach:\n> - **Python**: `ord('A') = 65`, `chr(65) = 'A'`. Indeks `'A' 'Z'` = 0 25.\n> - **C++**: `'A' + i` (char arithmetic).\n> - **Pascal**: `Chr(Ord('A') + i)`.\n>\n> Reference - Modulo dla ujemnych:\n> - Python: `(-5) % 26 = 21` (zawsze dodatni wynik).\n> - C++: `(-5) % 26 = -5` (zależy od kompilatora, lepiej `((x % 26) + 26) % 26`).\n> - Pascal: `(-5) mod 26 = -5`. Tu klucz dodatni więc nie problem.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.1, max 3 pkt):\n> - **3 pkt** - poprawny plik wynikowy (wszystkie 100 słów)\n> - **2 pkt** - pominięcie ostatniego wiersza\n> - **1 pkt** - błąd zawijania (brak modulo 26) ALBO bez zawijania\n> - **0 pkt** - błędna albo brak\n\n## Typowe pułapki\n\n- **Brak `mod 26`** - klucz 107 bez modulo da `ord('A') + 65 + 107 = 237` → znak '`í`' lub coś niedrukowalnego. Konieczne `% 26`.\n- **Pomyłka `mod 26` z `mod 25` lub `mod 27`** - alfabet ma 26 liter.\n- **Indeksowanie od 1 vs 0** - Pascal stringi indeksowane od 1, Python/C++ od 0.\n- **Pominięcie ostatniego wiersza** - przy `while fin >> s` w C++ działa OK, ale `while not Eof(fin)` w Pascal może pominąć ostatni wiersz, jeśli plik nie kończy się newline.\n- **Klucz ujemny przy odszyfrowywaniu** - uważać na `(x % 26 + 26) % 26`.\n- **Polskie znaki** - w zadaniu są tylko wielkie litery angielskie A-Z; ewentualne polskie znaki pomijamy lub błąd danych.\n\n## Złożoność obliczeniowa\n\n- Szyfrowanie jednego słowa długości L: **O(L)**.\n- 100 słów × max 30 znaków: **O(3000)** operacji.\n- I/O dominuje, ale to też O(N) liniowo.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2016 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura","text_html":"<p>Zadanie 6. Szyfr Cezara</p>\n<p>Podstawieniowy szyfr Cezara z przesunięciem (kluczem) k polega na zastąpieniu każdego znaku jawnego znakiem leżącym w alfabecie o k pozycji w prawo od zastępowanego znaku. Przykład: znak &#x27;B&#x27; po zakodowaniu kluczem k=3 zastąpiony zostanie znakiem &#x27;E&#x27;.</p>\n<p>Przy szyfrowaniu znaku należy postępować w sposób cykliczny: jawny znak &#x27;X&#x27; kluczem k=3 → &#x27;A&#x27;, &#x27;Y&#x27; → &#x27;B&#x27;, &#x27;Z&#x27; → &#x27;C&#x27;.</p>\n<p>W tym zadaniu rozpatrujemy tylko słowa zbudowane z wielkich liter alfabetu angielskiego (ASCII 65-90), długości ≤ 30 znaków.</p>\n<p>W pliku dane_6_1.txt znajduje się 100 słów (każde w osobnym wierszu). Fragment:<br>INTERPRETOWANIE<br>ROZWESELANIE<br>KONSERWOWANIE</p>\n<p>Uwaga: Dla pierwszego słowa z pliku (INTERPRETOWANIE) wynikiem jest słowo LQWHUSUHWRZDQLH (k=3? - w treści k=107).</p>\n<p>Napisz program, który zaszyfruje słowa z pliku dane_6_1.txt z użyciem klucza k = 107. Wynik zapisz do pliku wyniki_6_1.txt, każde słowo w osobnym wierszu, w porządku odpowiadającym kolejności słów z pliku z danymi.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Ostatnie wiersze pliku wyniki_6_1.txt:</strong></p>\n<p>| Nr | Tekst jawny | Zaszyfrowany |<br>| 97 | INWOKACJA | LQZRNDFMD |<br>| 98 | INWESTOWANIE | LQZHVWRZDQLH |<br>| 99 | ROZSZERZANIE | URCVCHUCDQLH |<br>| 100 | ARYSTOTELES | DUBVWRWHOHV |</p>\n<h4>Sposób 1 - szyfr Cezara z modulo 26</h4>\n<p><strong>Idea:</strong> dla klucza k = 107, faktyczne przesunięcie = <code>k mod 26 = 107 mod 26 = 3</code> (bo 26·4 = 104, 107 - 104 = 3).</p>\n<p><strong>Wzór szyfrowania</strong>:<br>zaszyfrowane(c) = ((ord(c) - ord(&#x27;A&#x27;) + k) mod 26) + ord(&#x27;A&#x27;)</p>\n<h4>Sposób 2 - implementacja Python</h4>\n<p>```python<br>def szyfruj_cezara(slowo, k):<br>wynik = []<br>for znak in slowo:<br>pozycja = ord(znak) - ord(&#x27;A&#x27;) # 0 25<br>nowa = (pozycja + k) % 26<br>wynik.append(chr(ord(&#x27;A&#x27;) + nowa))<br>return &#x27;&#x27;.join(wynik)</p>\n<p>k = 107<br>z_wejscia = open(&#x27;dane_6_1.txt&#x27;, encoding=&#x27;utf-8&#x27;).read().splitlines()<br>z_wyjscia = [szyfruj_cezara(s.strip(), k) for s in z_wejscia if s.strip()]</p>\n<p>with open(&#x27;wyniki_6_1.txt&#x27;, &#x27;w&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>for s in z_wyjscia:<br>f.write(s + &#x27;\\n&#x27;)</p>\n<h3>Sprawdzenie ostatnich:</h3>\n<p>for i, (jawne, szyfr) in enumerate(zip(z_wejscia, z_wyjscia), 1):<br>if i &gt;= 97:<br>print(f&quot;{i} {jawne} -&gt; {szyfr}&quot;)</p>\n<p><strong>Wynik:</strong><br>97 INWOKACJA -&gt; LQZRNDFMD<br>98 INWESTOWANIE -&gt; LQZHVWRZDQLH<br>99 ROZSZERZANIE -&gt; URCVCHUCDQLH<br>100 ARYSTOTELES -&gt; DUBVWRWHOHV</p>\n<h4>Sposób 3 - C++</h4>\n<p>```cpp<br>#include &lt;iostream&gt;<br>#include &lt;fstream&gt;<br>#include &lt;string&gt;<br>using namespace std;</p>\n<p>string szyfruj(const string&amp; s, int k) {<br>string wynik = s;<br>for (char&amp; c : wynik) {<br>int p = c - &#x27;A&#x27;;<br>c = &#x27;A&#x27; + (p + k) % 26;<br>}<br>return wynik;<br>}</p>\n<p>int main() {<br>ifstream fin(&quot;dane_6_1.txt&quot;);<br>ofstream fout(&quot;wyniki_6_1.txt&quot;);<br>string s;<br>int k = 107;<br>while (fin &gt;&gt; s) fout &lt;&lt; szyfruj(s, k) &lt;&lt; &quot;\\n&quot;;<br>return 0;<br>}</p>\n<h4>Sposób 4 - Pascal</h4>\n<p>```pascal<br>program Cezar61;<br>var fin, fout: TextFile; s: String; i: Integer;</p>\n<p>function Szyfruj(s: String; k: Integer): String;<br>var i, p: Integer;<br>begin<br>for i := 1 to Length(s) do begin<br>p := Ord(s[i]) - Ord(&#x27;A&#x27;);<br>s[i] := Chr(Ord(&#x27;A&#x27;) + (p + k) mod 26);<br>end;<br>Szyfruj := s;<br>end;</p>\n<p>begin<br>AssignFile(fin, &#x27;dane_6_1.txt&#x27;); Reset(fin);<br>AssignFile(fout, &#x27;wyniki_6_1.txt&#x27;); Rewrite(fout);<br>while not Eof(fin) do begin<br>Readln(fin, s);<br>Writeln(fout, Szyfruj(s, 107));<br>end;<br>CloseFile(fin); CloseFile(fout);<br>end.</p>\n<h4>Reference informatyczny - szyfr Cezara</h4>\n<blockquote>Reference - Szyfr Cezara:<br>- <strong>Najstarszy szyfr podstawieniowy</strong> (Juliusz Cezar, ok. 50 p.n.e.).<br>- Klucz k przesuwa każdą literę o k pozycji w prawo.<br>- <strong>Cykliczność</strong> - modulo długość alfabetu (26 dla angielskiego).<br>- <strong>Klucz efektywny</strong> = <code>k mod 26</code>. Klucze różniące się o wielokrotność 26 dają <strong>ten sam wynik</strong>.<br>- <strong>Deszyfrowanie</strong>: użyj klucza <code>26 - k</code> lub <code>-k mod 26</code>.<br><br>Reference - Operacje na znakach:<br>- <strong>Python</strong>: <code>ord(&#x27;A&#x27;) = 65</code>, <code>chr(65) = &#x27;A&#x27;</code>. Indeks <code>&#x27;A&#x27; &#x27;Z&#x27;</code> = 0 25.<br>- <strong>C++</strong>: <code>&#x27;A&#x27; + i</code> (char arithmetic).<br>- <strong>Pascal</strong>: <code>Chr(Ord(&#x27;A&#x27;) + i)</code>.<br><br>Reference - Modulo dla ujemnych:<br>- Python: <code>(-5) % 26 = 21</code> (zawsze dodatni wynik).<br>- C++: <code>(-5) % 26 = -5</code> (zależy od kompilatora, lepiej <code>((x % 26) + 26) % 26</code>).<br>- Pascal: <code>(-5) mod 26 = -5</code>. Tu klucz dodatni więc nie problem.</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 6.1, max 3 pkt):<br>- <strong>3 pkt</strong> - poprawny plik wynikowy (wszystkie 100 słów)<br>- <strong>2 pkt</strong> - pominięcie ostatniego wiersza<br>- <strong>1 pkt</strong> - błąd zawijania (brak modulo 26) ALBO bez zawijania<br>- <strong>0 pkt</strong> - błędna albo brak</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>Brak <code>mod 26</code></strong> - klucz 107 bez modulo da <code>ord(&#x27;A&#x27;) + 65 + 107 = 237</code> → znak &#x27;<code>í</code>&#x27; lub coś niedrukowalnego. Konieczne <code>% 26</code>.</li><li><strong>Pomyłka <code>mod 26</code> z <code>mod 25</code> lub <code>mod 27</code></strong> - alfabet ma 26 liter.</li><li><strong>Indeksowanie od 1 vs 0</strong> - Pascal stringi indeksowane od 1, Python/C++ od 0.</li><li><strong>Pominięcie ostatniego wiersza</strong> - przy <code>while fin &gt;&gt; s</code> w C++ działa OK, ale <code>while not Eof(fin)</code> w Pascal może pominąć ostatni wiersz, jeśli plik nie kończy się newline.</li><li><strong>Klucz ujemny przy odszyfrowywaniu</strong> - uważać na <code>(x % 26 + 26) % 26</code>.</li><li><strong>Polskie znaki</strong> - w zadaniu są tylko wielkie litery angielskie A-Z; ewentualne polskie znaki pomijamy lub błąd danych.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Szyfrowanie jednego słowa długości L: <strong>O(L)</strong>.</li><li>100 słów × max 30 znaków: <strong>O(3000)</strong> operacji.</li><li>I/O dominuje, ale to też O(N) liniowo.</li></ul>"}]}