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 60 - Dzielniki

Zadanie 60 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

Tyle słowem wstępu. Zobaczmy jak wygląda polecenie. W pliku liczby.txt danych jest 200 różnych liczb całkowitych z przedziału [2, 1 000 000], każda w osobnym wierszu pliku. Napisz program (lub kilka programów), który poda odpowiedzi do poniższych zadań

Po przeczytaniu tego polecenia możemy zacząć pisać nasz kod. Pierwsze co trzeba zrobić to wczytać dane z pliku.

#funkcja za kazdym razem zwracajaca liste z liczbami
def readCleanData():
  numbers = list()
  
  with open("liczby.txt") as data:
    #odczytaj linie
    numbers = data.readlines()
    #usuwa znaki pokroju '\n' oraz biale spacje
    numbers = [i.strip() for i in numbers]
    #rzutuje kazdy element z objektu string na obiekt int
    numbers = [int(x) for x in numbers]

  return numbers

W powyższym kodzie najpierw deklarujemy nowa listę. Następnie za pomocą with otwieramy plik liczby.txt.

Wczytane dane jednak nie są w żaden sposób sformatowane, stąd trzeba odpowiednio dostosować liczby do naszego kodu.

Metodą readlines() odczytuję linie z objektu. W innym przypadku wypisanie samego obiektu data daje taki rezultat:

 io.TextIOWrapper name='liczby.txt' mode='r' encoding='UTF-8' 

Kiedy mamy już zczytaną linijkę po linijce możemy metodą strip() wyrzucić śmieci takie jak spację lub znaki końca lini '\n'. Przedostatnia linijka to już proste rzutowanie na objekt liczbowy. Musimy o tym pamiętać, gdyż liczby są wczytywane są z pliku txt. Warto to zrobić tutaj i zawsze pracować na obiektach typu Int.

Filtrowanie danych

Policz, ile jest w pliku wejściowym liczb mniejszych niż 1000, oraz podaj dwie takie liczby, które pojawiają się w pliku jako ostatnie (możesz założyć, że będą co najmniej dwie).

Pierwszy podpunkt typowo na rozgrzewkę. Musimy porównać liczby oraz wypisać dwie ostatnie. Zobaczmy jak wygląda kod.

#funkcja wypisująca mniejsze od 1000 oraz dwie ostatnie
def smallerThan1000():
  #wczytuje liczby do listy 'numbs'
  numbs=readCleanData()
  
  #odfiltrowywuje liczby mniejsze niz 1000 i zwraca do listy
  filtered=list(filter(lambda x: x < 1000, numbs))
  
  #z odfiltrowanych wyciaga 2 ostatnie pozycje
  lastTwo = filtered[:-3:-1]

  print("Mniejsze niż 1000: " + str(filtered))
  print("Ostatnie dwie: " + str(lastTwo))

W pierwszej linijce używamy już napisanej funkcji do odczytania danych. Nad drugą warto się jednak pochylić i wytłumaczyć. funkcja lamda pobiera liczbę z numbs (w lamdzie to 'x') i porównuje obiekt.

Jeśli obiekt spełnia warunek to lambda 'mówi' metodzie filter(), że może dodać element do listy.

Na samym końcu otrzymane liczby opakowywjemy za pomocą metody list(), tak by utworzyć obiekt i operować na nim.

Więcej o filtrowaniu danych w języku Python możesz przeczytać na bardzo czytelnej stronie o tutaj

Póżniej wystarczy nam już tylko wyciągnąć dwa ostatnie elementy z odfiltrowanych liczb. Robimy to operując na indeksach tablicy. -1 oznacza, że będziemy wypisywać od końca, a jako, że wypisujemy dwa elementy to zakończymy na pozycji -3.

Wyszukiwanie dzielników

Wśród liczb występujących w pliku wejściowym znajdź te, które mają dokładnie 18 dzielników naturalnych (wliczając w nie 1 i samą liczbę). Dla każdej znalezionej liczby wypisz, oprócz jej wartości, listę wszystkich jej dzielników, posortowaną rosnąco.

Drugie zadanie wymaga już trochę więcej wysiłku oraz odnosi się do dzielników, stąd warto użyć napisanej wcześniej funkcji.

#funkcja wypisujaca liczby z 18 dzielnikami
def find18Dividers():
  numbs = readCleanData()
  #deklaracja slownika na otrzymane wartości
  numbsWith18 = {}
  #iteracja po liczbach
  for numb in numbs:
    #znajdywanie dzielnikow
    if len(findDividersOf(numb)) == 18:
      
      #kod wykonuje sie dlugo, warto zaznaczyc, ze pracuje
      print("licze...")
      
      #w slowniku liczba jest kluczem a wartoscia lista z dzielnikami
      numbsWith18[numb] = findDividersOf(numb)

  print("Liczb z 18 dzielnikami jest: " + str(len(numbsWith18)))
  print("Liczby oraz ich dzielniki: " + str(numbsWith18))

W tym przykładzie idealnie pasuje użycie obiektu w Python'ie jakim jest słownik (dictionary). Pozwala on przypisać obiektowi (klucz) inny obiekt (wartość), a jednocześnie iterować jak po liście.

Trzecia linijka od końca wyraża przypisanie kluczowi, w tym przypadku liczba, listę z jej dzielnikami. Jak możesz zauważyć funkcja findDividersOf() zwraca już posortowane dzielniki, więc wszystkie wymagania zadania są spełnione.

Liczby pierwsze

Znajdź największą liczbę w pliku, która jest względnie pierwsza ze wszystkimi pozostałymi, czyli taką, która z żadną z pozostałych liczb nie ma wspólnego dzielnika innego niż 1.

W tym zadaniu musimy znaleźć wszystkie liczby względnie pierwsze oraz wybrać z nich tą największą. Sprawdźmy jak wygląda kod.

#funkcja wypisujaca wzglednie pierwsza
def findMostPrimary():
  numbs = readCleanData()
  
  #odfiltrowywuje liczby niepodzielne przez 2
  notDividedBy2 = list(filter(lambda num: num % 2 != 0, numbs))
  
  #z notDividedBy2 odfiltrowywuje liczby niepodzielne przez 3
  notDividedBy3 = list(filter(lambda num: num % 3 != 0, notDividedBy2))
  
  #na koncu wyszukuje jakiekolwiek liczby zlozone
  
  #deklaracja listy liczb pierwszych
  primaryNumbers = list()
  #ilosc dzielnikow
  dividers = 0
  #iteracja po pozostalych liczbach
  for i in range(0, len(notDividedBy3)):
    #dla kazdej liczby
    for a in range(10, 101):
        # sprawdza dzielniki od 10 do 100
        if notDividedBy3[i] % a == 0:
          #zwieksz liczbe dzielnikow
          dividers = dividers + 1
          break
    
    #dodaje do listy tylko te liczby z dzielnikami 1 i siebie sama
    if dividers == 0:
      primaryNumbers.append(notDividedBy3[i])
      dividers = 0
      
  #wypisuje maksymalna wartosc
  print("Najwieksza wzglednie pierwsza: " + str(max(primaryNumbers)))

Kolejne linijki zajmują się 'przesianiem' danych. Jeżeli są one podzielne przez 2 lub 3 to lambda nie doda ich do nowej listy. Ten zabieg ma na celu trochę przyspieszyć program.

Warto zauważyć, że w 4 linijce operujemy na już przefiltrowanych danych. Taki zabieg mocno zmniejsza ilość liczb, które trzeba porównać.

Pierwsza pętla iteruje po pozostałych liczbach.

Druga pętla (ta zagnieżdżona) sprawdza czy są jeszcze jakieś liczby mające dzielniki w przedziale od 10 do 100.

Jeżeli liczba miała jakiś inny dzielnik to licznik dividers zwiekszamy o jeden.

Wartość dividers inna niż 0 nie pozwoli dodać liczby do listy primaryNumbers.

Ostatnia linijka to wyszukanie najwiekszej liczby w primaryNumbers za pomocą metody max() i wypisanie.

smallerThan1000()
find18Dividers()
findMostPrimary()

Teraz wystarczy już tylko wywołać funkcje i przetestować działanie.

shop
Otwórz Sklep Play

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

python W pliku liczby.txt danych jest 200 różnych liczb całkowitych z przedziału [2, 1 000 000], każda w osobnym wierszu pliku. Napisz program (lub kilka programów), który poda odpowiedzi do poniższych zadań python python python python Policz, ile jest w pliku wejściowym liczb mniejszych niż 1000, oraz podaj dwie takie liczby, które pojawiają się w pliku jako ostatnie (możesz założyć, że będą co najmniej dwie). python python python python Wśród liczb występujących w pliku wejściowym znajdź te, które mają dokładnie 18 dzielników naturalnych (wliczając w nie 1 i samą liczbę). Dla każdej znalezionej liczby wypisz, oprócz jej wartości, listę wszystkich jej dzielników, posortowaną rosnąco. python python python python Znajdź największą liczbę w pliku, która jest względnie pierwsza ze wszystkimi pozostałymi, czyli taką, która z żadną z pozostałych liczb nie ma wspólnego dzielnika innego niż 1.