array.empty?coz mi prijde hezci nez:
array == []
@@content = YAML.load_file('file_name')takze ta indirekce pres:
File.open("file_name") { |f| @@content = YAML::load(f) }neni nutna (nehlede na to, ze pri pouziti vasi varianty bude drobny problem pri prirazeni do lokalni promenne, pokud jiz neexistovala, nebot bude block-local).
return vyber.sort_by { |x| -x[0].length }[0][0]misto puvodniho:
return vyber.map{ |pole| pole[0] }.inject do |memo, jmeno| memo.length > jmeno.length ? memo : jmeno end
return vyber.sort_by { |x| -x[0].length }[0][0]je sice zdánlivě elegantnější, ale rozhodně je to pomalejší. To je typická chyba lidí, co příliš používají vyžší programovací jazyky a zapomínají co se děje pod kapotou (pokud to vůbec kdy věděli). Pokud teda ruby nepoužívá tak chytré lazy evaluation a výsledek bude stejný. Ale o tom dost silně pochybuji. V daném případě, kdy to pole bude obsahovat 1-3 prvky, je to putna, ale představte si, co by se stalo, použít stejný kód na 10^6 prvků.
Tohle mi fakt bavi :-) Tak my se tady bavime o +-365ti zaznamech ... a vy tu vytahnete 10^6 a jeste se me snazite urazet, ze nad tim nepremyslim (pokud na to tedy vubec mam :) ).
Ja chapu, ze slozitostne je to moje minimalne O(n*log(n)) a to puvodni O(n), protoze ja delam trideni (qsort), kdezto puvodni reseni dela jen 2x pruchod tim polem. Jenze pri ~400 prvcich je rozdil asi tak:
wejn@ns ~ $ ruby a.rb Velikost: 400 user system total real new: 0.000000 0.000000 0.000000 ( 0.001714) orig: 0.000000 0.000000 0.000000 ( 0.001567) user system total real new: 0.000000 0.000000 0.000000 ( 0.001742) orig: 0.010000 0.000000 0.010000 ( 0.004466) user system total real new: 0.000000 0.000000 0.000000 ( 0.001608) orig: 0.000000 0.000000 0.000000 ( 0.001983)pri pouziti nasledujiciho benchmarku, coz zajiste nehraje roli.
Az se nekdy v budoucnu rozhodnu operovat nad daty z celonarodniho scitani lidu, nebo tak neco ... tak se opravdu zamyslim nad slozitosti (a treba pujdu pouzit merge sort misto quick sortu) ... ale do te doby bych vas poprosil, abyste netahal 10^6 prvku tam, kde se jedna o stovky.
oba jak mali, a oba mimo ;-)))
wejn: jde opravdu o 1 - 3 zaznamy (pokud nema v jeden den svatek vic jak 2 lidi), protoze predtim, jak sis jiste vsimnul, se vyberou zaznamy pouze z daneho dne.
a takovy profesionalni koder jako monsignor pichi by mel vedet, ze ani kod ktery obhajuje neni uplne koser, protoze mi prijde uplne zbytecne nejdriv si delat nove pole obsahujici pouze jmena a pak ho prohledavat.
takze asi takhle :
return vyber.inject { |memo, jmeno| memo.length > jmeno[0].length ? memo : jmeno[0] }
vyhrady k implementaci prikladu:
proc uvadet i kombinovanou podobu, kdyz ji jednoduse muzeme dostat spojenim vsech hodnot z daneho dne. ( a odpadne ono hledani nejdelsi varianty ;-))) ?
a jeste, proc muset porovnavat 2 cisla, kdyz by slo porovnavat jedno ? bud zapisovat datum jako xxyy (pokud to nechceme pouzit pro razeni, je jedno, jestli bude prvni mesic nebo den), nebo je nechat ve stejne podobe, a konverzi provadet pri nacitani (treba za pomoci metody yaml.load_documents, i kdyz to by vyzadovalo oddelit kazdou polozku) ?
No hezky, hezky :-)
Ja jsem si "v zapalu boje" ani neuvedomil, ze to bezi pres "vyber" a ne pres cely vstup. Shame on me! :)
Navic ten vas inject se da taky prepsat "lepe" (aby byl i monsignor spokojen), protoze jak jsem napsal o neco niz -- Enumerable#max bere blok:
return vyber.max { |x,y| x[0].length <=> y[0].length }
:-)
Ad spojeni hodnot: no, to mi taky nebylo jasne, ale na miste je argument s jiz existujicim formatem dat (ktery jsem dostal i na svoji pripominku ohledne pouziti jineho formatu datumu).
Ha! A ono nabizi ... jen jsem nevedel o tom, ze existuje i verze, ktera bere blok (proto jsem ju nepouzil).
Takze "nejlepsi" reseni je vlastne:
return vyber.max { |x,y| x[0].length <=> y[0].length }coz uz by se mohlo zamlouvat vsem, huh? :)
(mimochodem je nejrychlejsi z tech 3)