Zadanie projektowe
Napisać fantastyczny program, który będzie obliczać dyskretną transformatę Fouriera danych wejściowych i wyświetlać ją na ekranie (w trybie graficznym biblioteki Allegro 4) oraz zapisywać do pliku.
Argumenty uruchomienia programu są następujące:
./fourier (-b | -t) <nazwa_pliku_we> -o <nazwa_pliku_wy> [-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.
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:
- {1 pkt.} Funkcja sygnal obetnij_dane (const sygnal &dane, size_t n) - wykonuje kopię n pierwszych elementów swojego argumentu i zwraca je w postaci nowej struktury (pamiętaj o przydzieleniu nowej pamięci!). [sygnal.cpp]
- {0,5 pkt.} Struktura wymiary zawierająca 4 liczby oznaczające położenie lewego górnego rogu (x0, y0) oraz szerokość i wysokość. [grafika.h]
- {2,5 pkt.} Funkcja void rysuj_okna (BITMAP *ekran, const wymiary &w1, const wymiary &w2, int kolor_tla, int kolor_wykresow, int kolor_ramek) - czyści ekran na podany kolor tła (clear_to_color()), rysuje dwie ramki w podanym kolorze (rect()) o podanych rozmiarach oraz wypełnie je kolorem wykresów (rectfill()). [grafika.cpp]
- {4 pkt.} Funkcja void rysuj_wykres (BITMAP *ekran, const wymiary &wykres, const sygnal &dane, int kolor) - wykreśla dane wewnątrz podanej ramki na określony kolor (line()). [grafika.cpp]
- {2 pkt.} Wywołanie w funkcji main() napisanych dziś funkcji rysujących, które w efekcie dadzą piękne okno z dwoma wykresami. Transformata Fouriera powinna być wyświetlana dla 1/10 rozmiaru danych wejściowych. [main.cpp]
Część II - 1 czerwca 2016 r.
Etapy rozwiązania:
- {1 pkt.} Funkcja double max (const sygnal &dane) zwracająca wartość największą sygnału. [sygnal.cpp]
- {0,5 pkt.} Funkcja double min (const sygnal &dane) zwracająca wartość najmniejszą sygnału. [sygnal.cpp]
- {4 pkt.} Funkcja sygnal fourier (const sygnal &dane) zwracająca dyskretną transformatę Fouriera (moduł) danych. [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 tranformatę Fouriera. [main.cpp]
- {1 pkt.} Po dokonanych obliczeniach, jeśli jest włączony przełącznik trybu graficznego, wyświetlenie pustego okna o rozmiarach 800x600 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:
- {1 pkt.} Typ wyliczeniowy rodzaj_pliku (binerny / tekstowy) oraz struktura opcje_programu zawierająca nazwę pliku wejściowego, typ pliku wejściowego, 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źnik na tablicę typu double oraz rozmiar tejż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. [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ć program wsadowy, który obliczy (na żądanie) wartość średnią (a), odchylenie standardowe (s), element największy (M), najmniejszy (m) oraz medianę (d) zbioru liczb podanego w pliku. Przebieg programu jest sterowany z linii komend, przy czym wywołanie następuje wg schematu:
./program09 (-f | -d | -t) nazwa_pliku opcje_programu
gdzie przełączniki -f oraz -d oznaczają pliki binarne w pojedynczej (float) lub podwójnej (double) precyzji, zaś przełącznik -t oznacza plik tekstowy. Na opcje programu składają się literki oznaczające poszczególne funkcjonalności (patrz wyżej).
Program winien się składać z trzech plików źródłowych: main.cpp, io.cpp, analiza.cpp, stosownych plików nagłówkowych oraz Makefile.
Etapy rozwiązania (po 1 pkt.):
- Typ wyliczeniowy rodzaj_pliku oraz struktura opcje_programu zawierająca nazwę pliku, typ pliku oraz typy logiczne (bool) odpowiadające poszczególnym funkcjonalnościom. [io.h]
- Funkcja opcje_programu analizuj_opcje_programu (int argc, char *arg[]) analizująca argumenty uruchomieniowe programu i zwracająca wypełniony obiekt struktury. [io.cpp]
- Funkcja double *wczytaj_dane (const opcje_programu &op, size_t &rozmiar) wczytująca i wracająca dane z pliku oraz przekazująca przez referencję rozmiar wczytanych danych. [io.cpp] {1,5 pkt.}
- Funkcja double srednia (const double dane[], size_t rozmiar) obliczająca wartość średnią danych w tablicy. [analiza.cpp]
- Funkcja double sigma (const double dane[], size_t rozmiar, double m) obliczająca odchylenie standardowe od wartości średniej m danych w tablicy. [analiza.cpp]
- Funkcja double max (const double dane[], size_t rozmiar) obliczająca wartość maksymalną. [analiza.cpp] {0,5 pkt.}
- Funkcja double min (const double dane[], size_t rozmiar) obliczająca wartość minimalną. [analiza.cpp] {0,5 pkt.}
- Funkcja void sortowanie (double dane[], size_t rozmiar) sortująca tablicę danych. [analiza.cpp]
- Funkcja double mediana (const double dane[], size_t rozmiar) zwracająca medianę wartości z tablicy. [analiza.pp] {0,5 pkt.}
- Sensowne wywołanie instrukcji w funkcji main(). [main.cpp]
- Podział kodu na pliki źródłowe, nagłówkowe oraz Makefile.
Pliki binarne do testowania:
Zadanie #8 - 4 maja 2016 r.
Napisać program wyświetlający w okienku obrazek zapisany w 16-bitowym formacie TPWGF16 (Tomasz Pietrzak's Weird Graphic Format). Program napisać w oparciu o dostarczony szablon, zawierający m.in. funkcje biblioteki graficznej Allegro. Po wyświetleniu obrazu program czeka na wciśnięcie dowolnego klawisza (funkcja readkey()). Wykorzystać typy o rozmiarach niezależnych od platformy (plik nagłówkowy stdint.h).
Format (binarny) plików TPWGF jest następujący: szerokość obrazu (16 bitów); wysokość (16 bitów); kolor RGB piksela 0,0 (16 bitów); kolor RGB piksela 1,0 (16 bitów); ... Kolor zakodowany jest wg specyfikacji bitowej: 0bbbbbgggggrrrrr.
Etapy rozwiązania (po 1 pkt.):
- Pobranie nazwy pliku z parametru uruchomieniowego programu (+ sprawdzenie poprawności).
- Otwarcie + zamknięcie pliku (na końcu) + sprawdzenie poprawności uchwytu.
- Wczytanie z pliku szerokości i wysokości obrazu.
- Otwarcie okna trybu graficznego; nazwa pliku w tytule okna.
- Wczytywanie kolorów kolejnych pikseli (binarnie, 16 bitów) i konwertowanie ich na trzy składowe RGB w zakresie 0-255. {2 pkt.}
- Rysowanie pikseli na ekranie {3 pkt.}.
- Rozszerzyć program, aby wyświetlał kolejno pliki podane na liście parametrów.
Materiały do pobrania:
Zadanie #7 - 27 kwietnia 2016 r.
Napisać program generujący raport statystyczny dla transportu mięsa (w postaci stosów) z Centrum Zaopatrzenia Budek z Kebabami, który powinien zawierać sumaryczną liczbę stosów, średnią wysokość stosu, sumaryczną objętość oraz masę. W związku ze wzrostem popytu na kebaby w Polsce, Centrum Zaopatrzenia Budek z Kebabami rozpoczęlo dystrybucję stosów mięsa 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
Stosy powinny być reprezentowane w programie jako obiekty odpowiednich struktur.
Etapy rozwiązania (po 1 pkt.):
- Struktury KebabW, KebabP oraz KebabT dla poszczególnych kształtów stosów.
- Unia KebabU zawierająca trzy ww. typy kebabów oraz struktura Kebab zawierajaca unię oraz obiekt typu wyliczeniowego określający kształt przechowywanego kebaba.
- Funkcja Kebab *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 Kebab *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, kebab.cpp, kebab.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 całkowitych, posortuje je bąbelkowo i wypisze je w takim samym formacie na standardowe wyjście.
Należy użyć funkcji wymienionych poniżej. Inne rozwiązania nie będą tym razem tolerowane.
- Funkcja int *wczytaj_dane (FILE *strumien, size_t *n) wczytująca dane z podanego strumienia do tworzonej przez nią tablicy dynamicznej; rozmiar tablicy należy powiększać o 1 (realloc) przy okażdym wczytaniu liczby, aby robić miejsce na nową daną; na koniec ustawia w n rozmiar wczytanej tablicy. {3 pkt.}
- Funkcja void zapisz_dane (FILE *strumien, const int dane[], size_t n) zapisujące tablicę z danymi o rozmiarze n do wskazanego strumienia.
- Funkcja void sortuj_babelkowo (int dane[], size_t n) sortująca bąbelkowo podaną tablicę z danymi o rozmiarze n. {2,5 pkt.}
- Prawidłowe wywołanie ww. funkcji w funkcji main() wraz z potrzebnymi definicjami zmiennych.
- 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.
Obliczyć, jaka część (procent) energii emitowanej przez ciało doskonale czarne o podanej przez użytkownika temperaturze zawiera się w zakresie fal widzialnych (400-700 nm).
Powszechnie wiadomo, że radiancja spektralna na jednostkę długości fali ciała doskonale czarnego wyraża się prawem Plancka. Wynik, wyjątkwo, powinien być wyświetlany na standardowe wyjście błędów (stderr). Natomiast na standardowe wyjście program winien wypisywać w dwóch kolumnach długość fali (z krokiem co ok. 1 nm) i odpowiadającą jej radiancję.
Przydatne stałe fizyczne:
const long double hc = 1.23984193e-6; // eV*m
const long double k_B = 8.6173324e-5; // eV/K
Etapy rozwiązania (po 1 pkt.):
- Nagłowki, blok funkcji main() i definicje stałych.
- Zapytanie o temperaturę ciała (w kelwinach) i zareagowanie, gdy temperatura będzie niedodatnia.
- Nagłowek petli for iterujący po długości fali z zadanym krokiem całkowania.
- Obliczenie przyczynku "mocy" promieniowania w danej iteracji.
- Wyświetlenie na standardowe wyjście długości (jesli jest większa o 1 nm od poprzednio wyświetlonej wartości) i odpowiadającej jej mocy promieniowania. {1,5 pkt.}
- Dodanie powyższego do mocy łącznej i ewentualnie mocy "widzialnej".
- Wyświetlenie wyniku (sprawności) w procentach. {0.5 pkt.} .
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ę!