Cześć @michalstroz!
Pisząc, że programujesz około roku zbyt wiele to nie mówi. Intensywnie ucząc się można w ciągu takiego czasu dużo się nauczyć, ale równie można nie mieć pomysłu jak uczyć się dobrze i tkwić niejako w miejscu.
Jeśli szukasz stażu to bardzo dobrze! Ogólnie nauka na realnym kodzie, w środowisku z bardziej doświadczonymi programistami daje ogromnego kopa (zakładam oczywiście, że na takim stażu robiony jest code review kodu stażysty i nie jest on rzucany w przysłowiowy kąt).
Z rekrutacją jest różnie. Są firmy, które trzepią ostro z algorytmów, inne z kolei przepytują wręcz z teorii, a inne będą chciały Cię sprawdzić od razu w praktyce. Rekrutacja programistów jest trudna i tak naprawdę nie ma idealnego sposobu (choć oczywiście są lepsze i gorsze sposoby). Nie ma się co zrażać do tego czy przejmować. Idąc na rozmowę musisz postawić sobie realny cel, nie wymagać od siebie cudów. Tym realnym celem póki co jest dowiedzieć się czego firmy wymagają od kandydatów i za każdym razem próbować się pod tym kątem przygotować jeszcze lepiej. Jeśli rzeczywistość pokaże, że firmy trzepią z algorytmów nie pozostanie nic innego jak podszkolenie się w tej dziedzinie.
Podajesz przykład zadania z jakim miałeś do czynienia. Czy udało Ci się wymyślić algorytm? To zadanie być może z początku wydawać się trudne, ale już po chwili zastanowienia rozwiązanie powinno przyjść do głowy. Pozwolę sobie zaprezentować tutaj rozwiązanie, po to żebyś zobaczył że rozwiązanie nie jest trudne.
Nie przytaczasz pełnej treści tego zadania (co w zadaniach algorytmicznych ma ogromne znaczenie, czasem jedno słowo może zmieniać sens), ale zakładam że mając ciąg aabbbcccca
wystarczy, że dokonam 4 podmian (aabbbcccca
-> axbxbcxcxa
) i dostaję łańcuch, w którym nie powtarzają się znaki obok siebie. Analizując dochodzę do wniosku, że interesują mnie podciągi spójne (czyli następujące po sobie znaki) z powtarzającymi się znakami. Jeśli powtarzających się znaków w takim ciągu jest 2 to wystarczy, że zamienię 1 z nich (aa
-> ax
), jeśli jest ich 3 to wystarczy, że zamienię także 1 (aaa
-> axa
). Idąc dalej dla 4 i 5 zmian muszę zrobić 2 (aaaa
-> axax
, aaaaa
-> axaxa
). Widzę zatem że jest to całkowite (bez reszty) dzielenie N/2, gdzie N to długość takiego podciągu.
Wystarczy znaleźć długości kolejnych podciągów składających się z tych samych znaków i zsumować ich długości podzielone przez 2 (co ciekawe nie trzeba robić specjalnego przypadku dla podciągu o długości 1 bo 1/2 da nam 0).
Kod:
def count_changes(arr)
arr.map { |str| count_changes_in_string(str) }.sum
end
def count_changes_in_string(str)
total = 0
i = 0
while i < str.size
j = i + 1
while str[i] == str[j]
j += 1
end
total += (j - i) / 2
i = j
end
total
end
puts count_changes([
'ab',
'aab',
'abba',
'abaaaba'
]);
Do zadanie to typowa łamigłówka gdyż nie trzeba znać żadnego konkretnego algorytmu. Kwestia pogłówkowania i pobawienia się danymi. Ilość czasu potrzebna na rozwiązanie to kwestia względna. Też nie przepadam za dawaniem jakiś wyśrubowanych limitów.
Sposób myślenia, umiejętność główkowania. Wiem, że różnie są odbieranie tego typu zadania, ale mimo wszystko umiejętność rozwiązywania tego typu zadań trochę mówi o potencjale programistycznym kandydata. Natomiast nie oznacza to, że każdy kto programuje musi się w tym specjalizować. Programowanie jest ogromną dziedziną i nie da się od wszystkich wymagać tych samych umiejętności.
Predyspozycje to raczej coś co sprawia, że uczysz się szybciej lub wolniej. To co budujesz to umiejętności. Jak? Pracując, ucząc się, pisząc kod, czytając. I nie możesz tego robić z doskoku. Potrzebna jest praca regularna, najlepiej codzienna. Większość programistów miała taki etap w życiu, że programowana codziennie.
Ależ oczywiście, że tak! I recepta jest prosta. Próbujesz rozwiązywać tego typu zadania, aż zaczną wchodzić w krew. One naprawdę uczą myślenia logicznego i kombinowania. To się z czasem przełoży na ogólne programistyczne myślenie. Ze swojej strony polecam Ci polski serwis SPOJ http://pl.spoj.com/ (mają skopaną trochę rejestrację, robisz to na wersji anglojęzycznej a potem wchodzisz ręcznie na adres który Ci podałem).
Zacznij sobie od kategorii łatwe. Nie wszystkie zadania da się rozwiązać w Ruby (limity czasowe często są ustawione pod szybsze języki). Polecam przed rozwiązywaniem sprawdzić czy ktoś rozwiązał zadanie w Ruby (wchodzisz na konkretne zadanie, potem w zakładkę ‘Najlepsze’ i filtrujesz po Ruby). Spróbuj codziennie rozwiązywać po 3-5 zadań. Po miesiącu będziesz mieć setkę zadań.
Nauka RoR oczywiście też jest ważna. Ostatecznie chodzi przecież o umiejętności tworzenia aplikacji (tak, w pracy nie rozwiązuje się zadań tego typu jak przytoczyłeś ;-)).
Co do nauki algorytmów to zależy od Ciebie. Są firmy, które nie trzepią z algorytmicznych zadań, bardziej skupiając się np. na praktyce w RoR. Ale moim zdaniem dużo zyskasz jednak robiąc i takie zadania. One uczą logicznego myślenia, umiejętności przelewania wymyślonego algorytmu w kod, szukania przypadków brzegowych i wiele innych.
Ogólnie nie masz się co załamywać. Kwestia czasu i samozaparcia. W końcu osiągniesz swój cel :). Jakbyś miał jeszcze jakieś konkretne pytania to pisz śmiało (nawet PW). Chętnie podpowiem.