# Informatyka — zadanie 6.3

> Źródło: matura.lol — https://matura.lol/question/maturazai-informatyka-inf-2019-05/zad/6.3
> Wersja Markdown strony zadania (dla asystentów AI). Przy cytowaniu podaj matura.lol i link powyżej.

- arkusz: Informatyka · Matura · maj 2019 (rozszerzona)
- rok: 2019
- poziom: rozszerzona
- typ: open
- punkty: 3
- działy: Programowanie i algorytmika

## Treść

Kontekst - patrz zadanie 6.1.

Utwórz uporządkowaną alfabetycznie listę wszystkich nazw marek, które nie zawierają w swoich perfumach żadnego składnika mającego w nazwie słowo „paczula”.

## Rozwiązanie — maturazai.pl (AI)

## Poprawna odpowiedź

**Marki bez "paczuli" wśród składników (alfabetycznie):**
Aison Eranciro
Arthbey
Embert Lucas
Enmith
Nnick a Kieffo

## Sposób 1 - SQL z NOT EXISTS

```sql
SELECT m.nazwa_m
FROM marki m
WHERE NOT EXISTS (
SELECT 1
FROM perfumy p
INNER JOIN sklad s ON p.id_perfum = s.id_perfum
WHERE p.id_marki = m.id_marki
AND s.nazwa_skladnika LIKE '%paczula%'
)
ORDER BY m.nazwa_m;

**Wyjaśnienie:**
- Główne zapytanie: marki.
- Podzapytanie: czy marka ma jakiś składnik z "paczula" w nazwie?
- `NOT EXISTS`: zwróć marki, które **nie mają** takiego składnika.
- `LIKE '%paczula%'`: "paczula" gdziekolwiek w nazwie (np. "paczula indonezyjska", "olejek z paczuli").
- `ORDER BY`: sortowanie alfabetyczne.

## Sposób 2 - SQL alternatywne (LEFT JOIN + WHERE NULL)

```sql
SELECT DISTINCT m.nazwa_m
FROM marki m
WHERE m.id_marki NOT IN (
SELECT DISTINCT p.id_marki
FROM perfumy p
INNER JOIN sklad s ON p.id_perfum = s.id_perfum
WHERE s.nazwa_skladnika LIKE '%paczula%'
)
ORDER BY m.nazwa_m;

## Sposób 3 - Python

```python
# Wczytaj marki: id -> nazwa
marki = {}
with open('marki.txt', encoding='utf-8') as f:
f.readline()
for linia in f:
id_m, nazwa = linia.strip().split('\t')
marki[id_m] = nazwa

# Wczytaj perfumy: id_perfum -> id_marki
perf_marka = {}
with open('perfumy.txt', encoding='utf-8') as f:
f.readline()
for linia in f:
pola = linia.strip().split('\t')
perf_marka[pola[0]] = pola[2]

# Znajdź marki, które mają składnik z "paczula"
marki_z_paczula = set()
with open('sklad.txt', encoding='utf-8') as f:
f.readline()
for linia in f:
id_p, nazwa_skl = linia.strip().split('\t')
if 'paczula' in nazwa_skl.lower():
id_m = perf_marka.get(id_p)
if id_m:
marki_z_paczula.add(id_m)

# Marki BEZ paczuli
wynik = sorted([marki[id_m] for id_m in marki if id_m not in marki_z_paczula])
for m in wynik:
print(m)

## Sposób 4 - arkusz kalkulacyjny

**Krok 1:** w sklad.txt - kolumna pomocnicza C: `=JEŻELI(ISNUMBER(SZUKAJ.TEKST("paczula"; B2)); A2; "")`. To daje id_perfum jeśli składnik zawiera paczulę.

**Krok 2:** zbierz unikalne id_perfum (zaawansowany filtr lub UNIQUE).

**Krok 3:** dopasuj id_perfum → id_marki (VLOOKUP w perfumy.txt).

**Krok 4:** lista wszystkich marek minus te z paczulą - formuła `IF(COUNTIF(zlepaczula; id_marki) = 0; nazwa; "")`.

**Krok 5:** sortuj alfabetycznie.

## Reference informatyczny - NOT EXISTS vs NOT IN

> Reference - Subqueries z negacją:
> - `NOT EXISTS (SELECT WHERE )`: efektywne, działa poprawnie z NULL.
> - `NOT IN (SELECT )`: prostsze, ale ma pułapkę - jeśli podzapytanie zwróci NULL, cały warunek staje się UNKNOWN (faktycznie FALSE)!
> - **Preferowane: `NOT EXISTS`** - bezpieczniejsze.
>
> Reference - LIKE z wildcardami:
> - `%paczula%` - "paczula" gdziekolwiek (start, środek, koniec).
> - `paczula%` - zaczyna od "paczula".
> - `%paczula` - kończy na "paczula".
> - `_paczula_` - z dokładnie jednym znakiem przed i po.

## Schemat oceniania CKE

> Klucz CKE (zadanie 6.3, max 3 pkt):
> - **2 pkt** - zastosowanie filtra `*paczula*` (= `%paczula%`)
> - **1 pkt** - filtr `paczula*` lub samo `paczula` (zamiast `*paczula*`) - niepełne
> - **1 pkt** - sortowanie alfabetyczne
> - **0 pkt** - błędna lub brak

## Typowe pułapki

- **`= 'paczula'`** zamiast `LIKE '%paczula%'` - pominie składniki typu "olejek paczuli".
- **`paczula%`** - pominie składniki typu "olejek paczuli" (nie zaczyna się od paczula).
- **Pomylenie polskich znaków** - "paczula" (litera 'l') vs "paczuli" (l, ale forma deklinacyjna).
- **Brak sortowania** - utrata 1 punktu.
- **`NOT IN` z NULL** - może spowodować błędy. Lepiej `NOT EXISTS`.
- **Pomylenie kierunku** - listujemy marki BEZ paczuli, NIE marki Z paczulą.

## Złożoność obliczeniowa

- SQL z indeksami: O(n log n) sortowanie + O(n + m) join.
- Python: O(n + m) - dwa przejścia przez pliki.
- Pamięć: O(liczba marek + liczba składników z paczulą).

## Linki

- [dane JSON](https://matura.lol/api/question/maturazai-informatyka-inf-2019-05/zad/6.3)
- [otwórz w wyszukiwarce](https://matura.lol/?problem=maturazai-informatyka-inf-2019-05%2Fzad%2F6.3)

## Podobne zadania

- [Zadanie 1.1](https://matura.lol/question/informatyka-2022-maj-matura-rozszerzona/zad/1.1) — Zadanie 1.1. (0-2) Uzupełnij poniższą tabelę - dla każdego z podanych ciągów podaj najmniejszą liczbę elementów, które trzeba podmienić, aby dany ciąg był n-per

_Ostatnia aktualizacja danych: 2026-10-03_
