Zadania maturalne informatyka

Każdy przygotowywujący się do matury z informatyki spotyka się z różnymi zadaniami w języku c++. Obecnie coraz więcej szkół zaczyna korzystać z Python'a, a ja chcę w tej serii pokazać jak rozwiązywać przykładowe zadania.

Zadanie 61 - Ciągi arytmetyczne

Zadanie 61 z arkusza specjalnie przygotowywanych dla maturzystów zadań i rowiązań kładzie nacisk na iteracyjne podejście do dużej bazy liczb.

Arkusz z zadaniami (Matura Zbiór zadań Informatyka) możesz znaleźć pod tym linkiem

Pliki do zadania z kolei znajdują się tutaj

Nasze zadanie będę rozwiązywać w języku Python

Kod źródłowy do zadania wraz z plikami znajdziesz tutaj

Wczytywanie danych

Treść polecenia brzmi: Ciąg liczb całkowitych nazywamy ciągiem arytmetycznym, jeśli różnica między każdymi dwoma kolejnymi jego wyrazami jest identyczna. Ciągiem arytmetycznym jest na przykład ciąg (1, 3, 5, 7, 9). Jest to ciąg o różnicy 2, ponieważ każdy wyraz tego ciągu, poza pierwszym, różni się od poprzedniego wyrazu o 2. Ciąg (17, 22, 27, 32, 37) jest ciągiem arytmetycznym o różnicy 5. W tym zadaniu rozpatrujemy tylko takie ciągi arytmetyczne, które mają dodatnią różnicę oraz co najmniej pięć wyrazów.

Informacji jest dużo, ale dla nas najważniejsze jest to, że doczynienia mamy z ciągami artmetycznymi o stałej różnicy.

Ważna jest także informacja o liczbie poprzedzającej ciąg. Można założyć, iż jest ona pomocna dla języka c++, gdzie wymagane jest zadeklarowanie wielkości tablicy.

def loadCleanData(fileName):
  with open(fileName) as data:
    content = data.readlines()
    content = [x.strip() for x in content]
    #dane sa wciaz typu str
    values = [y.split(' ') for y in content[1::2]]
    
    index = 0
    for table in values:
      #konwersja ze str na int
      values[index] = [int(n) for n in table]
      index += 1

  #zwraca [ [1,2,3], [17,22,27] ]
  return(values)

Po części wczytywanie danych zostało omówione w pierwszym zadaniu tego cyklu.

Funkcja wczytująca posiada parametr fileName, gdyż późniejsze zadanie wymaga odczytania podobnego pliku o tej samej strukturze.

W następnych linijkach dane są odczytywane i rozdzielane za pomocą funkcji split().

Na samym końcu liczby wymagają konwersji na typ int.

Ciągi artmetyczne

Podaj, ile spośród podanych w pliku ciagi.txt ciągów jest ciągami arytmetycznymi. Znajdź wśród nich ciąg o największej różnicy i oblicz jego różnicę.

def findDifference(numbers):
  return numbers[1] - numbers[0]
  
def isArthmetic(numbers):
  difference = findDifference(numbers)
  
  for idx, el in enumerate(numbers):
    if idx != len(numbers)-1:
      if numbers[idx+1] - el != difference:
        return False
  return True
					

Powyższy kod sprawdza podany ciąg liczb. Na początku wyznacza różnicę początkową. Jeśli wszystkie wyrazy rosną o podanę różnicę to zwraca True.

Ważnym elementem jest tutaj funkcja enumerate(). Pozwala ona na iterowanie po elementach oraz podawanie indeksu na raz :).

def arthProgression():
  #tablice jak [ [1,2,3], [17,22,27] ]
  tables = loadCleanData("ciagi.txt")
  arthStrings = list()
  differences = list()
  
  for numbers in tables:
    if isArthmetic(numbers):
      #jesli ciag jest artmetyczny
      arthStrings.append(numbers)#dodaj ciag
      differences.append(findDifference(numbers))#dodaj jego roznice
      
  print("Artmet. ciagow jest: " + str(len(arthStrings)))
  print("Najwieksz roznica wynosi: " + str(max(differences)))
         	    	

Na samym końcu sprawdzamy który ciąg jest artmetyczny i dodajemy go oraz jego różnicę. Ostatnim krokiem jest podanie ilości ciągów oraz największej różnicy.

Sześcian liczby

Dla każdego podanego ciągu znajdź — jeśli istnieje — największą występującą w nim liczbę, która jest pełnym sześcianem jakiejś liczby naturalnej (w pierwszym z przykładowych ciągów jest to 1 = 1^3 , w drugim — 27 = 3^3 ).

Bez użycia bibloteki math. Sprawdzanie czy liczba jest sześcianem innej liczby może wydać się nieco skomplikowane. Jednak w pythonie można skorzystać z prostego triku.

def isPerfectCube(x):
  #podnosi liczbe do potegi 1/3 (pierwiastek z 3)
  root = x ** (1. / 3)
  #zaokragla liczbe do calosci
  root = round(root)
  #rzutuje na typ Int
  root = int(root)
  
  #ponownie podnosi liczbe do potegi i sprawdza 
  #czy jest taka sama jak wejściowa
  return root ** 3 == x
         	    	

Kiedy mamy funkcję sprawdzającą czy liczba jest sześcianem możemy poszukać tych największych.

def biggestCube():
  tables = loadCleanData("ciagi.txt")
  #zadeklarowana lista pod szesciany
  cubes = list()
  #iteruje po wierszach
  for line in tables:
    cubesInLine = list()
    #iteruje po liczbach w wierszu
    for number in line:
      #sprawdza czy liczba jest szescianem
      if isPerfectCube(number):
        cubesInLine.append(number)
    #jesli lista nie jest pusta, 
    #bierze maksymalna wartosc
    if cubesInLine:
      cubes.append(max(cubesInLine))
      
  print("Największe sześciany w ciągach to: " + str(cubes))
         	    	

Kolejno wyszukujemy wszystkie sześciany w danym ciągu i umieszczamy w tablicy cubesInLine. Ze wszystkich liczb te największe dodajemy w tablicy cubes.

Błędne ciągi

Plik bledne.txt ma identyczną strukturę jak ciagi.txt, ale zawiera tylko 20 ciągów. Wiadomo jednak, że wszystkie występujące w nim ciągi są ciągami arytmetycznymi z jednym błędem: jeden z wyrazów w każdym ciągu został zastąpiony przez liczbę naturalną nienależą- cą do ciągu. Dla każdego ciągu znajdź i wypisz błędny wyraz.

def wrongElements():
  lines = loadCleanData("bledne.txt")
  #deklaracja listy dla niepasujacych elementow
  wrongNumbers = list()
  
  for line in lines:
    difference = findDifference(line)
    #zmienna logiczna wskazujaca znalezienie elementu
    done = False

    for idx, number in enumerate(line):
      #petla wykonuje sie tylko jesli:
      #zaczyna od drugiego elementu
      #oraz nie zostal znalezieny element
      if idx != 0 and not done:
        previousItem = line[idx - 1]
        
        if number - difference != previousItem:
          wrongNumbers.append(number)
          #wskazujemy znalezienie
          done = True
          
  print("Bledne wyrazy to: " + str(wrongNumbers))
					

Początkowe linie kodu odpowiadają za znalezienie różnicy. Poźniej porównujemy czy kolejne wyrazy spełniają regułę. Jeśl nie to dodajemy je do tablicy wrongNumbers oraz wskazujemy znalezienie.

Ostateczne wyniki jednak nie do końca pokrywają się z odpowiedziami.

W arkuszu możemy przeczytać, że To zadanie może sprawić kłopoty bardzo szczególnego rodzaju.

Powodem jest rozważanie przypadków, kiedy błedny jest wyraz pierwszy lub drugi.

Ja jednak nie zamierzam rozważać tych przypadków i wywołać ostatecznie nasze funkcje :).

arthProgression()
biggestCube()
wrongElements()
					

TL;DR

Skopiuj cały kod do jednego pliku w kolejności podanej w tekście. UWAGA zadanie trzecie nie spełnia wszystkich warunków!

shop
Otwórz Sklep Play

Zachęcam cię do odwiedzenia mojej strony na Google Play store i sprawdzenia wszystkich moich aplikacji.