Meşhur mülakat sorusu FizzBuzz hakkında beyin fırtınası

Pek çok teknik mülakatta meşhur “FizzBuzz” sorusu soruluyor. Bilmeyenler için soru şu şekilde:

Write a short program that prints each number from 1 to 100 on a new line. 
For each multiple of 3, print "Fizz" instead of the number. 
For each multiple of 5, print "Buzz" instead of the number. 
For numbers which are multiples of both 3 and 5, print "FizzBuzz" instead of the number.

Bu sorunun pek çok çözümü var ve ilk akla gelen şu şekilde:

for i in range(1, 101):
    if i % 3 == 0 and i % 5 == 0:
        print("FizzBuzz")
    elif i % 3 == 0:
        print("Fizz")
    elif i % 5 == 0:
        print("Buzz")
    else:
        print(i)

en basiti bu ancak kişisel düşüncem, bu kodun bakımı zor gibi görünüyor. Örneğin kullanıcı Fizz yerine Neet yazmak isterse ya da Buzz yerine Yeet yazmak isterse gidip bunu print eden yeri bulup değiştirmesi gerekiyor vs. vs. (evet kod çok kısa ve değiştirmesi zor değil fakat büyük projelerde bu tip küçük şeyler sorun çıkarabiliyor), ya da belki de kullanıcı ekstra bir sayı eklemek istiyor, örneğin sayı 7’ye bölünebiliyorsa “Beep” yazmasını istiyor. bunu gidip yine if ile belirtmemiz gerekecek. Aklıma gelen sorunlar bunlar olduğundan şöyle bir kod hazırladım:

CONDITIONS = {
    3: "Fizz",
    5: "Buzz",
}

for i in range(1, 101):
    s = ""
    for k in CONDITIONS.keys():
        if i % k == 0:
            s += CONDITIONS[k]
    print(i) if s == "" else print(s)

bu şekilde CONDITIONS içerisinden istediğimiz şeyi değiştirebilir hale getirdim. Hatalarım olabilir, daha iyi yapılabilir, konuyu açma sebebim de bu aslında. Sizlerin de fikrini merak ediyorum. Nasıl daha iyi bir FizzBuzz kodu yazabiliriz?

Ben de şöyle bir şey yazayım:

START_RANGE, END_RANGE, INCREASE_COUNT = 1, 100, 1
TEXT_3, TEXT_5 = "Fizz", "Buzz"
TEXTS_NUMBERS = {3: TEXT_3, 5: TEXT_5}	

for i in range(START_RANGE, END_RANGE, INCREASE_COUNT):
    text_to_print = "" 

    for number, text in TEXTS_NUMBERS.items():
        if not i % number:
            text_to_print += text

    if text_to_print:
        print(text_to_print)

1 Beğeni

print(map(lambda i: ‘Fizz’(not i%3)+‘Buzz’*(not i%5) or i, range(1,101)),sep=‘\n’)

Kaynak:

Solve FizzBuzz in Python With These 4 Methods | Built In

Mesele soruyu çözmek mi? Çözmeye uğraşmak mı? Alternatif çözüm geliştirmek mi?

Bir satır içinde fizz buzz bulmak çok da zor olmasa gerek.

Ve bunu bunu mülakatta soran şirketlerden uzak durmak tavsiyemdir.

1 Beğeni

Sunu soyle birakiyorum: GitHub - EnterpriseQualityCoding/FizzBuzzEnterpriseEdition: FizzBuzz Enterprise Edition is a no-nonsense implementation of FizzBuzz made by serious businessmen for serious business purposes.

Bu bir kombinasyon sorusu.

Bence bizden, fizz: 2, buzz: 3, tazz: 5, gazz: 7 gibi farklı durumlar için de çalışabilen bir fonksiyon yazmamızı istiyorlar.

Yani;

2 x 3 = 6'ya tam bölünenler için fizzbuzz yazdırmalı.
2 x 5 = 10'a tam bölünenler için fizztazz yazdırmalı.
2 x 3 x 5 = 30'a tam bölünenler için fizzbuzztazz yazdırmalı.

def combinations(*args, r: int):
    if not r:
        yield []
        return
    for i in range(len(args)):
        for c in combinations(*args[i + 1:], r=r - 1):
            yield [args[i], *c]


def mul(*args):
    return map((f := lambda i: i[0] * f(i[1:]) if i else 1), args)


def combine_conditions(conditions: dict):
    combined = {}
    for r in range(1, len(conditions) + 1):
        combs = list(combinations(*conditions, r=r))
        combined.update(
            {
                j: "".join(map(lambda k: conditions[k], i))
                for i, j in zip(combs, mul(*combs))
            }
        )
    return {k: combined[k] for k in sorted(combined, reverse=True)}


def fizzbuzz(conditions: dict, n: int):
    combined = combine_conditions(conditions=conditions)
    for i in range(n):
        if i in combined:
            print(i, combined[i])
        else:
            for j in combined:
                if i and not i % j:
                    print(i, combined[j])
                    break
            else:
                print(i, i)


fizzbuzz(
    conditions={
        3: "Fizz",
        5: "Buzz",
        2: "Pazz",
        11: "Rozz"
    },
    n=100
)

Çıktı:

0 0
1 1
2 Pazz
3 Fizz
4 Pazz
5 Buzz
6 FizzPazz
7 7
8 Pazz
9 Fizz
10 BuzzPazz
11 Rozz
12 FizzPazz
13 13
14 Pazz
15 FizzBuzz
16 Pazz
17 17
18 FizzPazz
19 19
20 BuzzPazz
21 Fizz
22 PazzRozz
23 23
24 FizzPazz
25 Buzz
26 Pazz
27 Fizz
28 Pazz
29 29
30 FizzBuzzPazz
31 31
32 Pazz
33 FizzRozz
34 Pazz
35 Buzz
36 FizzPazz
37 37
38 Pazz
39 Fizz
40 BuzzPazz
41 41
42 FizzPazz
43 43
44 PazzRozz
45 FizzBuzz
46 Pazz
47 47
48 FizzPazz
49 49
50 BuzzPazz
51 Fizz
52 Pazz
53 53
54 FizzPazz
55 BuzzRozz
56 Pazz
57 Fizz
58 Pazz
59 59
60 FizzBuzzPazz
61 61
62 Pazz
63 Fizz
64 Pazz
65 Buzz
66 FizzPazzRozz
67 67
68 Pazz
69 Fizz
70 BuzzPazz
71 71
72 FizzPazz
73 73
74 Pazz
75 FizzBuzz
76 Pazz
77 Rozz
78 FizzPazz
79 79
80 BuzzPazz
81 Fizz
82 Pazz
83 83
84 FizzPazz
85 Buzz
86 Pazz
87 Fizz
88 PazzRozz
89 89
90 FizzBuzzPazz
91 91
92 Pazz
93 Fizz
94 Pazz
95 Buzz
96 FizzPazz
97 97
98 Pazz
99 FizzRozz

2 Beğeni

Konuya bir hikaye anlatarak gireyim. Belki biraz daha açıklamakta kolaylık sağlar. Türkiyenin sayılı nükleer fizik hocalarından biri İhsam hocam anlatmıştı. Bir kaç üniversite gezmiş sonunda da 2020 yılında emekli olmuş. Kapısındaki radyoaktif madde işaretinden hatırları hep anılarımda.

Bir mülakat hikayesi anlatmıştı.

Bir gerekçe ile bir şirketin ricası üzerine mülakatlarına katılmış. Mülakatta ciddi sorular sorduğunda mülakata katılanların zorlanmadığını görmüş.

Olaya bir de tersten bakalım deyip basit bir soru sorduğunda bir çoğunun başarısız olduğunu görmüş.

Şöyle ki, bir çok, master, doktora seviyesinde başvuru yapan katılımcıya bu sefer bir A4 kağıdı verip bundan bir koni yapmasını istemiş. (kağıttan katlayıp yapıştırak 3 boyutlu bir koni yapması istenmiş)

Bir kısmı bakmış kağıda bir şeyler çizmiş kesmeye çalışmış, büyük bir kısmı ise elini bile kağıda sürmeden hocam ben yapamam demiş.

Hoca denemey bile cesaret edemelerini. Teşebbüs dahi etmemelerini önce şaşkınlıkla sonra da üzüntüyle izlemiş.

Oysa ki amacı, bu basit soru ile bilgi seviylerini ölçmek değil. Sadece neler yapabileceklerini görebilmek, denme ve başarma azimlerini gözlemlemek miş.

Hikayeyi neden anlattım şimdi biraz anlaşılıyordur.

Bu mülkatlarda sorulan soru da basit koni sorusudur. Amaç burada fizz buzz algoritmasının karmaşıklığı ve zorluğu değil. Bunu deneyip nasıl gerçeklediklerini gözlemlemekten ibarettir.

Yani katılımcı, deneyecek mi? Uğraşacak mı nasıl bir bakış açısı getirecek koda görmekten ibarettir.

Yani biraz bu işin "Hello World"ü dür.

Kod bilgisi testi değil, kişilik testidir de diyebiliriz.

Konu basit, bir kaç temel bilgi beceri içeriyor. Gizem katmaya gerek yok.

Bölünebilme kurallarını, koşullu işlemleri ve iterasyonları bilen biri bu soruya farklı farklı bir çok çözüm getirebilir.

3’e ve 5’e bölünebilme kurallarının kontrolü ve bir for döngüsü ile yapılabilen kodun hiç bir özelliği yok.

Özel yanı, bu kadar basit bir kodu kim deneyecek, kim denemeyip bırakacak ona bakmak.

Bu nedenle bunu soran şirkete başvurmaya bile değmez dedim. Çünkü artık gereksinimler çok daha fazla bu tarz bir teste gerek kalmış mıdır bilmiyorum. İnsan kaynakları bir bilim dalına dönüşmüşken böyle adam seçmek biraz gelenekçi bir yaklaşım gibi geldi bana.

Yani,5 bölme için en sağdaki rakam 0 veya 5 mi diye bakarak.

Yada üçe bölünebilme durumu için sayının sayı değerleri toplamının 3’e bölümünü kontrol etmek gibi farklı yaklaşımlar da getirilebilirdi.

Sorana da bu şekilde saat çevrim sayısı daha az kod yazarak performansa önem verdim gibi değişik yaklaşımlar da önerilebilirdi.

Hayat for’lardan ibaret değil de diyebilirdi. While ile de yapılabilirdi. Yani her yöne genişleyebileceğiniz bir geliştirme sürecü oluşturulur.

Ama mesele az önce anlattığım hikaye üzerinden işliyor.

Yine de koda takıldıysanız, bir kaç farklı varyasyon daha kodlayabiliriz. Bir faydası olur mu emin olamadım.

Kolay gelsin.