Sprawdź się
Zadanie 3. Sklep papierniczy
Sklep Nowa Linia ma szeroki asortyment produktów papierniczych.
Każdy artykuł w sklepie opisany jest następującymi danymi:
id produktu
– liczba całkowita dodatnia, unikatowy numer każdego produktu,rodzaj
– „zeszyt”, „kalendarz”, „notatnik”,rozmiar
– „A3”, „A4”, „A5”,liczba kartek
– liczba całkowita z zakresu ,okladka
– „twarda”, „miekka”.
Przedstawione informacje dla 500 artykułów zostały zapisane w pliku papierniczy.txt
, każdy artykuł w osobnej linii. Informacje dotyczące artykułów zostały oddzielone od siebie pojedynczymi znakami odstępu.
papierniczy.txt
.Korzystając z danych w pliku, wykonaj zadania:
Niektóre dane produktów zostały błędnie wpisane. Zapisz, ile artykułów z błędnymi danymi znajduje się w pliku. Błędne dane rozpoznajemy po tym, że nie spełniają podanych niżej zasad:
Zeszyt w miękkiej okładce nie ma więcej kartek niż 110.
Liczba kartek w notatniku jest liczbą z zakresu .
Kalendarze w rozmiarze A3 występują tylko w miękkiej okładce.
Kalendarze mają zawsze 6 lub 12 kartek.
Produkt łamiący więcej niż jedno kryterium liczymy tylko raz. Produkty z błędnymi danymi nie powinny być uwzględniane podczas wykonywania kolejnych zadań!
Produkty należą do jednej kategorii, jeżeli mają jednakowe następujące dane:
rodzaj
,rozmiar
,liczba kartek
,okładka
.
Dla każdego rodzaju (zeszyt, notatnik oraz kalendarz) zapisz największą liczbę produktów danej kategorii. Kolejne liczby rozdziel znakami odstępu.
Zapisz nazwę rodzaju produktu, który zawiera łącznie najwięcej różnych kategorii produktów oraz łączną liczbę kartek produktów różnych kategorii tego rodzaju.
Sprawdź, czy istnieje produkt o liczbie kartek, która jest liczbą pierwszą. Jeżeli tak, zapisz „tak”, w przeciwnym wypadku zapisz „nie”.
Kolejne odpowiedzi zapisz do pliku wyniki.txt
, każdy podpunkt w nowej linii (wyniki w ramach podpunktów oddziel pojedynczymi znakami odstępu).
Do oceny oddajesz:
plik
wyniki.txt
zawierający odpowiedzi do poleceń,plik(i) z komputerową realizacją zadania (kodem programu).
JĘZYK C++
Przykładowe rozwiązanie zadania wykorzystujące klasę vector
omówioną w materiale Dynamiczne struktury danych w języku C++D18GJWMHoDynamiczne struktury danych w języku C++.
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
struct Produkt {
int id;
string rodzaj;
string rozmiar;
int liczba;
string okladka;
};
struct Kategoria {
string rozmiar;
int liczba;
string okladka;
int l_produktow;
};
// funkcja do podpunktu 4
bool czyPierwsza(int liczba) {
if (liczba < 2) {
return false;
}
int i = 2;
while (i*i <= liczba) {
if (liczba % i == 0)
return false;
i++;
}
return true;
}
Kategoria dodajKategorie(Produkt produkt) {
Kategoria k;
k.rozmiar = produkt.rozmiar;
k.liczba = produkt.liczba;
k.okladka = produkt.okladka;
k.l_produktow = 1;
return k;
}
int dodajProdukt(vector<Kategoria> &kat, Produkt produkt) {
if (!kat.empty()) {
for (int i = 0; i < (int)kat.size(); i++) {
if (kat[i].rozmiar == produkt.rozmiar and kat[i].liczba == produkt.liczba and kat[i].okladka == produkt.okladka) {
kat[i].l_produktow++;
return 0;
}
}
kat.push_back(dodajKategorie(produkt));
}
else
kat.push_back(dodajKategorie(produkt));
return 0;
}
int main() {
const int n = 20;
vector<Produkt> dane;
Produkt p;
int id_produktu[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
string rodzaj[] = {"zeszyt", "zeszyt", "kalendarz", "zeszyt", "notatnik", "zeszyt", "kalendarz", "kalendarz", "zeszyt", "notatnik", "notatnik", "notatnik", "zeszyt", "zeszyt", "kalendarz", "zeszyt", "notatnik", "zeszyt", "zeszyt", "zeszyt"};
string rozmiar[] = {"A3", "A3", "A3", "A5", "A5", "A5", "A4", "A3", "A3", "A5", "A3", "A5", "A3", "A4", "A5", "A3", "A5", "A5", "A5", "A5"};
int liczba_kartek[] = {88, 88, 6, 44, 74, 115, 12, 12, 178, 42, 35, 69, 30, 43, 6, 167, 49, 44, 111, 44};
string okladka[] = {"miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "twarda", "miekka", "twarda", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka"};
// podpunkt 1
int l_bledow = 0;
for (int i = 0; i < n; i++) {
if (rodzaj[i] == "zeszyt")
if (okladka[i] == "miekka" && liczba_kartek[i] > 110) {
l_bledow++;
continue;
}
if (rodzaj[i] == "notatnik")
if (liczba_kartek[i] < 30 || liczba_kartek[i] > 85) {
l_bledow++;
continue;
}
if (rodzaj[i] == "kalendarz") {
if (rozmiar[i] != "A3" && okladka[i] != "miekka") {
l_bledow++;
continue;
} else if (liczba_kartek[i] != 6 && liczba_kartek[i] != 12) {
l_bledow++;
continue;
}
}
p.id = id_produktu[i];
p.rodzaj = rodzaj[i];
p.rozmiar = rozmiar[i];
p.liczba = liczba_kartek[i];
p.okladka = okladka[i];
dane.push_back(p);
}
// przygotowanie kategorii
vector<Kategoria> zeszyty;
vector<Kategoria> notatniki;
vector<Kategoria> kalendarze;
for (int i = 0; i < (int)dane.size(); i++) {
if (dane[i].rodzaj == "zeszyt") {
dodajProdukt(zeszyty, dane[i]);
} else if (dane[i].rodzaj == "notatnik") {
dodajProdukt(notatniki, dane[i]);
} else if (dane[i].rodzaj == "kalendarz") {
dodajProdukt(kalendarze, dane[i]);
}
}
// podpunkt 1
cout << l_bledow << endl;
// podpunkt 2 i 3
int x = 0;
int x_kartki = 0;
int y = 0;
int y_kartki = 0;
int z = 0;
int z_kartki = 0;
for (int i = 0; i < (int)zeszyty.size(); i++) {
if (zeszyty[i].l_produktow > x)
x = zeszyty[i].l_produktow;
x_kartki += zeszyty[i].liczba * zeszyty[i].l_produktow;
}
for (int i = 0; i < (int)notatniki.size(); i++) {
if (notatniki[i].l_produktow > y)
y = notatniki[i].l_produktow;
y_kartki += notatniki[i].liczba * notatniki[i].l_produktow;
}
for (int i = 0; i < (int)kalendarze.size(); i++) {
if (kalendarze[i].l_produktow > z)
z = kalendarze[i].l_produktow;
z_kartki += kalendarze[i].liczba * kalendarze[i].l_produktow;
}
// podpunkt 2: zeszyt, notatnik, kalendarz
cout << x << " " << y << " " << z <<endl;
// cd. podpunkt 3
x = (int)zeszyty.size();
y = (int)notatniki.size();
z = (int)kalendarze.size();
if (x > y && x > z) {
cout << "zeszyty" << " " << x_kartki << endl;
} else if (y > x && y > z) {
cout << "notatniki" << " " << y_kartki << endl;
} else {
cout << "kalendarze" << " " << z_kartki << endl;
}
// podpunkt 4
string czy_istnieje = "nie";
for (int i = 0; i < (int)dane.size(); i++) {
if (czyPierwsza(dane[i].liczba)) {
czy_istnieje = "tak";
break;
}
}
cout << czy_istnieje << endl;
return 0;
}
JĘZYK JAVA
W podanym niżej rozwiązaniu do porównywania ciągów znaków (typ String
) używamy operatora ==
, który zwraca prawdę tylko wtedy, kiedy porównywane ciągi są tymi samymi obiektami, a tak się dzieje dla literałów znakowych umieszczonych w kodzie programu.
Po wczytaniu danych z pliku każdy ciąg znakowy jest innym obiektem, próba porównania go z literałem za pomocą operatora ==
zawsze zwróci fałsz. Właściwym sposobem na porównanie jest w takim wypadku użycie metody equals()
klasy String
, a więc np.:
zamiast
okladka[i] == "miekka"
powinno byćokladka[i].equals("miekka")
,zamiast
okladka[i] != "miekka"
powinno być!okladka[i].equals("miekka")
.
import java.util.*;
class Produkt {
public int id;
public String rodzaj;
public String rozmiar;
public int liczba;
public String okladka;
}
class Kategoria {
public String rozmiar;
public int liczba;
public String okladka;
public int l_produktow;
}
public class Main {
// funkcja do podpunktu 4
static boolean czyPierwsza(int liczba) {
if (liczba < 2) {
return false;
}
int i = 2;
while (i*i <= liczba) {
if (liczba % i == 0) {
return false;
}
i++;
}
return true;
}
static Kategoria dodajKategorie(Produkt produkt) {
Kategoria k = new Kategoria();
k.rozmiar = produkt.rozmiar;
k.liczba = produkt.liczba;
k.okladka = produkt.okladka;
k.l_produktow = 1;
return k;
}
static int dodajProdukt(Vector<Kategoria> kat, Produkt produkt) {
if (!kat.isEmpty()) {
Kategoria k;
for (int i = 0; i < kat.size(); i++) {
k = kat.get(i);
if (k.rozmiar == produkt.rozmiar && k.liczba == produkt.liczba && k.okladka == produkt.okladka) {
k.l_produktow++;
return 0;
}
}
kat.addElement(dodajKategorie(produkt));
}
else
kat.addElement(dodajKategorie(produkt));
return 0;
}
public static void main(String[] args) {
int n = 20;
Vector<Produkt> dane = new Vector<Produkt>();
int[] idProduktu = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
String[] rodzaj = {"zeszyt", "zeszyt", "kalendarz", "zeszyt", "notatnik", "zeszyt", "kalendarz", "kalendarz", "zeszyt", "notatnik", "notatnik", "notatnik", "zeszyt", "zeszyt", "kalendarz", "zeszyt", "notatnik", "zeszyt", "zeszyt", "zeszyt"};
String[] rozmiar = {"A3", "A3", "A3", "A5", "A5", "A5", "A4", "A3", "A3", "A5", "A3", "A5", "A3", "A4", "A5", "A3", "A5", "A5", "A5", "A5"};
int[] liczbaKartek = {88, 88, 6, 44, 74, 115, 12, 12, 178, 42, 35, 69, 30, 43, 6, 167, 49, 44, 111, 44};
String[] okladka = {"miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "twarda", "miekka", "twarda", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka"};
// podpunkt 1
int l_bledow = 0;
for (int i = 0; i < n; i++) {
if (rodzaj[i] == "zeszyt")
if (okladka[i] == "miekka" && liczbaKartek[i] > 110) {
l_bledow++;
continue;
}
if (rodzaj[i] == "notatnik")
if (liczbaKartek[i] < 30 || liczbaKartek[i] > 85) {
l_bledow++;
continue;
}
if (rodzaj[i] == "kalendarz") {
if (rozmiar[i] != "A3" && okladka[i] != "miekka") {
l_bledow++;
continue;
} else if (liczbaKartek[i] != 6 && liczbaKartek[i] != 12) {
l_bledow++;
continue;
}
}
Produkt p = new Produkt();
p.id = idProduktu[i];
p.rodzaj = rodzaj[i];
p.rozmiar = rozmiar[i];
p.liczba = liczbaKartek[i];
p.okladka = okladka[i];
dane.addElement(p);
}
// przygotowanie kategorii
Vector<Kategoria> zeszyty = new Vector<Kategoria>();
Vector<Kategoria> notatniki = new Vector<Kategoria>();
Vector<Kategoria> kalendarze = new Vector<Kategoria>();
Produkt p = new Produkt();
for (int i = 0; i < dane.size(); i++) {
p = dane.get(i);
if (p.rodzaj == "zeszyt") {
dodajProdukt(zeszyty, p);
} else if (p.rodzaj == "notatnik") {
dodajProdukt(notatniki, p);
} else if (p.rodzaj == "kalendarz") {
dodajProdukt(kalendarze, p);
}
}
// podpunkt 1
System.out.println(l_bledow);
// podpunkt 2 i 3
int x = 0;
int x_kartki = 0;
int y = 0;
int y_kartki = 0;
int z = 0;
int z_kartki = 0;
for (int i = 0; i < zeszyty.size(); i++) {
if (zeszyty.get(i).l_produktow > x)
x = zeszyty.get(i).l_produktow;
x_kartki += zeszyty.get(i).liczba * zeszyty.get(i).l_produktow;
}
for (int i = 0; i < notatniki.size(); i++) {
if (notatniki.get(i).l_produktow > y)
y = notatniki.get(i).l_produktow;
y_kartki += notatniki.get(i).liczba * notatniki.get(i).l_produktow;
}
for (int i = 0; i < kalendarze.size(); i++) {
if (kalendarze.get(i).l_produktow > z)
z = kalendarze.get(i).l_produktow;
z_kartki += kalendarze.get(i).liczba * kalendarze.get(i).l_produktow;
}
// podpunkt 2: zeszyt, notatnik, kalendarz
System.out.println(x + " " + y + " " + z);
// cd. podpunkt 3
x = zeszyty.size();
y = notatniki.size();
z = kalendarze.size();
if (x > y && x > z)
System.out.println("zeszyty" + " " + x_kartki);
else if (y > x && y > z)
System.out.println("notatniki" + " " + y_kartki);
else
System.out.println("kalendarze" + " " + z_kartki);
// podpunkt 4
String czyIstnieje = "nie";
for (int i = 0; i < dane.size(); i++) {
if (czyPierwsza(dane.get(i).liczba)) {
czyIstnieje = "tak";
break;
}
}
System.out.println("tak");
}
}
JĘZYK PYTHON
Przykładowe rozwiązanie wykorzystuje instrukcję zip()
, która iteruje po podanych jako argumenty listach i zwraca tuple zawierające paralelne elementy z każdej z nich. Listy muszą zawierać taką samą liczbę elementów. Zobacz przykłady w trybie interaktywnym interpretera:
>>> l1 = ['a', 'b', 'c']
>>> l2 = [3, 2, 1]
>>> l_tupli = list(zip(l1, l2))
>>> l_tupli
[('a', 3), ('b', 2), ('c', 1)]
Jeżeli instrukcja dict()
otrzyma sekwencję tupli zawierających klucze i wartości, zwraca słownik:
>>> dict(zip(l1, l2))
{'a': 3, 'b': 2, 'c': 1}
Słowo kluczowe lambda
służy do tworzenia prostych anonimowych funkcji, które używane są w programie zazwyczaj tylko raz. Np. ekwiwalentem funkcji, która sumuje dwa elementy:
>>> def suma(a, b):
... return a + b
jest wyrażenia lambda
:
>>> f = lambda a, b: a + b
>>> a, b = 3, 4
>>> print(f(a, b))
7
Wyrażenia lambda
używa się w instrukcjach sorted()
, max()
lub min()
jako opcjonalnego argumentu key
do wskazania elementu, według którego sortujemy lub wyszukujemy, np.:
>>> l_tupli
[('a', 3), ('b', 2), ('c', 1)]
>>> sorted(l_tupli, key=lambda x: x[1])
[('c', 1), ('b', 2), ('a', 3)]
>>> max(l_tupli, key=lambda x: x[1])
('a', 3)
Rozwiązanie:
# funkcja do podpunktu 4
def czy_pierwsza(liczba):
if liczba < 2:
return False
i = 2
while i*i <= liczba:
if liczba % i == 0:
return False
i += 1
return True
def dodaj_kategorie(p):
klucze = ["rozmiar", "liczba", "okladka", "l_produktow"]
return dict(zip(klucze, (p["rozmiar"], p["liczba"], p["okladka"], 1)))
def dodaj_produkt(kategoria, p):
if kategoria:
for k in kategoria:
if k["rozmiar"] == p["rozmiar"] and k["liczba"] == p["liczba"] and k["okladka"] == p["okladka"]:
k["l_produktow"] += 1
return
kategoria.append(dodaj_kategorie(p))
else:
kategoria.append(dodaj_kategorie(p))
dane = []
klucze = ["id", "rodzaj", "rozmiar", "liczba", "okladka"]
id_produktu = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
rodzaj = ["zeszyt", "zeszyt", "kalendarz", "zeszyt", "notatnik", "zeszyt", "kalendarz", "kalendarz", "zeszyt", "notatnik", "notatnik", "notatnik", "zeszyt", "zeszyt", "kalendarz", "zeszyt", "notatnik", "zeszyt", "zeszyt", "zeszyt"]
rozmiar = ["A3", "A3", "A3", "A5", "A5", "A5", "A4", "A3", "A3", "A5", "A3", "A5", "A3", "A4", "A5", "A3", "A5", "A5", "A5", "A5"]
liczba_kartek = [88, 88, 6, 44, 74, 115, 12, 12, 178, 42, 35, 69, 30, 43, 6, 167, 49, 44, 111, 44]
okladka = ["miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka", "twarda", "miekka", "twarda", "miekka", "miekka", "miekka", "miekka", "miekka", "miekka"]
# podpunkt 1
l_bledow = 0
for produkt in [dict(zip(klucze, p)) for p in zip(id_produktu, rodzaj, rozmiar, liczba_kartek, okladka)]:
if produkt["rodzaj"] == "zeszyt":
if produkt["okladka"] == "miekka" and produkt["liczba"] > 110:
l_bledow += 1
continue
elif produkt["rodzaj"] == "notatnik":
if (produkt["liczba"] < 30 or produkt["liczba"] > 85):
l_bledow += 1
continue
else:
if produkt["rozmiar"] == "A3" and produkt["okladka"] != "miekka":
l_bledow += 1
continue
elif produkt["liczba"] != 6 and produkt["liczba"] != 12:
l_bledow += 1
continue
dane.append(produkt)
# przygotowanie kategorii
zeszyty = []
notatniki = []
kalendarze = []
for produkt in dane:
if produkt["rodzaj"] == "zeszyt":
dodaj_produkt(zeszyty, produkt)
elif produkt["rodzaj"] == "notatnik":
dodaj_produkt(notatniki, produkt)
else:
dodaj_produkt(kalendarze, produkt)
# podpunkt 1
print(l_bledow)
# podpunkt 2
max_produktow = []
if zeszyty:
max_produktow.append(max(zeszyty, key=lambda p: p['l_produktow'])['l_produktow'])
if notatniki:
max_produktow.append(max(notatniki, key=lambda p: p['l_produktow'])['l_produktow'])
if kalendarze:
max_produktow.append(max(kalendarze, key=lambda p: p['l_produktow'])['l_produktow'])
# zeszyt, notatnik, kalendarz
print(*max_produktow)
# podpunkt 3
kategoria = zeszyty
max_kategorii = len(zeszyty)
nazwa = "zeszyty"
if len(notatniki) > max_kategorii:
max_kategorii = len(notatniki)
kategoria = notatniki
nazwa = "notatniki"
if len(kalendarze) > max_kategorii:
kategoria = kalendarze
nazwa = "kalendarze"
l_kartek = sum(p['liczba'] * p['l_produktow'] for p in kategoria)
print(nazwa, l_kartek)
# podpunkt 4
czy_istnieje = "nie"
for produkt in dane:
if czy_pierwsza(produkt["liczba"]):
czy_istnieje = "tak"
break
print(czy_istnieje)
Wyniki dla pliku papierniczy.txt
:
73
3 4 59
notatniki 8951
tak