Zadanie projektowe
Napisać fantastyczny program, który będzie wyświetlać w oknie przypominającym ekran oscyloskopu dane wejściowe (w trybie graficznym biblioteki Allegro 4) i/lub wykonywać na nich kilka śmiesznych operacji. :).
Argumenty uruchomienia programu są następujące:
./oscyloskop (-b | -t) <nazwa_pliku_we> -o <nazwa_pliku_wy> (-s | -d | -i | -p) [-g]
gdzie -b oznacza format binarny, -t format tekstowy, -o poprzedza plik wynikowy (tylko format tekstowy), -g wyświetlenie wyników także w postaci graficznej (argument opcjonalny). Kolejność argumentów jest dowolna. Opcja -p nie potrzebuje pliku wynikowego.
W pliku binarnym pierwsze 32 bity mają specjalne znaczenie. Zapalony najstarszy bit (MSB) oznacza, że dane będą typu double. Zgaszony MSB oznacza, że będą typu float. Pozostałe bity określają liczbę danych. Następnie następuje określona liczba danych typu double lub float.
Dane do testowania programu.
Część III - 8 czerwca 2016 r.
Etapy rozwiązania:
- {2 pkt.} Funkcja sygnal normalizuj (const sygnal &dane) zwracająca sygnał znormalizowany do przedziału [-1 : +1] niezależnie w obu osiach. [sygnał.cpp]
- {2,5 pkt.} Funkcja void rysuj_okno (BITMAP *ekran, int kolor_tla, int kolor_kratki) - czyści ekran na podany kolor tła (clear_to_color()), rysuje kratki ekranu oscyloskopu: główne linie ciągłe (line()), pozostałe kropkowane (putpixel()). [grafika.cpp]
- {3,5 pkt.} Funkcja void rysuj_wykres (BITMAP *ekran, const sygnal &dane, int kolor, double amp = 1.0, double offsety = 0.0) - wykreśla dane wewnątrz podanej ramki na określony kolor (line()). Stosuje podane wzmocnienie sygnału oraz przesunięcie pionowe. [grafika.cpp]
- {2 pkt.} Wywołanie w funkcji main() napisanych dziś funkcji rysujących, które w efekcie dadzą piękne okno oscyloskopu z wykresami. W przypadku dwóch kanałów (dane wejściowe i wyjściowe) wykresy rysowane są ze wzmocnieniem 0.5 i przesunięciem +/- 0.5. [main.cpp]
Część II - 1 czerwca 2016 r.
Etapy rozwiązania:
- {1 pkt.} Funkcja double max (const double *dane, size_t rozmiar) zwracająca wartość największą sygnału. [sygnal.cpp]
- {0,5 pkt.} Funkcja double min (const double *dane, size_t rozmiar) zwracająca wartość najmniejszą sygnału. [sygnal.cpp]
- {1 pkt.} Funkcja sygnal wygladz (const sygnal &dane) zwracająca wygładzony sygnał (średnia 3 sąsiednich punktów). [sygnal.cpp]
- {1.5 pkt.} Funkcja sygnal pochodna (const sygnal &dane) zwracająca pochodną numeryczną sygnału. [sygnal.cpp]
- {1.5 pkt.} Funkcja sygnal calka (const sygnal &dane) zwracająca całkę numeryczną sygnału. [sygnal.cpp]
- {1 pkt.} Funkcje otwierające i zamykające okno biblioteki graficznej Allegro. [grafika.cpp]
- {1,5 pkt.} Modyfikacja funkcji main() tak, aby wypisywała do pliku wyjściowego obliczoną funkcję. [main.cpp]
- {1 pkt.} Po dokonanych obliczeniach, jeśli jest włączony przełącznik trybu graficznego, wyświetlenie pustego okna o rozmiarach 600x600 px i czekanie na wciśnięcie dowolnego klawisza. [main.cpp]
- {1 pkt.} Usunięcie tablic na stercie. [main.cpp]
Część I - 25 maja 2016 r.
Etapy rozwiązania:
- {0,5 pkt.} Typ wyliczeniowy rodzaj_pliku (binerny / tekstowy), typ wyliczeniowy rodzaj_operacji (s / d / i / p). [arg.h]
- {0,5 pkt.} Struktura opcje_programu zawierająca nazwę pliku wejściowego, typ pliku wejściowego, rodzaj operacji, nazwę pliku wyjściowego oraz typ logiczny (bool) związany z opcją trybu graficznego. [arg.h]
- {2 pkt.} Funkcja opcje_programu analizuj_opcje_programu (int argc, char *arg[]) analizująca argumenty uruchomieniowe programu i zwracająca wypełniony obiekt struktury. W przypadku braku wszystkich wymaganych parametrów, wyświetla czytelny komunikat o błędzie i kończy program. [arg.cpp]
- {0,5 pkt.} Struktura sygnal zawierająca wskaźniki na dwie tablicę typu double (x oraz y) oraz rozmiar tychże tablicy. [io.h]
- {2 pkt.} Funkcja sygnal wczytaj_dane (const opcje_programu &op) wczytująca i zwracająca dane z pliku wejściowego. [io.cpp]
- {1 pkt.} Funkcja void zapisz_dane (const opcje_programu &op, const sygnal &dane) zapisująca dane do pliku wyjściowego (w dwóch kolumnach oddzielonych tabulacją). [io.cpp]
- {1,5 pkt.} Test modułowy: funkcja main() wywołująca powyższe funkcje tak, aby program wczytał dane z pliku wejściowego i wypisał je do pliku wyjściowego. [main.cpp]
- {2 pkt.} Podział na pliki źródłowe, nagłówkowe oraz Makefile.
Zadania laboratoryjne
Zadanie #10 - 18 maja 2016 r.
Wykorzystując bibliotekę Ncurses, napisać grę polegającą na pogoni za biegającymi chaotycznie postaciami na planszy. Po uruchomieniu gry użytkownik jest pytany o rozmiar planszy oraz liczbę gonionych postaci. Gra kończy się w momencie złapania ostatniej postaci.
Etapy rozwiązania (po 1 pkt.):
- Struktura struct postac zawierająca położenie postaci i jej status życiowy (żywa/martwa). [postac.h] {0,5 pkt.}
- Funkcja postac *generuj_postacie (size_t szerokosc, size_t wysokosc, size_t n) - zwraca listę jednokierunkową żywych postaci rozlosowanych na planszy o podanym rozmiarze. [postac.cpp] {1,5 pkt.}
- Funkcja void ruch_postaci (postac *lista, size_t szerokosc, size_t wysokosc) - wykonuje ruch każdej postaci o jeden w losowym kierunku, pilnując aby postać nie wyskoczyła z planszy. [postac.cpp] {2 pkt.}
- Funkcja size_t ile_zywych (const postac *lista) - zwraca liczbę żywych postaci z listy. [postac.cpp] {0,5 pkt.}
- Funkcja void lapanka (const postac *bohater, const postac *lista) - sprawdza, czy bohater złapał jakąś postać; jeśli tak, to zmienia jej status życiowy. [postac.cpp]
- Funkcja pomocnicza void rysuj_ramke (size_t szerokosc, size_t wysokosc) - rysuje ramkę o podanych rozmiarach. [ekran.cpp] {0,5 pkt.}
- Funkcja void rysuj_plansze (const postac *bohater, const postac *lista, size_t szerokosc, size_t wysokosc) - czyści ekran, rysuje ramkę, wyświetla naszego bojatera oraz wszystkie postaci z listy na planszy. [ekran.cpp]
- Funkcja main()- pyta o parametry gry, rozlosowuje położenia początkowe oraz prowadzi zabawę do czasu złapania wszystkich postaci lub wciśnięcia sklawisza ESC. [main.cpp] {3 pkt.}
Fantastyczny szablon programu wraz z Makefile
Zadanie #9 - 11 maja 2016 r.
Napisać generator liczb losowych o dwóch rozkładach: a) jednostajnego pomiędzy wartością minimalną a maksymalną; b) Gaussa. Wybór rozkładu, rozmiar próbki oraz jego parametry określane są jako argumenty wywołania programu. Liczby wypisywane są na standardowe wyjście. Na ekran wypisuje się także faktyczne parametry rozkładu (wartość średnia i odchylenie standardowe). Komunikaty o błędach na standardowe wyjście błędów. Użyć wskaźników na funkcje!
Przykłady użycia:
a) 10000 liczb o rozkładzie Gaussa (3; 0,15):
./program09 -G 10000 3 0.15
b) 5000 liczb o rozkładzie jednostajnym pomiędzy -100 a +100:
./program09 -J 5000 -100 +100
Etapy rozwiązania (po 1 pkt.):
- Funkcja double generator_gaussa (double m, double s) zwracająca jedną liczbę z rozkładu Gaussa (m, s).
- Funkcja double generator_jednostajny (double min, double max) zwracająca jedną liczbę z rozkładu jednostajnego o wartości z zakresu (min, max).
- Analiza parametrów uruchomienia programu, sprawdzenie ich poprawności i przypisanie do wskaźnika funkcji wybranego rozkładu. {1,5 pkt.}
- Funkcja double *generator_losowych (double (*generator) (double, double), size_t n, double p1, double p2) zwracająca wskaźnik na tablicę na stercie (przydzielić pamięć!) zawierającą n liczb losowych wygenerowanych przez podany generator, o parametrach p1 i p2. {2 pkt.}
- Funkcja void oblicz_statystyke (const double dane[], size_t rozmiar, double &m, double &s) obliczająca estymator wartości średniej i odchylenia standardowego danych w tablicy.
- Trywialna funkcja void wypisz (FILE *wy, const double dane[], size_t n) wypisująca na podany strumień wyjściowy n liczb z tablicy dane.
- Funkcja main(), w tym porównanie parametrów rozkładu z oczekiwanymi i zwolnienie na końcu pamięci. {1,5 pkt.}
- Podział na pliki: main.c, generator.c, generator.h + Makefile.
Zadanie #8 - 4 maja 2016 r.
Napisać symulator rozpadu pierwiastków promieniotwórczych. Parametry symulacji podaje się w formacie binarnym w pliku, którego nazwę należy podać jako parametr uruchomienia programu. Atomy są rozłozone na dwuwymiarowym prostokącie. Reakcję rozpadu symulujemy metodą Monte Carlo. "Rozpadnięty" atom znika z planszy i nie bierze udziału w dalszej symulacji. Symulacja kończy się, gdy liczba atomów zmaleje 25-krotnie.Format pliku binarnego:
szerokość (16 bitów), wysokość (16 bitów), ilość_pierwiastków (8 bitów),
dla każdego pierwiastka: lambda (float), kolor (4x8 bitów formacie 0x00rrggbb).
Dane do programu:
Etapy rozwiązania (po 1 pkt.):
- Analiza parametru uruchomienia programu, otwarcie pliku w trybie binarnym, sprawdzenie błędów.
- Wczytanie rozmiarów "planszy" i otwarcie okna.
- Wczytanie liczby pierwiastków, utworzenie tablicy do przechowywania ich kolorów i wypełnienie jej (użyj funkcji int makecol (int r, int g, int b).
- Wyświetlenie na standardowe wyście błędów liczby atomów i ich czasów rozpadu (w formacie tekstowym).
- Struktura struct atom zawierająca jego połozenie na planszy (x, y), czas połowicznego rozpadu, kolor oraz stan (rozpadnięty / nierozpadnięty).
- Funkcja struct atom *generuj_atomy (size_t szerokosc, size_t wysokosc, size_t n, const int kolory[], const float lambdy[]) zwracająca wskaźnik na tablicę na stercie zawierającą rozlosowane atomy na całej planszy; n oznacza liczbę pierwiastków; każdy pierwiastek losowany jest z jednakowym prawdopodobieństwem). {2 pkt.}
- Narysowanie atomów na planszy.
- Symulacja rozpadu (może być w funkcji main()); atom ulegający rozpadowi znika (staje się czarny) z planszy; na standardowe wyjście zapisujemy dane w formacie: czas symulacji; liczba atomów. {2 pkt.}
Zadanie #7 - 27 kwietnia 2016 r.
Napisać program generujący raport statystyczny dla transportu modnych francuskich kapeluszy (w modnych francuskich pudłach) z Centrum Mody Francuskiej, który powinien zawierać sumaryczną liczbę pudeł, średnią wysokość pudła, sumaryczną objętość oraz masę. W związku ze wzrostem popytu na modne francuskie kapelusze w Polsce, Centrum rozpoczęlo dystrybucję kapeluszy w kształcie walców (W), prostopadłościanów (P) oraz graniastosłupów o podstawie trójkątnej (T).
Specyfikacja zestawienia transportu jest teraz następująca:
W masa wysokość promień
P masa wysokość szerokość głębokość
T masa wysokość długość_krawędzi_podstawy
Pudła powinny być reprezentowane w programie jako obiekty odpowiednich struktur.
Etapy rozwiązania (po 1 pkt.):
- Struktury KapeluszW, KapeluszP oraz KapeluszT dla poszczególnych kształtów pudeł.
- Unia KapeluszU zawierająca trzy ww. typy pudeł oraz struktura Kapelusz zawierajaca unię oraz obiekt typu wyliczeniowego określający kształt przechowywanego kapelusza.
- Funkcja Kapelusz *wczytaj_dane (FILE *we, size_t &rozmiar) z dynamiczną realokacją pamięci (2 pkt.).
- Definicja struktury StatParam przechowującej obliczoną statystykę (średnią wysokość stosu wraz z odchyleniem, sumaryczną objętość oraz masę). {0,5 pkt.}
- Funkcja StatParam oblicz_statystyke (const Kapelusz *tk, size_t n) obliczająca i zwracająca wymagane informacje statystyczne. {2 pkt.}
- Instrukcje funkcji main() wywołujące sensownie powyższe funkcje.
- Wyświetlenie wyników analizy na ekranie.
- Podział kodu na pliki źródłowe: main.cpp, kapelusz.cpp, kapelusz.hpp oraz Makefile.
Zadanie #6 (9 pkt.) - 20 kwietnia 2016 r.
Wykonać symulację jednowymiarowego układu złożonego z dwóch mas punktowych m1 = 10 kg i m2 = 2 kg połączonych sprężyną o stałej sprężystości k = 200 N/m i długości l = 1 m. W chwili początkowej masie m1 nadano prędkość υ0 = 0,5 m/s. Zaimplementować struktury MasaPunktowa oraz Sprezyna zawierające fizyczne parametry reprezentowanych obiektów. Wyniki zapisywać do pliku / standardowego wyjścia (wybór) w czterech kolumnach: czas, x1, x2, Ecałkowita.
Etapy rozwiązania (po 1 pkt.):
- Podział poniższego kodu na trzy pliki źródłowe: main.c, obiekty.h (definicja struktur) i obiekty.c (funkcje użytkownika) oraz Makefile. {1,5 pkt.}
- Struktury MasaPunktowa oraz Sprezyna. Sprezyna powinna zawierać wskaźniki na masy punktowe stanowiące początek i koniec sprężyny.
- Funkcja double silaSprezyny (const Sprezyna &s) zwracająca siłę pochodzącą od sprężyny s oraz funkcje double energia (const Sprezyna &s) oraz double energia (const MasaPunktowa &m) zwracające energię mechaniczna zgromadzona w obiektach. {2,5 pkt.}
- Utworzenie i zainicjowanie obiektów w funkcji main().
- Symulacja metodą Eulera. {2 pkt.}
- Wypisywanie wyników na standardowe wyjście.
Zadanie #5 (8 pkt.) - 13 kwietnia 2016 r.
Zajęcia kontrolne! :)
Napisać program, który wczyta ze standardowego wejścia zestaw liczb i obliczy dla niego wartość średnią i odchylenia standardowe, które to wartości wyświetli na ekran.
Pierwsza wartość w pliku z danymi oznacza liczbę liczb zawartych w pliku.
Należy użyć funkcji wymienionych poniżej. Inne rozwiązania nie będą tym razem tolerowane.
- Funkcja double *wczytaj_dane (FILE *strumien, size_t *n) wczytująca dane z podanego strumienia do tworzonej przez nią tablicy dynamicznej; ustawia w n rozmiar wczytanej tablicy. {1,5 pkt.}
- Funkcja void analiza_statystyczna (const double dane[], size_t n, double *m, double s) obliczająca dla tablicy z danymi o rozmiarze n wartość średnią i odchylenie standardowe, które przypisuje poprzez wskaźniki m i s. {3 pkt.}
- Prawidłowe wywołanie ww. funkcji w funkcji main() wraz z potrzebnymi definicjami zmiennych.
- Wyświetlenie na ekran obliczonych estymatorów. {0,5 pkt}
- Funkcja bool test_sigma (double liczba, double m, double s, double x) zwracająca true, jeżeli liczba znajduje się w przedziale [m-sx; m+sx]; w przeciwnym wypadku false. {0,5 pkt.}
- Obliczenie i wyświetlenie na ekran, ile liczb (wartość bezwzględna oraz w procentach) nie mieści się w przedziale 6 sigma.
- Usunięcie w odpowiednim miejscu tablicy na stercie. {0,5 pkt}
Zadanie #4 - 6 kwietnia 2016 r.
Napisać program, który wczyta poprzez standardowe wejście nazwiska i imiona studentów w grupie (pierwsza linijka ma zawierać liczebność grupy), posortuje je alfabetycznie (wykorzystując algorytm sortowania bąbelkowego) i wyświetli na standardowe wyjście, dodając obok nazwiska nazwę pluszowego zwierzątka, które wygrywa dana osoba. Nagrodą jest zwierzątko, któremu odpowiada spełnienie pierwszego z poniższych warunków:
- Eskulapa - nazwisko zawiera co najmniej 2 litery e
- Kokoszka - nazwisko zaczyna się od sylaby ko
- Orzeł - nazwisko zawiera literę o
- Lew - nazwisko kończy się na ski/ska
- Króliczek - nagroda pocieszenia
Etapy rozwiązania (po 1 pkt.):
- Wczytanie liczebności grupy oraz utworzenie dwóch tablic wskaźników char*.
- Wczytywanie w pętli nazwisk i imion do buforów, tworzenie dynamicznych tablic dostosowanych do przechowania tychże oraz skopiowanie tam nazwiska i imiona oraz "podczepienie" pod tablice z pkt. 1. {1,5 pkt.}
- Wysortowanie danych bąbelkowo {2 pkt.}.
- Sprawdzenie warunków 1-2.
- Sprawdzenie warunków 3-4.
- Instrukcje if sprawdzające powyższe tudzież przyznające nagrodę pocieszenia. {0,5}
- Wyświetlenie pełnych rekordów na standardowe wyjście.
Zadanie #3 - 30 marca 2016 r.
Napisać program weryfikujący numer konta bankowego podanego w formacie NRB. Program powinien poprosić użytkownika o podanie numeru i wczytać go, ignorując białe znaki (np. spacje, myślniki itd.) oraz wyświetlać komunikat Numer rachunku poprawny/niepoprawny oraz wyświetlić nazwę banku prowadzącego rachunek. Do weryfikacji numeru użyć tzw. metody wielomianowej. Zoptymalizować typy używanych tablic pod kątem oszczędności pamięci.
Etapy rozwiązania (po 1 pkt.):
- Stworzenie tablicy const short [] zawierającej współczynniki wielomianu; wyświetlenie monitu o podanie NRB
- Wczytanie NRB do tablicy liczb (ignorując białe znaki).
- Obliczenie liczby kontrolnej. {2 pkt.}
- Sprawdzenie wartości liczby kontrolnej i na tej podstawie wyświetlenie komunikatu o (nie)poprawności numeru.
- Wczytanie pliku z identyfikatorami banków, wyszukanie pasującego identyfikatora i wyświetlenie nazwy banku. {1,5 pkt.}
- Optymalizacja operacji na tablicach (w dwóch dowolnie wybranych miejscach) poprzez zastosowanie "przesuwanych" wskaźników. {1,5 pkt.}
Przykładowe numery kont do weryfikacji działania programu można znaleźć na stronie ZUS.
Zadanie #2 - 16 marca 2016 r.
Napisać program obliczający wartości funkcji sinus, cosinus oraz ln (1+x) ze wzoru Taylora. Użytkownik dokonuje wyboru funkcji z menu, następnie podaje wartość argumentu oraz minimalną dokładność wyniku. Program trwa do czasu wybrania opcji "wyjście" w menu.
Etapy rozwiązania (po 1 pkt.):
- Pętla while oraz wyświetlenie opcji menu (w tym 0 - wyjście).
- Analiza wyboru z menu instrukcją switch. Uwgzlędnienie błędnych opcji oraz wyjścia.
- Case 1: pętla do-while obliczająca i sumująca kolejne wyrazy szeregu Taylora dla funkcji sinus. {2 pkt.}
- Case 2 i 3: pętle do-while obliczające i sumujące kolejne wyrazy szeregu Taylora dla funkcji cosinus i ln (1+x). {2 pkt.}
- Schludne wyświetlanie wyników na ekran.
Zadanie #1 - 9 marca 2016 r.
Napisać program, który zapyta użytkownika o nazwę pliku z danymi studentów, wczyta go, a następnie wyświetli na standardowe wyjście w formie eleganckiej tabelki zawierającej kolejno pola: lp., nr albumu, nazwisko, imię, grupa, wiek, uwagi. Wymagane są pionowe linie oddzielające poszczególne kolumny oraz poziome linie wokół nagłówka i na końcu tabeli. W polu uwagi mogą pojawić się dwie informacje: "wymiana zagraniczna", gdy nr albumu jest mniejszy niż 100000; albo "ZUS", gdy wiek studenta przekroczy 26 lat.
Etapy rozwiązania (po 1 pkt.):
- Zapytanie o nazwę pliku wejściowego i pobranie jego nazwy.
- Otwarcie pliku oraz sprawdzenie, czy operacja wykonała się poprawnie. Zamknięcie pliku (na końcu programu).
- Wyświetlenie nagłówka tabeli wraz z poziomymi liniami.
- Definicje zmiennych pomocniczych i pętla czytająca rekordy z plików do zmiennych pomocniczych.
- Licznik nr. porządkowego. {0,5 pkt.}
- Sprawdzenie warunków i ewentualny wybór odpowiedniej uwagi.
- Instrukcja printf wyświetlająca kolejne rekordy na ekran (wewnątrz pętli). {1,5 pkt.}
Zadanie #0 - 2 marca 2016 r.
Zajęcia wprowadzające.
- Korzystając z informacji zawartych na TEJ stronie, skonfiguruj w programie IceDove / Thunderbird swoją skrzynkę pocztową w domenie student.fizyka.pw.edu.pl oraz pw.edu.pl.
- Skonfiguruj swoje ulubione środowisko programistyczne, tj. Geany.
- Napisz swój pierwszy fantastyczny program, np. wyświetlający rozmiary zmiennych różnych typów na ekranie.
- Uśmiechnij się!