Instrukcja:
Przed przystąpieniem do realizacji zadań upewnij się, że rozumiesz mechanizm alokacji pamięci dla tablic oraz różnicę między typami referencyjnymi a wartościowymi. Zadania wymagają korzystania z przestrzeni nazw System.Collections.Generic.

UWAGA: W kodzie C# separatorem dziesiętnym jest zawsze KROPKA (.), nie przecinek! Podczas parse'owania liczb rzeczywistych używaj formatu np. 12.5 a nie 12,5.

Spis treści

  1. Statystyki temperatury (Tablice 1D)
  2. Sortownik liczb (Listy i Sortowanie)
  3. Zarządzanie parkingiem (Tablice 2D)
  4. Dziennik ocen (Tablice nieregularne)
  5. Interaktywna lista zakupów (List<string>)
  6. Uproszczona gra w wisielca
  7. Licznik słów (Podstawy Dictionary)
  8. Algorytm wyszukiwania binarnego
  9. Sumowanie kwadratów (Pętla foreach)
  10. System rezerwacji biletów (Hybryda)
01
Statystyki temperatury (Tablice 1D)
Cel

Praktyczne zastosowanie jednowymiarowych tablic do przechowywania i analizy zbiorów danych liczbowych.

Opis

W tym zadaniu stworzysz aplikację do analizy danych meteorologicznych pobranych w ciągu jednego tygodnia. Program powinien najpierw zapytać użytkownika, ile pomiarów temperatury chce wprowadzić, a następnie utworzyć tablicę typu double o dokładnie takim rozmiarze. Wykorzystując pętlę for, wypełnij tablicę wartościami podanymi z klawiatury. Po zebraniu wszystkich danych, program musi przejrzeć tablicę, aby znaleźć temperaturę maksymalną, minimalną oraz obliczyć średnią arytmetyczną wszystkich pomiarów. Do znalezienia ekstremów możesz wykorzystać własną logikę z instrukcjami warunkowymi lub statyczne metody klasy Math. Na koniec wyświetl raport podsumowujący. Zadanie to uczy deklarowania tablic o dynamicznym rozmiarze (określanym w czasie działania programu) oraz iterowania po ich elementach w celu ekstrakcji istotnych informacji statystycznych.

Przykład kodu
// WYMAGANE NA POCZĄTKU PLIKU: using System; using System.Collections.Generic; Console.Write("Ile pomiarow? "); int n = int.Parse(Console.ReadLine()); double[] temperatury = new double[n]; for (int i = 0; i < n; i++) { Console.Write($"Podaj temperature {i+1}: "); temperatury[i] = double.Parse(Console.ReadLine()); } // Obliczanie statystyk: double max = temperatury[0]; double min = temperatury[0]; double suma = 0; foreach (double t in temperatury) { if (t > max) max = t; if (t < min) min = t; suma += t; } double srednia = suma / n; Console.WriteLine($"Maksimum: {max:F2}"); Console.WriteLine($"Minimum: {min:F2}"); Console.WriteLine($"Srednia: {srednia:F2}");
Przykład działania
Ile pomiarow? 3 Podaj temperature 1: 12.5 Podaj temperature 2: 15.0 Podaj temperature 3: 10.2 --- ANALIZA --- Maksimum: 15.00 Minimum: 10.20 Srednia: 12.57
02
Sortownik liczb (Listy i Sortowanie)
Cel

Użycie dynamicznej kolekcji List<T> do przechowywania nieokreślonej z góry liczby elementów oraz wykorzystanie metod sortujących.

Opis

W przeciwieństwie do tablic, listy w C# mogą dynamicznie zmieniać swój rozmiar w trakcie pracy programu. Twoim zadaniem jest stworzenie aplikacji, która pozwoli użytkownikowi na wprowadzanie dowolnej ilości liczb całkowitych. Proces dodawania liczb powinien trwać tak długo, aż użytkownik wpisze cyfrę '0', co zasygnalizuje koniec wprowadzania danych (sama cyfra 0 nie powinna trafić do kolekcji). Wszystkie liczby mają być przechowywane w obiekcie klasy List<int>. Po zakończeniu etapu wprowadzania, program musi wywołać wbudowaną metodę .Sort(), aby uporządkować liczby od najmniejszej do największej. Na koniec wyświetl zawartość listy w jednej linii, oddzielając liczby przecinkami. Zadanie to uczy korzystania z generycznych kolekcji, obsługi pętli o nieznanej liczbie iteracji oraz wykorzystywania gotowych algorytmów dostarczanych przez platformę .NET.

Przykład kodu
using System; using System.Collections.Generic; List<int> liczby = new List<int>(); Console.WriteLine("Podaj liczby (0 konczy):"); while (true) { int n = int.Parse(Console.ReadLine()); if (n == 0) break; liczby.Add(n); } liczby.Sort(); Console.Write("Posortowane liczby: "); Console.WriteLine(string.Join(", ", liczby));
Przykład działania
Podaj liczby (0 konczy): 8 -2 15 0 Posortowane liczby: -2, 8, 15
03
Zarządzanie parkingiem (Tablice 2D)
Cel

Zastosowanie tablic dwuwymiarowych do symulacji przestrzennych układów danych (siatki/mapy).

Opis

W tym zadaniu przygotujemy symulator małego parkingu piętrowego, który posiada 3 poziomy, a na każdym z nich znajduje się 5 miejsc postojowych. Do odwzorowania tej struktury wykorzystasz tablicę dwuwymiarową typu bool[,] o wymiarach 3x5, gdzie wartość true oznacza miejsce zajęte, a false – wolne. Napisz program, który wyświetla graficzną mapę parkingu (np. [X] dla zajętego i [ ] dla wolnego miejsca) oraz pozwala użytkownikowi "zaparkować" samochód poprzez podanie numeru piętra i numeru miejsca. Program powinien sprawdzić, czy wskazane miejsce jest wolne przed dokonaniem rezerwacji. Jeśli miejsce jest już zajęte, należy wyświetlić odpowiedni komunikat błędu. Zadanie to uczy elastycznego zarządzania danymi w macierzy oraz poprawnego operowania na dwóch wymiarach tablicy.

Przykład kodu
using System; using System.Collections.Generic; bool[,] parking = new bool[3, 5]; // Wyświetlanie mapy parkingu: for (int p = 0; p < 3; p++) { for (int m = 0; m < 5; m++) { Console.Write(parking[p, m] ? "[X]" : "[ ]"); } Console.WriteLine(); } // Rezerwacja miejsca: Console.Write("Podaj pietro (0-2): "); int pietro = int.Parse(Console.ReadLine()); Console.Write("Podaj miejsce (0-4): "); int miejsce = int.Parse(Console.ReadLine()); if (parking[pietro, miejsce]) { Console.WriteLine($"Blad: Miejsce {pietro}-{jestnie zajete}!"); } else { parking[pietro, miejsce] = true; Console.WriteLine("Zarezerwowano miejsce."); }
Przykład działania
MAPA PARKINGU: [ ] [ ] [X] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [X] [ ] [ ] [ ] [ ] Podaj pietro (0-2): 0 Podaj miejsce (0-4): 2 Blad: Miejsce 0-2 jest zajete!
04
Dziennik ocen (Tablice nieregularne)
Cel

Zrozumienie i implementacja tablic nieregularnych (jagged arrays) w sytuacjach, gdy wiersze mają różną długość.

Opis

Często zdarza się, że struktura danych nie jest idealnie prostokątna. W tym zadaniu zamodelujemy dziennik ocen dla trzech różnych grup studenckich, z których każda ma inną liczbę osób (np. grupa A: 3 osoby, grupa B: 5 osób, grupa C: 2 osoby). Do tego celu idealnie nadaje się tablica nieregularna (ang. jagged array) typu int[][]. Twoim zadaniem jest zainicjalizowanie takiej tablicy, a następnie wypełnienie jej ocenami podanymi przez użytkownika dla każdej grupy z osobna. Program powinien obliczyć i wyświetlić średnią ocen dla każdej grupy oraz średnią ogólną dla całego roku. Zwróć uwagę na składnię tablic nieregularnych, gdzie każdy "wiersz" musi zostać oddzielnie utworzony za pomocą słowa kluczowego new. Zadanie to uczy elastycznego zarządzania pamięcią oraz poprawnego operowania na strukturach typu "tablica tablic", co jest częstym wzorcem w zaawansowanym programowaniu C#.

Przykład kodu
using System; using System.Collections.Generic; // Poprawna składnia tablicy nieregularnej: int[][] dziennik = new int[3][]; dziennik = new int[3][]; // LUB prościej - od razu inicjalizacja wierszy: int[][] dziennik = new int[3][] { new int[3], // Grupa 1 - 3 osoby new int[5], // Grupa 2 - 5 osób new int[2] // Grupa 3 - 2 osoby }; // Dostęp do elementu: dziennik[1][4] = 5; // Piąta osoba w drugiej grupie // Obliczanie średniej dla grupy: double suma = 0; foreach (int ocena in dziennik[0]) { suma += ocena; } double srednia = suma / dziennik[0].Length;
Przykład działania
Wprowadzanie ocen dla Grupy 1 (3 osoby): Osoba 1: 4 Osoba 2: 5 Osoba 3: 3 Średnia Grupy 1: 4.00 ... (itd. dla pozostałych grup)
05
Interaktywna lista zakupów (List<string>)
Cel

Zastosowanie kolekcji List<string> do budowy prostego systemu zarządzania elementami dynamicznymi.

Opis

Zadanie polega na stworzeniu aplikacji konsolowej, która będzie pełniła rolę elektronicznej listy zakupów. Uczeń musi zainicjalizować listę generyczną przechowującą ciągi znaków (List<string>). Program powinien w pętli wyświetlać menu z opcjami: Dodaj produkt, Usuń produkt (według nazwy lub indeksu), Wyświetl listę oraz Wyjdź. Przy usuwaniu elementu należy zadbać o sprawdzenie, czy dany produkt w ogóle znajduje się na liście, aby uniknąć błędów w trakcie działania aplikacji. Dodatkowo, po każdej modyfikacji, program powinien informować użytkownika o aktualnej liczbie przedmiotów na liście przy użyciu właściwości .Count. Zadanie to uczy podstawowych operacji na kolekcjach dynamicznych (CRUD – Create, Read, Update, Delete) oraz interakcji z użytkownikiem poprzez tekstowe menu sterujące przepływem programu.

Przykład kodu
using System; using System.Collections.Generic; List<string> lista = new List<string>(); lista.Add("Chleb"); lista.Add("Mleko"); if (lista.Contains("Mleko")) { lista.Remove("Mleko"); } Console.WriteLine($"Na liscie jest: {lista.Count} elementow."); // Usuwanie po indeksie: int indeks = 0; if (indeks >= 0 && indeks < lista.Count) { lista.RemoveAt(indeks); }
Przykład działania
1. Dodaj | 2. Usun | 3. Pokaz | 4. Koniec Wybór: 1 Produkt: Masło Dodano produkt. Aktualnie: 3 elementy. Wybór: 3 Lista zakupów: 1. Chleb, 2. Jajka, 3. Masło
06
Uproszczona gra w wisielca
Cel

Praca na tablicach znaków (char[]) oraz manipulacja pojedynczymi elementami tekstowymi w kontekście logicznym.

Opis

W tym zadaniu stworzymy bazę pod popularną grę w odgadywanie słów. Twoim zadaniem jest zainicjalizowanie stałego słowa do odgadnięcia (np. "PROGRAMOWANIE") oraz utworzenie tablicy znaków o tej samej długości, wypełnionej na początku znakami podkreślenia '_'. Gracz w pętli podaje pojedynczą literę. Program musi sprawdzić, czy litera ta występuje w słowie-zagadce, przechodząc przez tablicę znaków. Jeśli tak, należy odsłonić literę w odpowiednich miejscach tablicy maskującej. Gra toczy się do momentu, w którym wszystkie litery zostaną odgadnięte (brak znaków podkreślenia w tablicy). Do zamiany słowa na tablicę znaków wykorzystaj metodę .ToCharArray(). Zadanie to uczy operowania na typach char, porównywania znaków oraz synchronizacji dwóch zbiorów danych (słowa celowego i aktualnego stanu gry widocznego dla użytkownika).

Przykład kodu
using System; using System.Collections.Generic; string slowo = "KOD"; char[] maska = new char[slowo.Length]; // Inicjalizacja maski podkreśleniami: for (int i = 0; i < maska.Length; i++) maska[i] = '_'; // Odgadnięcie litery - POPRAWNY SPOSÓB: string input = Console.ReadLine(); if (string.IsNullOrEmpty(input)) continue; char litera = char.ToUpper(input[0]); for (int i = 0; i < slowo.Length; i++) { if (char.ToUpper(slowo[i]) == litera) maska[i] = slowo[i]; } Console.WriteLine(new string(maska));
Przykład działania
Slowo do odgadniecia: _ _ _ Podaj litere: A Brawo! Slowo: _ A _ Podaj litere: K Niestety, nie ma takiej litery.
07
Licznik słów (Podstawy Dictionary)
Cel

Wprowadzenie do asocjacyjnych struktur danych typu Słownik (Dictionary) do zliczania unikalnych wystąpień kluczy.

Opis

Czasami musimy wiedzieć nie tylko, jakie dane posiadamy, ale ile razy każda z nich występuje. W tym zadaniu napiszemy program, który przeanalizuje krótkie zdanie wpisane przez użytkownika. Program powinien podzielić zdanie na pojedyncze słowa (metoda .Split()), a następnie zliczyć, ile razy każde słowo się powtarza. Do przechowania tych wyników użyjesz słownika Dictionary<string, int>, gdzie kluczem będzie słowo, a wartością liczba jego wystąpień. Przy każdym słowie sprawdź, czy znajduje się już w słowniku (metoda .ContainsKey()). Jeśli tak – zwiększ licznik, jeśli nie – dodaj nową parę z wartością 1. Na koniec wyświetl raport z częstotliwością słów. To zadanie uczy korzystania z niezwykle wydajnych struktur mapujących oraz podstaw czyszczenia i segmentacji danych tekstowych.

Przykład kodu
using System; using System.Collections.Generic; string zdanie = Console.ReadLine(); Dictionary<string, int> licznik = new Dictionary<string, int>(); string[] slowa = zdanie.Split(' ', StringSplitOptions.RemoveEmptyEntries); foreach (string s in slowa) { if (licznik.ContainsKey(s)) licznik[s]++; else licznik.Add(s, 1); } // Wyświetlanie wyników: foreach (var para in licznik) { Console.WriteLine($"{para.Key}: {para.Value} razy"); }
Przykład działania
Wpisz zdanie: ala ma kota ala ma psa FREKWENCJA SLOW: ala: 2 razy ma: 2 razy kota: 1 raz psa: 1 raz
08
Algorytm wyszukiwania binarnego
Cel

Implementacja wydajnego algorytmu wyszukiwania w posortowanym zbiorze danych (logarytmiczna złożoność obliczeniowa).

Opis

Wyszukiwanie liniowe (element po elemencie) jest nieefektywne przy dużych zbiorach danych. W tym zadaniu nauczysz się implementować wyszukiwanie binarne (Binary Search) na posortowanej tablicy liczb całkowitych. Algorytm ten polega na ciągłym dzieleniu zakresu poszukiwań na pół i porównywaniu wartości środkowej z szukaną liczbą. Twoim zadaniem jest stworzenie metody, która przyjmuje posortowaną tablicę oraz szukaną wartość, a następnie zwraca indeks tego elementu lub informację o jego braku. W opisie zadania należy podkreślić kluczowy warunek: wyszukiwanie binarne zadziała poprawnie tylko wtedy, gdy dane są już wcześniej uporządkowane. Zadanie to nie tylko uczy konkretnego algorytmu, ale przede wszystkim pokazuje, jak dobór odpowiedniej metody przetwarzania danych wpływa na wydajność i szybkość działania aplikacji. Jest to klasyczny przykład optymalizacji, który każdy programista powinien znać.

Przykład kodu
using System; using System.Collections.Generic; int BinarySearch(int[] tablica, int szukana) { int lewy = 0; int prawy = tablica.Length - 1; while (lewy <= prawy) { int srodek = lewy + (prawy - lewy) / 2; if (tablica[srodek] == szukana) return srodek; if (tablica[srodek] < szukana) lewy = srodek + 1; else prawy = srodek - 1; } return -1; // Nie znaleziono } // Użycie: int[] dane = { 10, 20, 30, 40, 50, 60, 70, 80 }; int wynik = BinarySearch(dane, 60); Console.WriteLine($"Indeks: {wynik}");
Przykład działania
Tablica: [10, 20, 30, 40, 50, 60, 70, 80] Podaj liczbe do znalezienia: 60 Wynik: Liczba 60 znajduje sie pod indeksem 5. Liczba operacji: 3 (podzialy binarne)
09
Sumowanie kwadratów (Pętla foreach)
Cel

Opanowanie składni pętli foreach do eleganckiego i bezpiecznego procesowania elementów kolekcji.

Opis

Podczas gdy pętla for opiera się na indeksach, pętla foreach skupia się bezpośrednio na elementach kolekcji, co czyni kod czytelniejszym i mniej podatnym na błędy typu "off-by-one". W tym zadaniu Twoim celem jest stworzenie listy liczb (List<int>), a następnie obliczenie sumy kwadratów wszystkich jej elementów przy użyciu pętli foreach. Program powinien najpierw wygenerować lub pobrać od użytkownika zestaw liczb, a w kolejnym kroku przejść przez nie, podnosząc każdą do kwadratu i dodając do zmiennej sumującej. Zadanie to ma na celu pokazanie różnicy w czytelności kodu między tradycyjną pętlą indeksowaną a nowoczesnym podejściem iteracyjnym. Pętla foreach jest standardem w codziennej pracy programisty C#, szczególnie przy operowaniu na złożonych obiektach i kolekcjach generycznych, gdzie bezpo��redni dostęp do elementu jest ważniejszy niż znajomość jego pozycji.

Przykład kodu
using System; using System.Collections.Generic; List<int> liczby = new List<int> { 1, 2, 3, 4, 5 }; long sumaKwadratow = 0; foreach (int x in liczby) { long kwadrat = (long)x * x; sumaKwadratow += kwadrat; Console.WriteLine($"{x}^2 = {kwadrat}"); } Console.WriteLine($"Suma kwadratow wynosi: {sumaKwadratow}");
Przykład działania
Zawartosc listy: [2, 3, 5] Obliczanie sekwencyjne kwadratow... 2^2 = 4 3^2 = 9 5^2 = 25 Suma koncowa: 38
10
System rezerwacji biletów (Hybryda)
Cel

Integracja różnych struktur danych (tablic wielowymiarowych i list) w jednej, funkcjonalnej aplikacji biznesowej.

Opis

Ostatnie zadanie wymaga połączenia wiedzy o tablicach i kolekcjach w celu stworzenia miniaturowego systemu rezerwacji biletów kinowych. Twoim zadaniem jest zamodelowanie układu sali kinowej o wymiarach 5x10 przy użyciu tablicy znaków char[,], gdzie '.' oznacza wolny fotel, a 'R' zarezerwowany. Dodatkowo, program musi prowadzić historię wszystkich dokonanych rezerwacji w formie listy ciągów znaków (List<string>), przechowując wpisy takie jak "Rząd 2, Miejsce 5 zarezerwowane o 14:30". Program powinien oferować menu pozwalające na podgląd sali, dokonanie rezerwacji oraz wyświetlenie dziennika zdarzeń (logów). Zadanie to symuluje realne problemy programistyczne, gdzie dane wizualne/strukturalne (mapa sali) są oddzielone od danych historycznych/zdarzeniowych (lista logów). Jest to doskonałe ćwiczenie z zakresu projektowania prostych systemów informatycznych oraz zarządzania stanem aplikacji poprzez współpracujące ze sobą kolekcje.

Przykład kodu
using System; using System.Collections.Generic; char[,] sala = new char[5, 10]; List<string> historia = new List<string>(); // Inicjalizacja sali - wszystkie miejsca wolne: for (int r = 0; r < 5; r++) for (int m = 0; m < 10; m++) sala[r, m] = '.'; // Rezerwacja miejsca: int rzad = 2; // (z inputu) int miejsce = 5; // (z inputu) if (sala[rzad, miejsce] == '.') { sala[rzad, miejsce] = 'R'; historia.Add($"Rzad {rzad}, Miejsce { miejsce} zarezerwowane."); Console.WriteLine("Rezerwacja udana!"); } else { Console.WriteLine("Miejsce jest zajete!"); } // Wyświetlanie logów: foreach (string wpis in historia) { Console.WriteLine(wpis); }
Przykład działania
--- SYSTEM KINOWY --- 1. Pokaz sale | 2. Rezerwuj | 3. Pokaz logi Wybór: 2 Podaj rzad: 2 | Podaj miejsce: 5 Rezerwacja udana! Wybór: 3 DZIENNIK ZDARZEN: - Rzad 2, Miejsce 5 zarezerwowane o 21:55