Na forum 4programmers.net korzystamy z plików cookies. Część z nich jest niezbędna do funkcjonowania
naszego forum, natomiast wykorzystanie pozostałych zależy od Twojej dobrowolnej zgody, którą możesz
wyrazić poniżej. Klikając „Zaakceptuj Wszystkie” zgadzasz się na wykorzystywanie przez nas plików cookies
analitycznych oraz reklamowych, jeżeli nie chcesz udzielić nam swojej zgody kliknij „Tylko niezbędne”.
Możesz także wyrazić swoją zgodę odrębnie dla plików cookies analitycznych lub reklamowych. W tym celu
ustaw odpowiednio pola wyboru i kliknij „Zaakceptuj Zaznaczone”. Więcej informacji o technologii cookie
znajduje się w naszej polityce prywatności.
Do wykonania miałem proste zadanie ze ślimakiem, który w ciągu dnia wychodzi po słupie, a w nocy zjeżdża o określoną wartość.
Należy obliczyć ilość dni których potrzebuje ślimak do wejścia na słup.
Być może chciałem to zrobić zbyt bardzo na skróty i jakość tego kodu nie powala, jednakże prosiłbym o wyjaśnienie.
**Dlaczego, pomimo spełnienia warunku FALSE, przy 8 okrążeniu pętli dokonuje się inkrementacja? W sumie result powinien wynosić 8 a nie 10, **
Kopiuj
publicclassMain{publicstaticvoidmain(String[] args){int h =10;//Wysokość słupaint a =3;//Tyle ślimak wychodzi w ciągu dniaint b =2;//Tyle ślimak zjeżdża w nocyint result =0;for(; h >0; h += b){
h -= a;
result++;}System.out.println(result);}}
Logika to tu nie powala, bo sugerowałaby że zaczynasz od h=0 i przerywasz kiedy h==10 a ty robisz jakieś cuda na kiju
Nie bardzo rozumiem twój problem. Skoro wchodzi o 3 a zjeżdża o 2 to znaczy że każdego dnia wysokość zmienia się sumarycznie o 1. Skoro słup ma 10 to siłą rzeczy trzeba 10 dni. Weź pod uwagę że warunek pętli jest ewaluowany RAZ na obieg pętli a nie że magicznie ja przeywa kiedykolwiek kiedy wartość zmiennej nie spełniłaby warunku.
Kopiuj
for(int i=0;i<10;i++){int x = i;
i =100;// pętla wcale sie nie przerywa bo warunek będzie sprawdziony dopiero przy nowym obiegu!System.out.println("To sie wypisze");
i = x;}
edytowany 4x, ostatnio: Shalom
Zobacz pozostały 1 komentarz
Shalom
No niby jak? o_O Inkrementacja odbywa się PO obiegu pętli a warunek jest sprawdzany PRZED obiegiem pętli. W 8 dniu zaczynasz pętlę z h=2, warunek h>0 jest spełniony, wykonujesz h -= a czyli h=-1, następnie pętla się kończy więc wykonuje się akcja po pętli czyli h += b więc h=1 i znów warunek pętli h>0 jest spełniony...
Odnosiłem się do tego 'Skoro wchodzi o 3 a zjeżdża o 2 to znaczy że każdego dnia wysokość zmienia się sumarycznie o 1. Skoro słup ma 10 to siłą rzeczy trzeba 10 dni.'
Shalom
Jeszcze raz: tak to zostało zaimplementowane. Równie dobrze mógłby tam robić h-=1
Nie bardzo rozumiem twój problem. Skoro wchodzi o 3 a zjeżdża o 2 to znaczy że każdego dnia wysokość zmienia się sumarycznie o 1. Skoro słup ma 10 to siłą rzeczy trzeba 10 dni.
Jest błąd w pętli i pętla działa według logiki @Shalom.
@Shalom, @Op zauważcie że jak ślimak wszedł w dzień to już w nocy nie zjedzie więc z każdego dnia wchodzi 1m za wyjątkiem ostatniego gdzie wchodzi trzy metry
brzydka poprawka na szybko:
Kopiuj
for(; h > 0; h += b) {
h -= a;
result++;
if (h > 0) break;
},
Ale to powinno być napisane inaczej, może:
Kopiuj
h -= a;
result =+1;while(h >0){
h += b
h -= a;
result =+1;}
A - wykona się raz przed całą pętlą
B - wykona się przed każdym obiegiem pętli i pętla wykona kolejny obieg tylko jeśli B zwróci true
C - wykona się po każdym obiegu pętli
D - wykona się w każdym obiegu pętli jeśli B było true, wykona się przed C
Teraz już rozumiem. Przyjąłem, że pętla zawsze sprawdza B zanim wykona C (przy drugim i kolejnym przebiegu).
W dodatku debuger utwierdzał mnie w tym przekonaniu, pewnie źle go zinterpretowałem
Czyli ładujemy pierwszą zmienną lokalną, porównujemy z 10 i jak jest greater or equal to skaczemy do L2 czyli za pętle.
Potem mamy tego naszego printa, a dopiero po nim:
Kopiuj
IINC 1 1
GOTO L1
L2
Czyli na sam koniec pętli jest inkrementacja i skok na początek.
IMHO naturalne podejście. Usuwanie dopiero rekurencji kiedy jest taka potrzeba
Fibonacci, factorial, naturalne definicja jest rekurencyjna. Fibonacci można prosto napisać rekurencyjnie, memoizatiion (DP), step up z generowaniem tablicy wcześniejszych wyników albo w pętli while.
Rekurencyjne podejście do takich tematów, Fibonacci albo ślimak na słupie jest najbardziej intuicyjne
Najlepiej sobie rozrysować na kartce pierwsze kilka dni, ślimak zaczął od zera, idzie 3 m w górę, nie doszedł do wierzchołka, zjechał w nocy 2 m
Nowy dzień, obudził się 1 m nad ziemią, nie doszedł do wierzchołka do wieczora, idzie spać, zjeżdża 2 m w dół...
Pewnego dnia doszedł na szczyt i tu koniec opowieści.
@Artur Gacek: zadanie nie był ani całkiem proste, ani banalne. IMHO inna wersja fizz-buzz, pokazująca jak programista myśli
I dlatego uważam, że jak jakieś "rozmowy algorytmiczne" to tylko przy "tablicy", a nie zadania domowe an tydzień albo anonimowo codility na czas.
Przy okazji Fibonacci, ile tematów do omówienia przy szerszym sprawdzaniu wiedzy na interview przy okazji prostego zadanka? ;) - Dali proste zadanie ze ślimakiem, w końcu coś napisałem według. mnie rozwiązałem 100%, ale nie pytali więcej i się już nie odezwali... ;)
snail.js
Kopiuj
const poleHeight = 10
const goesUp = 3
const goesDown = 2
let currentPosition = 0
let days = 0
function climb() {
//from down till dusk
days++
currentPosition += goesUp;
if (currentPosition >= poleHeight) {
return days;
}
// from dusk till down
currentPosition -= goesDown;
// another day of hard work
climb()
}
climb()
console.log(days);
Shalomh=2
, warunekh>0
jest spełniony, wykonujeszh -= a
czylih=-1
, następnie pętla się kończy więc wykonuje się akcjapo pętli
czylih += b
więch=1
i znów warunek pętlih>0
jest spełniony...ShalomShalomh-=1