{"id":"informatyka-2018-maj-matura-rozszerzona/zad/6.3","paper_id":"informatyka-2018-maj-matura-rozszerzona","number":"6.3","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2018,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 6.1.\n\nPewnego dnia nastąpiła awaria wszystkich komputerów w jednej z sekcji. Podaj datę awarii oraz symbol sekcji, w której nastąpiła awaria.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Data awarii: 23-12-2015**\n\n**Sekcja: Q**\n\n## Sposób 1 - analiza zadania\n\n**Cel:** znaleźć datę X i sekcję S takie, że WSZYSTKIE komputery sekcji S miały awarię tego dnia.\n\n**Algorytm:**\n1. Dla każdej kombinacji (data, sekcja) policz liczbę UNIKALNYCH komputerów, które miały awarię tego dnia.\n2. Dla każdej sekcji znajdź liczbę komputerów w sekcji.\n3. Znajdź kombinację gdzie obie liczby są EQ.\n\n## Sposób 2 - SQL\n\n```sql\nSELECT DATE(a.Czas_awarii) AS dzien, k.Sekcja, COUNT(DISTINCT k.Numer_komputera) AS uszkodzone\nFROM awarie a\nJOIN komputery k ON a.Numer_komputera = k.Numer_komputera\nGROUP BY DATE(a.Czas_awarii), k.Sekcja\nHAVING COUNT(DISTINCT k.Numer_komputera) = (\nSELECT COUNT(*)\nFROM komputery k2\nWHERE k2.Sekcja = k.Sekcja\n);\n\nWynik: **(2015-12-23, Q)**.\n\n## Sposób 3 - Python\n\n```python\nfrom collections import defaultdict\n\n# Wczytaj komputery: pesel -> sekcja\nkomputer_sekcja = {}\nsekcja_liczba = defaultdict(int)\nwith open('komputery.txt', encoding='utf-8') as f:\nnext(f)\nfor linia in f:\ncz = linia.strip().split('\\t')\nif len(cz) >= 3:\nkom, sek = cz[0], cz[1]\nkomputer_sekcja[kom] = sek\nsekcja_liczba[sek] += 1\n\n# Mapuj (data, sekcja) -> set(komputerów z awarią tego dnia)\nawarie = defaultdict(set)\nwith open('awarie.txt', encoding='utf-8') as f:\nnext(f)\nfor linia in f:\ncz = linia.strip().split('\\t')\nif len(cz) >= 4:\nkom = cz[1]\nczas = cz[2] # format: \"2015-01-01 04:40:55\"\ndata = czas[:10] # \"2015-01-01\"\nsek = komputer_sekcja.get(kom)\nif sek:\nawarie[(data, sek)].add(kom)\n\n# Znajdź (data, sekcja) gdzie awaria objęła wszystkie komputery sekcji\nfor (data, sek), uszkodzone in awarie.items():\nif len(uszkodzone) == sekcja_liczba[sek]:\nprint(f\"Data: {data}, Sekcja: {sek}, Komputerów: {len(uszkodzone)}\")\n# Data: 2015-12-23, Sekcja: Q, Komputerów: X\n\n## Sposób 4 - arkusz kalkulacyjny\n\n1. W komputery.txt: kolumna A = numer, B = sekcja.\n2. W awarie.txt: dodaj kolumnę pomocniczą E = `=LEWY(C2; 10)` (data bez godz.).\n3. JOIN: kolumna F = `=WYSZUKAJ.PIONOWO(B2; komputery!A:B; 2; FAŁSZ)` (sekcja).\n4. **Tabela przestawna**: wiersze = (E, F), wartości = LICZNIK.UNIKATOWE komputerów.\n5. Dla każdej sekcji: liczba wszystkich komputerów (`=LICZ.JEŻELI(komputery!B:B; \"Q\")`).\n6. Znajdź wiersz, gdzie liczba uszkodzonych = liczba całkowita sekcji.\n\n## Reference informatyczny - wszystkie elementy grupy\n\n> Reference - Sprawdzenie \"wszystkie z grupy\":\n> - Liczba awarii w grupie = liczba całkowita grupy → wszystkie elementy.\n> - Alternatywnie: `NOT EXISTS (SELECT 1 FROM grupa WHERE el NOT IN awarie)`.\n>\n> Reference - DATE() w SQL:\n> - `DATE(timestamp)` - wyciąga datę z timestampa.\n> - `SUBSTRING(czas, 1, 10)` - ręczne wyciągnięcie pierwszych 10 znaków.\n> - W Python: `czas[:10]` lub `datetime.strptime(czas, ).date()`.\n>\n> Reference - Korelowany podzapytanie:\n> - Podzapytanie odwołujące się do wartości z głównego zapytania.\n> - Np. `(SELECT COUNT(*) FROM komputery k2 WHERE k2.Sekcja = k.Sekcja)`.\n> - Wykonywane RAZ na wiersz głównego zapytania (potencjalnie wolne, ale tu mało danych).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.3, max 3 pkt):\n> - **2 pkt** za prawidłową datę (23-12-2015)\n> - **1 pkt** za prawidłową sekcję (Q)\n> - **0 pkt** - błędne lub brak\n\n## Typowe pułapki\n\n- **Format daty: 2015-12-23 vs 23-12-2015** - CKE oczekuje w formacie z treści (DD-MM-YYYY w odpowiedzi).\n- **Liczenie awarii zamiast komputerów** - jeden komputer może mieć WIELE awarii tego samego dnia. Liczymy UNIKALNE komputery (DISTINCT).\n- **Pomyłka sekcji** - uważać na pomyłkę z innym dniem (mogło być wiele dni z niemal-pełną awarią sekcji).\n- **Tylko COUNT na awariach** - nie wystarczy; trzeba zliczać DISTINCT lub używać set.\n- **Pominięcie warunku \"wszystkich\"** - wymóg to 100% sekcji, nie 99%.\n\n## Złożoność obliczeniowa\n\n- Wczytanie 3 plików: O(K + A + N).\n- Agregacja po (data, sekcja): O(A) z hashmapą.\n- Sprawdzenie warunku dla każdej grupy: O(S·D) gdzie S = sekcje, D = dni.\n- **Łącznie: O(A + K).**","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 2018 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura","text_html":"<p>Kontekst - patrz zadanie 6.1.</p>\n<p>Pewnego dnia nastąpiła awaria wszystkich komputerów w jednej z sekcji. Podaj datę awarii oraz symbol sekcji, w której nastąpiła awaria.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Data awarii: 23-12-2015</strong></p>\n<p><strong>Sekcja: Q</strong></p>\n<h4>Sposób 1 - analiza zadania</h4>\n<p><strong>Cel:</strong> znaleźć datę X i sekcję S takie, że WSZYSTKIE komputery sekcji S miały awarię tego dnia.</p>\n<p><strong>Algorytm:</strong></p>\n<ol><li>Dla każdej kombinacji (data, sekcja) policz liczbę UNIKALNYCH komputerów, które miały awarię tego dnia.</li><li>Dla każdej sekcji znajdź liczbę komputerów w sekcji.</li><li>Znajdź kombinację gdzie obie liczby są EQ.</li></ol>\n<h4>Sposób 2 - SQL</h4>\n<p>```sql<br>SELECT DATE(a.Czas_awarii) AS dzien, k.Sekcja, COUNT(DISTINCT k.Numer_komputera) AS uszkodzone<br>FROM awarie a<br>JOIN komputery k ON a.Numer_komputera = k.Numer_komputera<br>GROUP BY DATE(a.Czas_awarii), k.Sekcja<br>HAVING COUNT(DISTINCT k.Numer_komputera) = (<br>SELECT COUNT(*)<br>FROM komputery k2<br>WHERE k2.Sekcja = k.Sekcja<br>);</p>\n<p>Wynik: <strong>(2015-12-23, Q)</strong>.</p>\n<h4>Sposób 3 - Python</h4>\n<p>```python<br>from collections import defaultdict</p>\n<h3>Wczytaj komputery: pesel -&gt; sekcja</h3>\n<p>komputer_sekcja = {}<br>sekcja_liczba = defaultdict(int)<br>with open(&#x27;komputery.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>next(f)<br>for linia in f:<br>cz = linia.strip().split(&#x27;\\t&#x27;)<br>if len(cz) &gt;= 3:<br>kom, sek = cz[0], cz[1]<br>komputer_sekcja[kom] = sek<br>sekcja_liczba[sek] += 1</p>\n<h3>Mapuj (data, sekcja) -&gt; set(komputerów z awarią tego dnia)</h3>\n<p>awarie = defaultdict(set)<br>with open(&#x27;awarie.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>next(f)<br>for linia in f:<br>cz = linia.strip().split(&#x27;\\t&#x27;)<br>if len(cz) &gt;= 4:<br>kom = cz[1]<br>czas = cz[2] # format: &quot;2015-01-01 04:40:55&quot;<br>data = czas[:10] # &quot;2015-01-01&quot;<br>sek = komputer_sekcja.get(kom)<br>if sek:<br>awarie[(data, sek)].add(kom)</p>\n<h3>Znajdź (data, sekcja) gdzie awaria objęła wszystkie komputery sekcji</h3>\n<p>for (data, sek), uszkodzone in awarie.items():<br>if len(uszkodzone) == sekcja_liczba[sek]:<br>print(f&quot;Data: {data}, Sekcja: {sek}, Komputerów: {len(uszkodzone)}&quot;)</p>\n<h3>Data: 2015-12-23, Sekcja: Q, Komputerów: X</h3>\n<h4>Sposób 4 - arkusz kalkulacyjny</h4>\n<ol><li>W komputery.txt: kolumna A = numer, B = sekcja.</li><li>W awarie.txt: dodaj kolumnę pomocniczą E = <code>=LEWY(C2; 10)</code> (data bez godz.).</li><li>JOIN: kolumna F = <code>=WYSZUKAJ.PIONOWO(B2; komputery!A:B; 2; FAŁSZ)</code> (sekcja).</li><li><strong>Tabela przestawna</strong>: wiersze = (E, F), wartości = LICZNIK.UNIKATOWE komputerów.</li><li>Dla każdej sekcji: liczba wszystkich komputerów (<code>=LICZ.JEŻELI(komputery!B:B; &quot;Q&quot;)</code>).</li><li>Znajdź wiersz, gdzie liczba uszkodzonych = liczba całkowita sekcji.</li></ol>\n<h4>Reference informatyczny - wszystkie elementy grupy</h4>\n<blockquote>Reference - Sprawdzenie &quot;wszystkie z grupy&quot;:<br>- Liczba awarii w grupie = liczba całkowita grupy → wszystkie elementy.<br>- Alternatywnie: <code>NOT EXISTS (SELECT 1 FROM grupa WHERE el NOT IN awarie)</code>.<br><br>Reference - DATE() w SQL:<br>- <code>DATE(timestamp)</code> - wyciąga datę z timestampa.<br>- <code>SUBSTRING(czas, 1, 10)</code> - ręczne wyciągnięcie pierwszych 10 znaków.<br>- W Python: <code>czas[:10]</code> lub <code>datetime.strptime(czas, ).date()</code>.<br><br>Reference - Korelowany podzapytanie:<br>- Podzapytanie odwołujące się do wartości z głównego zapytania.<br>- Np. <code>(SELECT COUNT(*) FROM komputery k2 WHERE k2.Sekcja = k.Sekcja)</code>.<br>- Wykonywane RAZ na wiersz głównego zapytania (potencjalnie wolne, ale tu mało danych).</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 6.3, max 3 pkt):<br>- <strong>2 pkt</strong> za prawidłową datę (23-12-2015)<br>- <strong>1 pkt</strong> za prawidłową sekcję (Q)<br>- <strong>0 pkt</strong> - błędne lub brak</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>Format daty: 2015-12-23 vs 23-12-2015</strong> - CKE oczekuje w formacie z treści (DD-MM-YYYY w odpowiedzi).</li><li><strong>Liczenie awarii zamiast komputerów</strong> - jeden komputer może mieć WIELE awarii tego samego dnia. Liczymy UNIKALNE komputery (DISTINCT).</li><li><strong>Pomyłka sekcji</strong> - uważać na pomyłkę z innym dniem (mogło być wiele dni z niemal-pełną awarią sekcji).</li><li><strong>Tylko COUNT na awariach</strong> - nie wystarczy; trzeba zliczać DISTINCT lub używać set.</li><li><strong>Pominięcie warunku &quot;wszystkich&quot;</strong> - wymóg to 100% sekcji, nie 99%.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Wczytanie 3 plików: O(K + A + N).</li><li>Agregacja po (data, sekcja): O(A) z hashmapą.</li><li>Sprawdzenie warunku dla każdej grupy: O(S·D) gdzie S = sekcje, D = dni.</li><li><strong>Łącznie: O(A + K).</strong></li></ul>"}]}