|
Ülesanne: kirjutada funktsioonid, mis leiavad ringpuhvris olevas kasvavalt järjestatud arvujadas Ringpuhver on massiiv, mille esimest elementi loetakse viimasele järgnevaks. Kasvav arvujada ringpuhvris Vastavalt kasutatavale keelele võib eeldada massiivi PS. See on meelelahutus, mitte küsimus, mille vastust mulle millekski tegelikult vaja oleks. PPS. Väidetavalt kasutab Google seda küsimust oma programmeerijakandidaatide sõelumiseks. |
|
Ma pakun välja järgmise lahenduse
Kogu austuse juures pean ma ütlema seda, et need ühetähelised muutujad ajavad mul pea täiesti segi.
(Nov 15 '09 at 11:56)
Rene Saarsoo ♦♦
|
|
PHP-s
(Nov 15 '09 at 11:49)
Rene Saarsoo ♦♦
Ning
(Nov 15 '09 at 11:51)
Rene Saarsoo ♦♦
probleemid parandatud :)
(Nov 16 '09 at 20:47)
Jaan J
+1 selle koodi hallatavuse (maintainability) eest - suvaline programmeerija on võimeline 10 sekundiga tuvastama, mida see kood teeb ja kuidas teda muuta, nii et see katki ei lähe. Lisaks kasutab see mälu O(1) võrrelduna rekursioonipõhiste lahendustega, mis kasutavad mälu O(log2n) (pinu! :) (ärge tapke kui siin millegagi mööda panin). Lõpuks nende andmemahtude puhul, kus lineaarse otsingu ja kahendotsingu ajaline vahe märkimisväärseks kujuneb, on minu meelest lahenduseks mingi kavalam andmestruktuur, kuna andmed on niikuinii kõvakettal.
(Nov 17 '09 at 07:47)
Tambet Matiisen ♦♦
1
Koodi hallatavuse koha pealt ma olen nõus. Antud juhul on sul mälu keerukuse koha pealt ka õigus, aga need rekursiooniga töötavad lahendused saab iteratiivseks teha ilma stackita, st ka mälu kuluks saab O(1). Ise realiseerin rekursiivselt ainult loetavuse huvides. Mis andmemahtudesse puutub, siis 1k suuruse ringpuhvri korral on lg n lahendus 100 korda kiirem (reaalselt märksa vähem) ja kui puhvrist massiliselt päringuid tehakse, siis juba see suur vahe.
(Nov 17 '09 at 11:47)
Avo
@Jaan: Koos parandustega tekitasid
(Nov 17 '09 at 21:05)
Rene Saarsoo ♦♦
@Rene Aga palun õpeta mind noort inimest. Copy-pastega funktsioon töötab.
(Nov 18 '09 at 07:59)
Jaan J
@Jaan: Ahh.. minu viga. Unustasin ära, et need asjad on seal ringpuhvris ju kasvavalt järjestatud. Varem töötas su kood ka suvaliselt järjestatud massiivist miinimumi leidmiseks, aga ülesanne seda muidugi ei nõua.
(Nov 18 '09 at 20:05)
Rene Saarsoo ♦♦
Peab mainima, et Tambeti kiidetud iseenesest-mõistetavus langes tublisti selle
(Nov 18 '09 at 20:08)
Rene Saarsoo ♦♦
Vabandan kommentaaride puudumise ja üritan tulevikus end parandada.
(Nov 18 '09 at 20:25)
Jaan J
showing 5 of 10
show all
|
|
Kuna tegemist Googli küsimusega, siis läksin kaasa viimase hullusega ning kirjutasin lahenduse Go keeles. Kummagi funktsiooni puhul kasutatakse natuke modifitseeritud varianti kahendotsingust. Seega kumbki peaks halvimal juhul olema O(log(n)). Täiesti suurepäraselt sobisid selle ülesande jaoks Go tükid (slice), mis võimaldavad effektiivselt anda funktsioonile edasi valitud tükikese massiivist. Näiteks kui allolevas koodis on
Mulle tundub alati kahtlane, kui massiivi indeksiteks hakatakse reaalarve panema. Pakun, et int(math.Ceil(float64(length / 2))) asemel oleks parem kasutada (length + 1) / 2.
(Nov 25 '09 at 13:16)
Ahto Truu ♦♦
1
Pealegi, kui length on täisarv, siis on kõigis mulle tuntud keeltes paaritu length korral length / 2 juba allapoole ümardatud ja selle hilisem reaalarvuks teisendamine kaduma läinud .5 enam tagasi ei too. Pole küll kindel, kas see ümardamise suund üldse on lahenduse jaoks oluline, aga näha on, et selle nimel on tulutult vaeva nähtud ;)
(Nov 25 '09 at 13:20)
Ahto Truu ♦♦
Õige märkus. Nüüd takkajärgi ei saa ma enam ise ka aru, mida ma selle ümardamisega saavutada tahtsin. Aga noh... kell oli umbes kolm öösel ka juba kui ma seda koodi kirjutasin :)
(Nov 26 '09 at 19:08)
Rene Saarsoo ♦♦
|
|
Siin on siis minu käkerdis :D... (enda väikesed testid pidas vastu).
Mõlemad algoritmid ruumis
+1 mitterekursiivse lahenduse eest findMin() puhul. Selle eelis on, et kasutab mälu O(1) võrrelduna O(log2n) rekursiivsete puhul (pinu! :). findVal() saaks ju samamoodi lahendada? Kui ma ei eksi, on tegemist sabarekursiooniga (tail recursion).
(Nov 17 '09 at 07:53)
Tambet Matiisen ♦♦
Tegelikult findVal on ka mitte-rekursiivne. Lihtsalt, kui meil on
(Nov 17 '09 at 08:31)
egon ♦♦
Kiire ta võib ju olla arvutile täita, aga inimesele lugeda on see kood väga-väga aeglane.
(Nov 17 '09 at 21:11)
Rene Saarsoo ♦♦
|
|
Teeme siis lühidalt:
Või siis nüüd üldisemalt:
Nii et miinimumi leidmise asemel kirjutasid hoopis maksimumi leidmise funktsiooni.
(Nov 17 '09 at 21:13)
Rene Saarsoo ♦♦
Nujah, kesse siis seda püstitust nii tähelepanelikult lugema viitsib. :)
(Nov 22 '09 at 20:42)
kt ♦♦
|
|
Haskelli versioon:
Testid interpretaatoris:
|
|
find_min siis minupoolt
See paistab kohe mitme asja poolest kahtlane. Esiteks muutujale
(Dec 12 '09 at 22:36)
Ahto Truu ♦♦
|
|
C# variant:
1
Annab muidugi õigeid vastuseid, aga suurte massiivide korral võtab nende saamine aega. Samas, kui ülesande kontekstist on ette teada, et massiivid on alati väikesed, siis tasubki just lihtsa lahenduse peale panustada.
(Feb 16 '10 at 08:40)
Ahto Truu ♦♦
|
|
Reaalsed ringpuhvrid evivad sageli lisaks pesadele ka viita puhvri "sisulisse" algusse. Viide Google suunas tähendab ilmselt, et selles ülesandes niisugust viita ei ole (muidu oleks tegemist Microsofti ülesandega), aga kuna puhvri vähima elemendi positsiooni teadaolemine ülesande sisu oluliselt mõjutab, oleks see ilus ilmutatult ära mainida. Kui puhvri vähima elemendi indeks antud oleks, siis oleks a) küsimus ju täitsa mõttetu olnud?
(Nov 25 '09 at 13:23)
Ahto Truu ♦♦
Jah, reaalses elus tuleb seda ette, et muist ülesande nüansse on tegelikult täitsa mõttetud. :-)
(Nov 27 '09 at 17:30)
dig
|

Paar näidet oleks hea.
FindMin([5,6,7,1,2,3,4]) --> 4 (või 3, kui indeksid on nullist)
FindVal([5,6,7,1,2,3,4], 2) --> 5 (või 4, kui indeksid on nullist)
Ahjaa, väärtused ei tarvitse muidugi alati olla 1..n:
FindMin([7,9,2,4]) --> 3 (või 2, kui indeksid on nullist)
Ma olen natuke üllatunud, et ei tulnud ühtegi lahendust, mis oleks lähtunud tähelepanekust, et massiivi algusest kuni miinimumini on üks ja miinimumist massiivi lõpuni teine mittekahanev lõik. Otsitava väärtuse ja massiivi esimese elemendi võrdlemise põhjal oleks kohe teada, kummas neist kahest otsitav element olla võiks. Siis saaks
FindValrealisatsioonisFindMinabil miinimumi asukoha leida ja sealt edasi juba puhast kahendotsingut kasutada.