<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.universitas.ro/index.php?action=history&amp;feed=atom&amp;title=2059_-_porumbei</id>
	<title>2059 - porumbei - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.universitas.ro/index.php?action=history&amp;feed=atom&amp;title=2059_-_porumbei"/>
	<link rel="alternate" type="text/html" href="https://wiki.universitas.ro/index.php?title=2059_-_porumbei&amp;action=history"/>
	<updated>2026-05-03T09:43:04Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.universitas.ro/index.php?title=2059_-_porumbei&amp;diff=3688&amp;oldid=prev</id>
		<title>Sovago Rares-Andrei: Pagină nouă: ==Cerința==  A venit primăvara și a început sezonul de concursuri pentru porumbei. La un concurs fiecare participant trebuie să trimită câte doi porumbei. Fiecare porumbel are ataşat pe picior un inel care conţine un număr. Într-o noapte, înainte de un concurs, Tavi, un mare pasionat de porumbei, are un vis în care o zână bună îi spune codurile celor doi porumbei pe care, dacă îi va trimite, va câştiga concursul. Cum Tavi este un mare uituc, dimineaţa î...</title>
		<link rel="alternate" type="text/html" href="https://wiki.universitas.ro/index.php?title=2059_-_porumbei&amp;diff=3688&amp;oldid=prev"/>
		<updated>2023-04-15T16:03:12Z</updated>

		<summary type="html">&lt;p&gt;Pagină nouă: ==Cerința==  A venit primăvara și a început sezonul de concursuri pentru porumbei. La un concurs fiecare participant trebuie să trimită câte doi porumbei. Fiecare porumbel are ataşat pe picior un inel care conţine un număr. Într-o noapte, înainte de un concurs, Tavi, un mare pasionat de porumbei, are un vis în care o zână bună îi spune codurile celor doi porumbei pe care, dacă îi va trimite, va câştiga concursul. Cum Tavi este un mare uituc, dimineaţa î...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Cerința==&lt;br /&gt;
&lt;br /&gt;
A venit primăvara și a început sezonul de concursuri pentru porumbei. La un concurs fiecare participant trebuie să trimită câte doi porumbei. Fiecare porumbel are ataşat pe picior un inel care conţine un număr. Într-o noapte, înainte de un concurs, Tavi, un mare pasionat de porumbei, are un vis în care o zână bună îi spune codurile celor doi porumbei pe care, dacă îi va trimite, va câştiga concursul. Cum Tavi este un mare uituc, dimineaţa îşi mai aminteşte doar prima parte a visului în care zâna îi spune 2 numere a şi n. El îşi mai aminteşte că numerele X şi Y (pe care le-a uitat) de pe inelele porumbeilor sunt puse în aşa fel încât rezultatul aX – aY să fie divizibil cu n. X și Y sunt numerele de pe inelele porumbeilor pe care îi va trimite la concurs.&lt;br /&gt;
&lt;br /&gt;
Dându-se doua numere a şi n, să se afişeze cele două numere X şi Y cu Y minim.&lt;br /&gt;
== Date de intrare ==&lt;br /&gt;
&lt;br /&gt;
Fișerul &amp;#039;&amp;#039;&amp;#039;porumbei.in&amp;#039;&amp;#039;&amp;#039; are pe prima linie numerele a și n, separate printr-un spațiu.&lt;br /&gt;
&lt;br /&gt;
== Date de ieșire ==&lt;br /&gt;
&lt;br /&gt;
Dacă datele sunt introduse corect, pe ecran se va afișa: &amp;quot;Datele sunt introduse corect.&amp;quot; Fișierul porumbei.out conține două numere naturale distincte, în ordine crescătoare și separate printr-un spațiu, ce reprezintă valorile minime ale lui X și Y astfel încât rezultatul a^X – a^Y să fie divizibil cu n.&lt;br /&gt;
&lt;br /&gt;
În cazul în care datele nu respectă restricțiile, se va afișa: &amp;quot;Datele nu corespund restricțiilor impuse.&amp;quot;.&lt;br /&gt;
== Restricţii şi precizări ==&lt;br /&gt;
*2 ≤ n ≤ 2.000.000&lt;br /&gt;
* 2 ≤ a ≤ 2.000.000&lt;br /&gt;
* 0 ≤ X &amp;lt; Y&lt;br /&gt;
&lt;br /&gt;
== Exemple ==&lt;br /&gt;
===Exemplul 1===&lt;br /&gt;
; &amp;#039;&amp;#039;porumbei.in&amp;#039;&amp;#039;&lt;br /&gt;
:4 10&lt;br /&gt;
; &amp;#039;&amp;#039;ecran&amp;#039;&amp;#039;&lt;br /&gt;
:Datele sunt introduse corect.&lt;br /&gt;
; &amp;#039;&amp;#039;porumbei.out&amp;#039;&amp;#039;&lt;br /&gt;
:1 3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2===&lt;br /&gt;
; &amp;#039;&amp;#039;porumbei.in&amp;#039;&amp;#039;&lt;br /&gt;
:4 7&lt;br /&gt;
; &amp;#039;&amp;#039;ecran&amp;#039;&amp;#039;&lt;br /&gt;
:Datele sunt introduse corect.&lt;br /&gt;
; &amp;#039;&amp;#039;porumbei.out&amp;#039;&amp;#039;&lt;br /&gt;
:0 4&lt;br /&gt;
&lt;br /&gt;
===Exemplul 3===&lt;br /&gt;
; &amp;#039;&amp;#039;porumbei.in&amp;#039;&amp;#039;&lt;br /&gt;
:3 5000000&lt;br /&gt;
; &amp;#039;&amp;#039;ecran&amp;#039;&amp;#039;&lt;br /&gt;
:Datele nu corespund restricțiilor impuse.&lt;br /&gt;
; &amp;#039;&amp;#039;porumbei.out&amp;#039;&amp;#039;&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Rezolvare == &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# 12059 - porumbei&lt;br /&gt;
def validate_input(m, n, a):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Validates the input values for the pigeonhole principle algorithm.&lt;br /&gt;
&lt;br /&gt;
    Args:&lt;br /&gt;
        m (int): The value of the base.&lt;br /&gt;
        n (int): The value of the modulus.&lt;br /&gt;
        a (int): The starting value.&lt;br /&gt;
&lt;br /&gt;
    Raises:&lt;br /&gt;
        ValueError: If any of the input values are invalid.&lt;br /&gt;
&lt;br /&gt;
    Returns:&lt;br /&gt;
        None.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if not (2 &amp;lt;= n &amp;lt;= 2000000):&lt;br /&gt;
        raise ValueError(&amp;quot;Invalid value for n!&amp;quot;)&lt;br /&gt;
    if not (2 &amp;lt;= a &amp;lt;= 2000000):&lt;br /&gt;
        raise ValueError(&amp;quot;Invalid value for a!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def pigeonhole_principle(m, n):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Implements the pigeonhole principle algorithm for finding the smallest non-negative integers p and q such that&lt;br /&gt;
    m^p ≡ m^q (mod n), where 2 &amp;lt;= m, n &amp;lt;= 2,000,000.&lt;br /&gt;
&lt;br /&gt;
    Args:&lt;br /&gt;
        m (int): The value of the base.&lt;br /&gt;
        n (int): The value of the modulus.&lt;br /&gt;
&lt;br /&gt;
    Returns:&lt;br /&gt;
        A tuple containing the values of p and q.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    v = bytearray(262145)  # The vector used to mark the found remainders&lt;br /&gt;
    v[1 // 8] = v[1 // 8] | (1 &amp;lt;&amp;lt; (1 % 8))  # Mark the remainder 1 as found&lt;br /&gt;
&lt;br /&gt;
    a = 1&lt;br /&gt;
    r = 1&lt;br /&gt;
    while True:&lt;br /&gt;
        r = (r * m) % n&lt;br /&gt;
        if v[r // 8] &amp;amp; (1 &amp;lt;&amp;lt; (r % 8)) != 0:  # If the bit for the remainder is already set&lt;br /&gt;
            q = a  # Then there was a previous remainder equal to r, so we stop&lt;br /&gt;
            break&lt;br /&gt;
        else:&lt;br /&gt;
            v[r // 8] = v[r // 8] | (1 &amp;lt;&amp;lt; (r % 8))&lt;br /&gt;
        a += 1&lt;br /&gt;
&lt;br /&gt;
    if r == 1:&lt;br /&gt;
        p = 0&lt;br /&gt;
    else:&lt;br /&gt;
        r1 = 1&lt;br /&gt;
        for i in range(1, q):&lt;br /&gt;
            r1 = (r1 * m) % n&lt;br /&gt;
            if r1 == r:&lt;br /&gt;
                p = i&lt;br /&gt;
                break&lt;br /&gt;
&lt;br /&gt;
    return (p, q)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    try:&lt;br /&gt;
        with open(&amp;quot;porumbei.in&amp;quot;, &amp;quot;r&amp;quot;) as f, open(&amp;quot;porumbei.out&amp;quot;, &amp;quot;w&amp;quot;) as g:&lt;br /&gt;
            m, n = map(int, f.readline().strip().split())&lt;br /&gt;
            a = 2  # Set a to the minimum valid value&lt;br /&gt;
            validate_input(m, n, a)  # Validate the input values&lt;br /&gt;
            print(&amp;quot;Datele sunt introduse corect.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            p, q = pigeonhole_principle(m, n)  # Run the algorithm&lt;br /&gt;
&lt;br /&gt;
            g.write(f&amp;quot;{p} {q}\n&amp;quot;)  # Write the output to file&lt;br /&gt;
    except ValueError as e:&lt;br /&gt;
        print(&amp;quot;Datele nu corespund restricțiilor impuse.&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Explicatie==&lt;br /&gt;
&lt;br /&gt;
validate_input(m, n, a)&lt;br /&gt;
Această funcție validează valorile de intrare m, n, și a pentru a se asigura că îndeplinesc restricțiile impuse. Mai exact, funcția verifică dacă n și a sunt între 2 și 2,000,000 inclusiv, iar dacă nu, se ridică o excepție ValueError cu un mesaj corespunzător. Dacă valorile de intrare sunt valabile, funcția nu returnează nimic.&lt;br /&gt;
&lt;br /&gt;
pigeonhole_principle(m, n)&lt;br /&gt;
Această funcție implementează algoritmul principiului cutiei poștale pentru a găsi cele mai mici numere naturale pozitive p și q astfel încât m^p ≡ m^q (mod n). În primul rând, se inițializează un vector de byte-uri v care va fi folosit pentru a marca resturile găsite. Se marchează restul 1 ca fiind găsit, deoarece (m^0) % n = 1. Apoi, se calculează restul r = (m^1) % n și se marchează ca fiind găsit în vectorul v. Se crește contorul a și se calculează următorul rest r = (m^a) % n. Acest lucru continuă până când se găsește un rest care a mai fost întâlnit anterior. Atunci, se oprește și se returnează perechea (p, q) de valori, unde p este valoarea minimă a lui a astfel încât m^p ≡ r (mod n) și q este valoarea minimă a lui a astfel încât m^q ≡ r (mod n) și q &amp;gt; p.&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
Această condiție verifică dacă script-ul este rulat ca program principal sau este importat ca modul în alt script Python. În acest caz, script-ul este rulat ca program principal. Acest bloc conține citirea datelor de intrare din fișier, apelarea funcției validate_input() pentru a valida datele de intrare și apelarea funcției pigeonhole_principle() pentru a rula algoritmul. În cazul în care datele nu sunt valide, se va ridica o excepție ValueError care va fi prinsă în blocul except.&lt;br /&gt;
&lt;br /&gt;
try-except&lt;br /&gt;
Aceasta este o structură de control care permite prinderea și gestionarea excepțiilor în Python. În acest cod, folosim try-except pentru a prinde excepțiile ValueError care sunt ridicate de funcția validate_input(). Dacă o excepție ValueError este prinsă, se afișează un mesaj corespunzător.&lt;/div&gt;</summary>
		<author><name>Sovago Rares-Andrei</name></author>
	</entry>
</feed>