Documente Academic
Documente Profesional
Documente Cultură
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.
n = 5
# afisati True
print(n&1 == 1)
True
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
n = 13 # 0b1101
# afisati 15
print(n | (1 << 1))
15
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
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
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
Idee:
i) aceeasi idee ca la problema 1;
10000
01111
ii) cautam o operatie convenabila
n = 0b110011000
print (bin(n | (n-1)))
0b110011111
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
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):
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
print( nd_p_rime(poezie))
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)
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)))
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.
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|
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.
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
numar(“A”) = 1
coloana(2) = “B”