Sunteți pe pagina 1din 8

0. Primiti un numar n. A sati numarul 2^n folosind operatii pe biti.

Idee: folositi o shiftare pe biti.

n = 5
 
# afisati 32
print (1 << 5)

32

0. Primiti un numar. Veri cati daca primul bit (0) este setat (daca numarul este impar) folosind operatii pe biti.

Idee: numarul 1 este impar; cum arata numerele impare in baza 2?

n = 5
 
# afisati True
print(n&1 == 1)

True

0. Primiti un numar. Veri cati daca bit-ul 2 este setat.

Exemplu: 13 = 1101; bit-ul 3 este 1, bit-ul 2 este 1, bit-ul 1 este 0, bit-ul 0 este 1.

n = 0b1101 # sau n = 13
 
# afisati True
if n & (1 << 2):
    print(True)
else:
    print(False)

True

0. Primiti un numar natural. Setati bit-ul 1 la 1.

Exemplu: n = 13 => a sati 15, pentru n = 14 => a sati 14

n = 13 # 0b1101
 
# afisati 15
print(n | (1 << 1))

15

0. Primiti un numar natural. De-setati bit-ul 0 (bit-ul 0 devine 0).

Exemplu: n = 4 => a sati 4, pentru n = 5 => a sati 4

n = 4
 
print(n&(~(1<<0)))

0. Primiti un numar natural. Scrieti o instructiune (pe biti) pe care daca o executati de doua ori, primiti inapoi rezultatul initial. Ex fara biti:

x=5
x = x * (-1) # numarul este -5
x = x * (-1) # numarul este 5

Idee: operatia XOR.

x = 5
print(x)
x = x ^ 1
print(x)
x = x ^ 1
print(x)

5
4
5

Optional. Convertiti un numar natural in baza 2 (sub forma unei liste din Python). Apoi convertiti lista formata din 0 si 1 inapoi in numarul initial.

Exemplu:
    f(12) = [1, 1, 0, 0]
    g([1, 1, 0, 0]) = 12
 
Idee: - extrageti cifrele unui numar din baza 10 mai intai
        (1523 -> [1, 5, 2, 3] si [1,9,3,4] -> 1934)   
      - pentru a inversa o lista: xs[::-1]              

def f(n):
    xs = []
    while n:
        xs.append(n%2)
        n //= 2
    return xs[::-1]
 
def g(xs):
    n = 0
    for x in xs:
        n = n*2 + x
    return n
 
n = 12
print(n, f(n), g(f(n)))

12 [1, 1, 0, 0] 12

1. Veri care numar putere a lui 2

Ex:
2 => True
256 => True
768 => False
1024 => True

Idee:
i) daca avem un numar in baza 2, cand scadem 1 vom avea:
11011000 - 1
11010111 (ca la scadarea din baza 10)
ii) puterile bazei vor fi intotdeauna:
1, 10, 100, …
iii) daca aplicam rationamentul de la i) avem:
10000
01111
iv) cautam o operatie binara convenabila

n = 256
print(n&(n-1)==0) # 0?

True

2. Schimbati toti biti de 0 de la nal in 1

n = 110011000 => 110011111

Idee:
i) aceeasi idee ca la problema 1;
10000
01111
ii) cautam o operatie convenabila

n = 0b110011000
 
print (bin(n | (n-1)))

0b110011111

3. Stergeti ultimul bit de 1 setat

n = 1101000 => 1100000

Idee:
i) numarul este n = 1101000
ii) vrem sa stergem ultimul 1, cautam un numar care are 1 pe pozitia respectiva (si care depinde de n)
iii) ca la primele 2 probleme daca stergem 1 avem:
1101000
1100111
iv) cautam o operatie convenabila

n = 0b1101000 
 
print (bin(n & (n-1)))

0b1100000

4. Interschimbare pozitie biti

Primiti 3 numere: n, i si j. Interschimbati bitii de pe pozitile i si j.

n = 10111001    i = 4        j = 1        =>     10101011

Idee:
i) gasiti o formula care verifica daca un bit este setat; folositi pentru i si j
ii) luati toate cazurile posibile (4) ignorati cazurile triviale
iii) pentru celelalte cazuri folositi if-uri pentru a modifica elem (o modificare se face usor;
cealalta instructiune trebuie dedusa - stergerea unui bit)
iii’) daca folositi XOR puteti comuta un bit; cum?

n = 0b10111001
i = 4
j = 1
 
print(bin(n ^ (1<<i) ^ (1<<j)))

0b10101011

5. Inversare biti

Primiti un numar pe 32 de biti. Construiti numarul care are biti in ordine inversa. Exemplu (8 biti):

n = 11101110 => 1110111

Idee:
i) folositi functia de la problema anterioara de mai multe ori
i’) folositi acelasi algoritm de la inversul unui numar pentru baza 10; dar modificati-l pentru baza 2;
i’’) parcurgeti numarul bit cu bit si daca un bit este setat il veti seta in noul numar (care initial este 0)

# i'
 
def f(n):
    xs = []
    while n:
        xs.append(n%2)
        n //= 2
 
    for x in xs:
        n = n*2 + x
    return n
 
n = 0b11101110
print(bin(f(n)))

0b1110111

6. Duplicate

Primiti o lista in care toate numerele apar de un numar par de ori, mai putin un numar care apare de un numar impar de ori. Gasiti acel numar.

xs = [2,2,1,6,2,6,3,1,2]

Idee:
i) cautati o operatia binara care va sterge elemente cand sunt egale;
ii) aplicati-o pe toate elemente vectorului;
iii) daca conteaza ordinea in care se aplica operatia verificati daca operatia binara este comutativa/asociativa pen
iv) asigurati-va ca functioneaza pana la final.

xs = [2,2,1,6,2,6,3,1,2]
 
rez = 0
for x in xs:
    rez = rez ^ x
print(rez)

7. P-rime
Doua cuvinte sunt p-rime daca au ultimele p litere egale. Scrieti o functie care primeste doua cuvinte si returneaza p maxim pentru care
cuvintele sunt p-rime.

s1 = “niciodata”
s2 = “fata”

nd_p_rime(s1, s2) == 3

Idee:
i) inversati string-urile si parcurgeti-le simultan
ii) incrementati un contor cat timp literele de la final sunt egale
iii) literele sunt diferite sau daca s-a terminat un string - iesiti
iv) returnati contorul

def p_rime(s_1, s_2):
    s_1 = s_1[::-1]
    s_2 = s_2[::-1]
 
    cnt = 0
    for i in range(len(s_1)):
        if s_1[i] != s_2[i]:
            break
        cnt += 1
 
    return cnt
 
s1 = "niciodata"
s2 = "fata"
print(p_rime(s1, s2))

8. Limba pasareasca

In limba pasareasca, de ecare data cand avem o vocala intr-o propozitie vom concatena litera p si acea vocala. Exemplu:

masa     = mapasapa
iepure   = iepepupurepe

Primind un string in limba romana, scrie o functie encrypt care converteste string-ul in limba pasareasca si o functie decrypt care converteste
un string din limba pasareasca in limba romana (daca se poate). Pentru veri care folositi: s == decrypt(encrypt(s))

Idee criptare:
i) parcurgeti string-ul initial
ii) cand intalniti o vocala salvati in string-ul nou v urmat de pv
iii) returnati noul string

Idee decriptare:
i) parcurgeti string-ul
ii) cand apare o vocala, verificati daca urmatoarele litere sunt pv
iii) daca sunt, le stergeti, daca nu inseamna ca a aparut o eroare

def is_voyel(c):
    return c in "aeiou"
 
def encrypt(s):
    crypted = ""    
    for c in s:
        crypted += c
        if is_voyel(c):
            crypted += 'p' + c
 
    return crypted
 
def encrypt(s):
    for vocala in "aeiou":
        s = s.replace(vocala, vocala + "p" + vocala)
    return s
 
def decrypt(s):
    decrypted = ""
    i = 0                   # parcurgem cu while
    while i < len(s):       # pentru ca trebuie sa sarim
        c = s[i]            # extragem caracterul curent
        if is_voyel(c):     # daca este vocala
            if (i+1 < len(s) and i+2 < len(s) and  # ne asiguram ca exista inca
                s[i+1] == 'p' and s[i+2] == c):    # doua litere dupa si sunt px
                decrypted += c      # adaugam litera
                i += 3              # sarim peste caracterul curent, p si x
            else:
                return False        # altfel este o eroare in string
        else:
            decrypted += c          # e consoana, nu conteaza
            i += 1                  # mergem la urmatorul caracter
    return decrypted
 
def decrypt(s):
    # presupunem ca s este corect
    for vocala in "aeiou":
        s = s.replace(vocala + "p" + vocala, vocala)
    return s
 
s = "masa"
print(encrypt(s), decrypt(encrypt(s)))

mapasapa masa

9. Poezie

Primiti o poezie, trebuie sa gasiti p cu prop. ca versurile sunt p-rime

poezie = “””A fost odată ca-n poveşti,


A fost ca niciodată.
Din rude mari împărăteşti,
O prea frumoasă fată.”””

print( nd_p_rime(poezie))

Primiti poezia fara diacritice, dar cu semne de punctuatie!

Idee:
i) scapati de semnele de punctuatie cu .replace(semn, ‘’);
ii) faceti un split pe versuri .split(“ “);
iii) pentru fiecare tip de rima, folositi functia de la problema 1 pentru a gasi p-ul;
iv) luati valoarea maxima care este respectata de toate versurile;
Bonus:
rezolvati problema care contine toata poezia (nu primiti doar o strofa,
ci toata poezia; idee: faceti split initial pe strofe .split(“\n\n”) si
folositi functia de mai sus care merge pe strofe.

poezie = """A fost odată ca-n poveşti,
A fost ca niciodată.
Din rude mari împărăteşti,
O prea frumoasă fată.
 
Şi era una la părinţi
Şi mândră-n toate cele,
Cum e Fecioara între sfinţi
Şi luna între stele.
 
Privea în zare cum pe mări
Răsare şi străluce,
Pe mişcătoarele cărări
Corăbii negre duce.
 
Îl vede azi, îl vede mâini,
Astfel dorinţa-i gata;
El iar, privind de săptămâni,
Îi cade draga fata.
 
Cum ea pe coate-şi răzima
Visând ale ei tâmple,
De dorul lui şi inima
Şi sufletu-i se împle.
 
Şi cât de viu s-aprinde el
În orişicare sară,
Spre umbra negrului castel
Când ea o să-i apară."""
 
def p_strofe(strofa):
    semne = ',.?!;'
    for i in semne:
        strofa = strofa.replace(i, '')
 
    versuri = strofa.split("\n")
 
    # imperechetata
    p_1 = p_rime(versuri[0], versuri[1])
    p_2 = p_rime(versuri[2], versuri[3])
 
    min_1 = min(p_1, p_2)
 
    # imbratisata 
    p_1 = p_rime(versuri[0], versuri[3])
    p_2 = p_rime(versuri[1], versuri[2])
 
    min_2 = min(p_1, p_2)
 
    # incrucisata 
    p_1 = p_rime(versuri[0], versuri[2])
    p_2 = p_rime(versuri[1], versuri[3])
 
    min_3 = min(p_1, p_2)
 
    raspuns = max(min_1, min_2, min_3)
    return raspuns
 
strofe = poezie.split('\n\n')
minim = 100
for strofa in strofe:
    p = p_strofe(strofa)
 
    minim = min(minim, p)
print(minim)

10. Comprimare si decomprimare

Primiti un string fara spatii in care literele se repeta des. Scrieti o functie care comprima string-ul astfel:

“aabbbbaccc”    =>    “a2b4a1c3”

Scrieti o functie de decomprimare care primeste string-ul comprimat si il intoarce la varianta initiala.

Idee comprimare:
i) parcurgeti string-ul initial
ii) cand intalniti prima data o litera
salvati litera
contor = 0
iii) cand intalniti litera salvata incrementati contorul.
iv) daca apare alta litera salvati rezultatul intermediar (+= l + “123”)
Idee decomprimare:
i) sirul este de forma “litNRlitNR…”
ii) salvati lit, extrageti nr, converti-l in int(NR), refaceti sirul lit * NR

def comprimare(s):
    # salvam caracterul curent sa stim daca se repeta
    caracter_crt = s[0]
    cnt = 0
 
    str_comprimat = ''
 
    for c in s:               # pentru fiecare caracter din string
        if c == caracter_crt: # daca este caracterul curent il contorizam
            cnt += 1   
        else:                 # daca nu inseamna ca s-a schimbat caracterul
            str_comprimat += caracter_crt + str(cnt) # salvam comprimarea
            
            caracter_crt = c  # modificam caracterul curent
            cnt = 1           # aceasta a aparut o data (acum)
            
    if cnt != 0:    
        str_comprimat += caracter_crt + str(cnt)    
    return str_comprimat
 
def comprimare(s):
    # gasim indicii unde apar litere diferite
    idx_inceput = [0]
    idx_sfarsit = []
    for i in range(len(s) - 1):
        if s[i] != s[i + 1]:
            idx_sfarsit.append(i)
            idx_inceput.append(i + 1)
    idx_sfarsit.append(len(s) - 1)
 
    comprimat = ''
    for inc, sf in zip(idx_inceput, idx_sfarsit):
        comprimat += s[inc] + str(sf - inc + 1)
    
    return comprimat
 
 
def decomprimare(s):
    str_decomprimat = ""
 
    i = 0
    while i < len(s):
        # extragem litera
        litera = s[i]
 
        # salvam in str_nr numarul (poate avea mai multe cifre)
        str_nr = ''
        while i + 1 < len(s) and s[i + 1].isnumeric():
            str_nr += s[i + 1]
            i += 1
 
        # adaugam litera in string-ul decomprimat de str_nr ori
        str_decomprimat += litera * int(str_nr)
        i += 1
 
    return str_decomprimat
 
def decomprimare(s):
    decomprimat = ''
 
    idx_litere = []           # gasim pozitiile literelor din string
    for i in range(len(s)):
        if s[i].isalpha():
            idx_litere.append(i)
    idx_litere.append(len(s)) # adaugam o litera fictiva pentru sfarsit numarului
 
    for i in range(len(idx_litere) - 1):    # pentru fiecare indice
        idx_litera = idx_litere[i]          # extragem litera
        idx_start_nr = idx_litere[i] + 1    # extragem inceputul numarului
        idx_end_nr = idx_litere[i + 1] - 1  # extragem sfarsitul numarului
 
        decomprimat += s[idx_litera] * int(s[idx_start_nr:idx_end_nr + 1])
    
    return decomprimat
 
s = "aabbbbaccc"
print(s, comprimare(s), decomprimare(comprimare(s)))

aabbbbaccc a2b4a1c3 aabbbbaccc

11. Rot(13)

Primiti un string s si un numar k. Trebuie sa rotiti ecare litera din s cu k pozitii mai la dreapta.

De exemplu:

s = “bec” k = 3 =>
rot(s, k) = “ehf”
irot(“ehf”, k) = “bec”

Idee:
folositi functiile predefinite ord si chr pentru conversie ASCII:
ord(‘a’) = 97
chr(98) = ‘b’
aveti grija la literele de la final:
la rot: litere x, y, z (trebuie sa mearga de la capat)
la irot: literele a, b, c (trebuie sa mearga de la sfarsit)

Bonus:
alte operatii pentru a nu scrie if-uri pentru depasire?

s = "bec"
k = 3
 
def rot(s, k):
    r = ""
    for c in s:
        # trebuie sa avansam cuvantul k litere la dreapta
        # il convertim la ASCII, ii adaugam k pozitii, 
        # facem modulo 26 pt depasiri si il convertim inapoi in string
        idx_caracter_nou = (ord(c) + k - ord('a')) % 26
        r += chr(idx_caracter_nou + ord('a'))
    return r
 
def irot(s, k):             # putem face ca la rot cu "-"
    return rot(s, 26-k)     # sau rotim de 26-k ori (operatia %)
 
print(rot(s, k), irot(rot(s, k), k))

ehf bec

12. Powerset 2Q

Daca aveti o multime Q = {1, 2, 3}, multimea partilor lui Q se noteaza 2Q = {{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}}. Exista o functie bijectiva
intre numerele {0, … n - 1} si multimea 2Q. Gasiti aceasta functie si implementati un program care va a seaza pentru o lista xs data, multimea
partilor lui xs.

13. Cea mai apropriata greutate

De nim greutatea unui numar ca numarul de biti de 1 din reprezentarea sa in binar. Scrieti un program care pentru un numar x dat, gaseste y,
care este cel mai apropiat numar de acesta a.i.:

i) greutate(x) == greutate(y)
ii) ∀z care respecta i) |y - x| <= |z - x|

Exemplu: x = 1100 => y = 1010 (z = [0011, 0101, 0110, 1001…]


 

14. Calculati x * y, fara a folosi operatorul *

Puteti folosi variabile, |, &, ^, >>, << si instructiuni (if, for, while) si functii scrise de voi.

15. Concatenare

Primiti un string s. Trebuie sa gasiti k maxim astfel incat s sa se poate scrie ca t+t+...+t de k ori.

Exemplu: s = “abcabc” => gasim t = “abc” => s = t + t => k = 2

16. Adrese IP amestecate

Primiti o adresa IP fara puncte. Trebuie sa a sati toate adresele IP posibile care se pot forma (sa puneti 3 puncte):

Exemplu:

1721601 -> 172.16.0.1 | 17.216. 0. 1 | 1.72.160.1

17. Schimbare de baza

In Excel aveti coloanele: A, B … Z, AA, AB, … AZ, BA … AAA

Scrieti doua functii care fac conversia intre coloane si numere:

numar(“A”) = 1
coloana(2) = “B”

S-ar putea să vă placă și