# Informatyka — zadanie 4.2

> Źródło: matura.lol — https://matura.lol/question/maturazai-informatyka-inf-2019-05/zad/4.2
> Wersja Markdown strony zadania (dla asystentów AI). Przy cytowaniu podaj matura.lol i link powyżej.

- arkusz: Informatyka · Matura · maj 2019 (rozszerzona)
- rok: 2019
- poziom: rozszerzona
- typ: open
- punkty: 4
- działy: Programowanie i algorytmika

## Treść

Kontekst - patrz zadanie 4.1.

Silnią liczby naturalnej k większej od 0 nazywamy wartość iloczynu 1·2 k i oznaczamy przez k!. Przyjmujemy, że 0!=1. Zatem mamy:
- 0! = 1
- 1! = 1
- 2! = 1·2 = 2
- 3! = 1·2·3 = 6
- 4! = 1·2·3·4 = 24 itd.

Dowolną liczbę naturalną możemy rozbić na cyfry, a następnie policzyć sumę silni jej cyfr. Na przykład dla liczby 343 mamy 3! + 4! + 3! = 6 + 24 + 6 = 36.

W pliku przyklad.txt znajduje się jedna taka liczba: 145 (1!+4!+5! =1+24+120 =145).

Podaj, w kolejności ich występowania w pliku liczby.txt, wszystkie liczby, które są równe sumie silni swoich cyfr.

## Rozwiązanie — maturazai.pl (AI)

## Poprawna odpowiedź

**Liczby z pliku liczby.txt równe sumie silni swoich cyfr (w kolejności występowania):**

2
145
1
40585

**Te liczby to tzw. "factorions" - w dziesiętnym wszystkich jest dokładnie 4: 1, 2, 145, 40585.**

## Sposób 1 - implementacja Python

```python
# Precomputed silnie 0! 9!
silnie = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]

def suma_silni_cyfr(n):
s = 0
if n == 0:
return 1 # 0! = 1
while n > 0:
s += silnie[n % 10]
n //= 10
return s

wyniki = []
with open('liczby.txt', encoding='utf-8') as f:
for linia in f:
n = int(linia.strip())
if suma_silni_cyfr(n) == n:
wyniki.append(n)

for w in wyniki:
print(w)
# 2
# 145
# 1
# 40585

**Weryfikacja:**
- 1: 1! = 1 ✓
- 2: 2! = 2 ✓
- 145: 1! + 4! + 5! = 1 + 24 + 120 = **145** ✓
- 40585: 4! + 0! + 5! + 8! + 5! = 24 + 1 + 120 + 40320 + 120 = **40585** ✓

## Sposób 2 - implementacja Pascal

```pascal
program SumaSilniCyfr;
var
f: TextFile;
n, m, suma, cyfra, i: LongInt;
silnie: array[0 9] of LongInt;
begin
silnie[0] := 1;
for i := 1 to 9 do silnie[i] := silnie[i-1] * i;
AssignFile(f, 'liczby.txt');
Reset(f);
while not Eof(f) do
begin
ReadLn(f, n);
m := n; suma := 0;
if m = 0 then suma := 1
else while m > 0 do
begin
cyfra := m mod 10;
suma := suma + silnie[cyfra];
m := m div 10;
end;
if suma = n then WriteLn(n);
end;
CloseFile(f);
end.

## Sposób 3 - implementacja C++

```cpp
#include <iostream>
#include <fstream>
using namespace std;

int silnie[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};

long long sumaSilniCyfr(long long n) {
if (n == 0) return 1;
long long s = 0;
while (n > 0) {
s += silnie[n % 10];
n /= 10;
}
return s;
}

int main() {
ifstream plik("liczby.txt");
long long n;
while (plik >> n) {
if (sumaSilniCyfr(n) == n) cout << n << endl;
}
return 0;
}

## Reference informatyczny - wydobywanie cyfr liczby

> Reference - Algorytm na rozkład liczby na cyfry:
> ```
> dopóki n > 0
> cyfra ← n mod 10
> n ← n div 10
> ```
> Złożoność: O(log₁₀(n)) - liczba cyfr.
>
> Reference - Silnia:
> - 0! = 1, n! = n · (n-1)! dla n > 0.
> - Rosnie szybko: 10! = 3 628 800, 12! przekracza 32-bit int.
> - Pre-kompute: tablica silni[0 9] = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880].
>
> Reference - Factoriony:
> - W dziesiętnym SĄ TYLKO 4 factoriony: 1, 2, 145, 40585. Udowodniono, że więcej nie istnieje.

## Schemat oceniania CKE

> Klucz CKE (zadanie 4.2, max 4 pkt):
> - **4 pkt** - wszystkie 4 liczby (2, 145, 1, 40585) w prawidłowej kolejności
> - **1 pkt** za każdą poprawną liczbę w wyniku
> - **0 pkt** - błędna albo brak

## Typowe pułapki

- **Pominięcie 0! = 1** - bez tego dla liczby 40585 wynik byłby 23+1+120+40320+120 = 40584 (lub mocno błędny).
- **Kolejność w wyniku** - musi być w kolejności pojawiania się w pliku liczby.txt (nie alfabetycznie/numerycznie).
- **Złe wpisanie tablicy silni** - najczęstszy błąd: pomylenie 5! = 120 z 6! = 720.
- **Overflow w Pascal/C++** - 9! = 362880 mieści się w 32-bit int, ale uważać dla wielocyfrowych liczb.
- **Brak warunku zatrzymania pętli** - gdy n=0 (liczba 0 nie pojawi się w danych, bo zakres 1-100000).

## Złożoność obliczeniowa

- Wczytanie pliku: O(n) - 500 wierszy.
- Obliczenie sumy silni cyfr: O(log n) ≈ 6 operacji (max 6 cyfr).
- Łącznie: **O(n · log(max))** ≈ 3000 operacji - błyskawicznie.
- Pamięć: O(1) (tablica silni stała).

## Linki

- [dane JSON](https://matura.lol/api/question/maturazai-informatyka-inf-2019-05/zad/4.2)
- [otwórz w wyszukiwarce](https://matura.lol/?problem=maturazai-informatyka-inf-2019-05%2Fzad%2F4.2)

## Podobne zadania

- [Zadanie 4.1](https://matura.lol/question/informatyka-2019-czerwiec-matura-rozszerzona-2/zad/4.1) — Zadanie 4.1. (0-4) Podaj, (zachowując ich kolejność) te liczby z pliku liczby.txt, które są liczbami pierwszymi z przedziału 〈100; 5000〉. Odpowiedź zapisz w pli
- [Zadanie 4.2](https://matura.lol/question/informatyka-2019-maj-matura-rozszerzona-2/zad/4.2) — Kontekst - patrz zadanie 4.1. Silnią liczby naturalnej k większej od 0 nazywamy wartość iloczynu 1·2 k i oznaczamy przez k!. Przyjmujemy, że 0!=1. Zatem mamy: -
- [Zadanie 4.2](https://matura.lol/question/informatyka-2019-czerwiec-matura-rozszerzona-2/zad/4.2) — Zadanie 4.2. (0-4) Podaj, w kolejności ich występowania w pliku pierwsze.txt, wszystkie te liczby, które czytane od prawej do lewej również są liczbami pierwszy
- [Zadanie 6.3](https://matura.lol/question/informatyka-2016-maj-matura-stara-podstawowa-2/zad/6.3) — Zadanie 6.3. (4 pkt) Liczby bliźniacze to takie dwie liczby pierwsze, które różnią się o 2, np.: (3, 5), (5, 3), (11, 13) lub (19, 17). Zbadaj w pliku dane_6.tx

_Ostatnia aktualizacja danych: 2026-10-03_
