Mülakat Sorusu Çözümü

https://accenturemulakatsorulari.wordpress.com/

Bu sitedeki şu soruyu çözebilecek olan var mı? Ben denedim ama çözemedim, çözümünü de çok merak ediyorum. Teşekkürler şimdiden.

"""
Works only Python 3.8 or high version.
"""

def new_count(string, char):
	find = False
	count = 0
	for c in string:
		if c == char:
			find = True
			count += 1
		else:
			if find:
				return count

string = "aaaaaaaabbbbhhhhxx ccckkk jjjjjxxxx"

if (_:=input("Enter String: ")):
	string = _

n = int(input("Enter Number: "))

for char in set(string):
	if new_count(string, char) >= n:
		string = string.replace(char, "*")

print(string)

Sorun hep boyle sorulari, zevkli oluyor :slight_smile:

3 Beğeni

Bu da benden olsun.

def degistir(s: str, n: int):
    result = s
    length = len(s)
    while length >= n:
        for i in range(len(result)):
            if result[i:i + length] == result[i] * length:
                result = result.replace(result[i:i + length], "*" * length)
        length -= 1
    return result


string = "abbcccaaeeeeb bfffffca ccab"
for i in range(2, 10):
    print(degistir(string, i))
5 Beğeni

Ellerinize sağlık, tebrikler. Teşekkürler ikinize de.

nedense böyle her slice gördüğümde irkiliyorum :rofl:

Programınız yanlış çalışıyor. Aşağıdaki string için 3 değerini girdim ve sonuç:

String = "abbcccaaeeeeb bfffffca ccab"

Program sonucu: abb***aa****b b******a **ab
Olması gereken: abb***aa****b b*****ca ccab

Bu da benim çözümüm

import re

def degistir(metin,sayi):
	harfler = set(list(metin.replace(" ","")))
	for i in harfler:
		for k in re.findall(i+"{"+str(sayi)+",}",metin):
			metin = metin.replace(k,"*"*len(k))
	return metin

metin = "abbcccaaeeeeb bfffffca ccab"
for i in range(2,10):
	print(i,"",degistir(metin,i))

Çıktısı

2  a***********b b*****ca **ab
3  abb***aa****b b*****ca ccab
4  abbcccaa****b b*****ca ccab
5  abbcccaaeeeeb b*****ca ccab
6  abbcccaaeeeeb bfffffca ccab
7  abbcccaaeeeeb bfffffca ccab
8  abbcccaaeeeeb bfffffca ccab
9  abbcccaaeeeeb bfffffca ccab
2 Beğeni

biraz daha hızlı gibi

def hide_repeated_chars(s: str, n: int):
    new_str = ""
    start = 0

    for i in range(len(s) + 1):
        if (i == len(s)) or (s[start] != s[i]):
            if i - start >= n:
                new_str += '*' * (i - start)
            else:
                new_str += s[start : i]
            
            start = i
    
    return new_str
3 Beğeni

1000 deneme için sonuçlar :smile:

coderistan     0.039934786000230815
dildeolupbiten 0.3620850019997306
toxide         0.015108527000847971
1 Beğeni

Arkadaşlar sizce bu soru daha çok hangi seviyeye giriyor? Bana ileri düzey gibi geldi. Bi’ ara gerçekten saçı başı yolacaktım. :))

Giriş - orta seviye.

1 Beğeni

Kodunuz boşlukları da * karakteri ile değiştiriyor.


Amaç hız ise işlemi daha basit ifade ederiz olur biter. re'ye, str.replace falan gerek yok. Stringleri slice’lamanın da çok zaman aldığını göz önünde bulundurmak lazım.

from timeit import default_timer as timer

def race(n, functions, args):
    times = {}
    for f in functions:
        times[f.__name__] = 0
        for arg in args:
            for i in range(n):
                first_time = timer()
                f(*arg)
                times[f.__name__] += timer() - first_time
    for i in sorted(times, key = lambda i: times[i]):
        print(i + ":", times[i])


def ekrem(s: str, n: int):
    answer = ""
    last_char = ""
    last_change_index = 0
    for i, j in enumerate(s + "1"):
        if j != last_char:
            sub = i - last_change_index
            if sub < n or last_char == " ":
                answer += s[last_change_index: i]
            else:
                answer += "*" * sub
            last_change_index = i
            last_char = j
    return answer

import re

def coderistan(metin,sayi):
    harfler = set(list(metin.replace(" ","")))
    for i in harfler:
        for k in re.findall(i+"{"+str(sayi)+",}",metin):
            metin = metin.replace(k,"*"*len(k))
    return metin

def dildeolupbiten(s: str, n: int):
    result = s
    length = len(s)
    while length >= n:
        for i in range(len(result)):
            if result[i:i + length] == result[i] * length:
                result = result.replace(result[i:i + length], "*" * length)
        length -= 1
    return result

s = "aaaaaaaabbbbhhhhxx ccckkk jjjjjxxxx"
race(1000, [coderistan, ekrem, dildeolupbiten], [(s, 2), (s, 3), (s, 4)])

3 Beğeni

Şu şekilde daha hızlı oldu gibi

def coderistan(metin,sayi):
	liste = []
	for x in metin.split(" "):
		karakter = x[0]
		sayac = 1
		sonuc = ""
		x = x[1:]
		for i in x+"1":
			if(i==karakter):
				sayac += 1
			else:
				if(sayac>=sayi):
					sonuc = sonuc + "*"*sayac
					sayac = 1
				else:
					sonuc = sonuc + karakter*sayac
					sayac = 1
				karakter = i

		liste.append(sonuc)

	return " ".join(liste)

Sizin kodunuzu yeniden yazarsak :smile:

from timeit import default_timer as timer

def race(n, functions, args):
    times = {}
    for f in functions:
        times[f.__name__] = 0
        for arg in args:
            for i in range(n):
                first_time = timer()
                f(*arg)
                times[f.__name__] += timer() - first_time
    for i in sorted(times, key = lambda i: times[i]):
        print(i + ":", times[i])


def ekrem(s: str, n: int):
    answer = ""
    last_char = ""
    last_change_index = 0
    for i, j in enumerate(s + "1"):
        if j != last_char:
            sub = i - last_change_index
            if sub < n or last_char == " ":
                answer += s[last_change_index: i]
            else:
                answer += "*" * sub
            last_change_index = i
            last_char = j
    return answer

def coderistan(metin,sayi):
	liste = []
	for x in metin.split(" "):
		karakter = x[0]
		sayac = 1
		sonuc = ""
		x = x[1:]
		for i in x+"1":
			if(i==karakter):
				sayac += 1
			else:
				if(sayac>=sayi):
					sonuc = sonuc + "*"*sayac
					sayac = 1
				else:
					sonuc = sonuc + karakter*sayac
					sayac = 1
				karakter = i

		liste.append(sonuc)

	return " ".join(liste)


def dildeolupbiten(s: str, n: int):
    result = s
    length = len(s)
    while length >= n:
        for i in range(len(result)):
            if result[i:i + length] == result[i] * length:
                result = result.replace(result[i:i + length], "*" * length)
        length -= 1
    return result

s = "aaaaaaaabbbbhhhhxx ccckkk jjjjjxxxx"
race(1000, [coderistan, ekrem, dildeolupbiten], [(s, 2), (s, 3), (s, 4)])

Sonuç

coderistan: 0.03150056499362108
ekrem: 0.03404845884506358
dildeolupbiten: 1.7739373189215257
1 Beğeni

Tekrarlanan tüm karakterlere aynı işlemin yapılacağını varsaydım. Böyle bir istisna olduğunu bilmiyordum.

Bunun hakkında çıkarımda bulunacağımız bir örnek verilmemiş ama ben okuduğumdan bunu anladım.

Kodunuz “1”'lerden oluşan girdilerde çalışmıyor:

def ekrem(s: str, n: int):
    answer = ""
    last_char = ""
    last_change_index = 0
    for i, j in enumerate(s + "1"):
        if j != last_char:
            sub = i - last_change_index
            if sub < n or last_char == " ":
                answer += s[last_change_index: i]
            else:
                answer += "*" * sub
            last_change_index = i
            last_char = j
    return answer

>>> ekrem('1111111111111', 2)
''

Evet, soruda karakter dizisinin sadece harf ve boşluklardan oluşacağı belirtilmiş zaten.

Ben de sanmıyorum, ama for döngüsünün sonuna eklediğim "1" ile sizin yaptığınız bu kontrolden:

Ve @coderistan’ın yaptığı bu kod tekrarından kurtuluyorum:

En son hız konuşulduğu için böyle bir optimizasyonu göstermek istedim.

Bi’ tane de benden olsun:

from itertools import groupby
def then(s, n):
    return "".join("*"*rep if (rep := len(list(group))) >= n else key*rep
                   for key, group in groupby(s))

Boşlukları da tekrar ediyor ama

4 Beğeni

Dediğiniz gibi sadece “1” ekleyerek kod tekrarını kaldırdım. Teşekkürler.

def coderistan(metin,sayi):
	liste = []
	for x in metin.split(" "):
		karakter = x[0]
		sayac = 1
		sonuc = ""
		x = x[1:]
		for i in x+"1":
			if(i==karakter):
				sayac += 1
			else:
				if(sayac>=sayi):
					sonuc = sonuc + "*"*sayac
					sayac = 1
				else:
					sonuc = sonuc + karakter*sayac
					sayac = 1
				karakter = i

		liste.append(sonuc)

	return " ".join(liste)

Ben denediğimde bazen sizinki bazen benimki daha hızlı oluyor.

Ben de kodumda slicing kullanmak yerine sizin gibi str.__mul__ kullandığımda daha hızlı oluyor:

from timeit import default_timer as timer

def race(n, functions, args):
    times = {}
    for f in functions:
        times[f.__name__] = 0
        for arg in args:
            for i in range(n):
                first_time = timer()
                f(*arg)
                times[f.__name__] += timer() - first_time
    for i in sorted(times, key = lambda i: times[i]):
        print(i + ":", times[i])


def ekrem(s: str, n: int):
    answer = ""
    last_char = ""
    last_change_index = 0
    for i, j in enumerate(s + "1"):
        if j != last_char:
            sub = i - last_change_index
            if sub < n or last_char == " ":
                answer += last_char * sub
            else:
                answer += "*" * sub
            last_change_index = i
            last_char = j
    return answer

def coderistan(metin,sayi):
	liste = []
	for x in metin.split(" "):
		karakter = x[0]
		sayac = 1
		sonuc = ""
		x = x[1:]
		for i in x+"1":
			if(i==karakter):
				sayac += 1
			else:
				if(sayac>=sayi):
					sonuc = sonuc + "*"*sayac
					sayac = 1
				else:
					sonuc = sonuc + karakter*sayac
					sayac = 1
				karakter = i

		liste.append(sonuc)

	return " ".join(liste)


s = "aaaaaaaabbbbhhhhxx ccckkk jjjjjxxxx"
race(1000, [coderistan, ekrem], [(s, 2), (s, 3), (s, 4)])

Ama sizin kodunuzdaki ekstra metin.split ve fazladan bir for kullanımı algoritmayı karmaşıklaştırıyor zaten, hızlı olsa da dilin implementasyon detayları ile alakalı olur.

1 Beğeni

Aslında fazladan değil. Dikkat ederseniz girdi metnine göre ilk for 3 kez, iç for ise kelime uzunluğu kadar çalıştığı için sizin düz for döngünüz kadar çalışıyor.

For döngüsünü düzelttim, çok fark olmadı sanki

def coderistan(metin,sayi):
	karakter = metin[0]
	sayac = 1
	sonuc = ""

	for i in metin[1:]+"1":
		if(i == " " and karakter == " "):
			sonuc = sonuc + " "
			continue

		if(i == karakter):
			sayac += 1
		else:
			if(sayac>=sayi):
				sonuc = sonuc + "*"*sayac
			else:
				sonuc = sonuc + karakter*sayac
			sayac = 1
			karakter = i

	return sonuc

Dediğiniz gibi bazen sizin kod, bazen de benim kod üstün geliyor :smile: