Aktualizace:
- update: výsledky
- update6: Tomáš Kořínek
- update5: J. Jelínek a jeho třetí pokus.
- update4: aktualizace pořadí, změna na možnost 3 řešení, průběžné výsledky jsou zpět
- update3: podle návrhu udělím i cenu za nejoriginálnější řešení - i když nebude nejrychlejší - něco jako minule cena poroty. Jako podporu pro zasílání i krapet pomalejších řešení.
- update2: další soutěžící
- update: vylepšené měření, můj druhý pokus, dva další soutěžící
Od minulé soutěže mi už otrnulo a jelikož převážná většina lidí v anketě nebyla proti dalšímu kolu soutěže a do jara ještě chvilku máme čas, je zde další úkol.
Proti minulému kolu jsem změnil několik pravidel:
- je možno použít libovolný kompilátor pascalu (Delphi 2 - Delphi XE, FreePascal, ohledně C++Builderu zatím nevím zda by byl zájem)
- testované budou výsledné Vámi přeložené aplikace (minule jen jedna obsahující všechny řešení), zdrojový kód je jen pro kontrolu vítězů
- průběžně budou zveřejňovány přeložené aplikace, zaslané zdrojové kódy budou zveřejněny nakonec
- výsledné pořadí bude určeno během na 2 jádrovém Core 2 Duo (Thinkpad R400) na XP SP3
- v případě stejných výsledků rozhoduje zajímavější řešení, rozhodne porota ve složení Já, Já a Já
- můžu se tím pádem zúčastnit i já (bez nároku na výhru - doufám, že skončím aspoň v první polovině pole)
- co se bude dít mezi označenými místy kódu je úplně na Vás - dostanete vstupní data a na výstupu musí být naplněno pole počtů. Můžete použít i vlákna nebo si předat vhodně data. Žádná pravidla. Jen musí být data vypočítána programem (výsledný běh bude nad kapánek jinými daty)
- Pro určení pořadí bude rozhodující minimální čas ze 40 vyvolání soutěžní části programu. Při každém vyvolání musí být výsledky vypočítány samostatně bez návaznosti na předchozí nebo následující výpočty. Výpočty z různých vyvolání nemohou běžet paralelně. Opakované vyvolání je jen pro zpřesnění měření a program se musí chovat stejně i při pouhém jednom opakovaní.
- lze poslat max. 3 řešení (změna: dříve bylo 2 řešení)
- není povoleno manipulování s měřením času (jako přeprogramování časovače, patchnutí volání API funkce atd.)
- program dávající špatné výsledky je vyřazen
- konec 28.2.2011 ve 22:00 (tj. tři týdny)
- na výhru není právní nárok :-)
Doufám, že se pobavíte stejně jako já.
Zadání
Níže uvedený program vygeneruje testovací data (nejsou to ale data, která budou použita pro výsledný test) - jejich velikost zhruba odpovídá, formát bude přesně stejný. Jedná se o textový neunicode soubor, obsahující na každém řádku (konec řádku je CRLF) jeden z 20 tagů, případně jeho ukončovací variantu. Ukončovací varianta, tj. </xxxxxxx se bude ignorovat a nezapočítává se do výsledku.
generator.zip - program pro vygenerovaní vstupních dat - generování trvá několik sekund :-D
Ukázka výsledného souboru:
</body>
</strong>
<li>
</ul>
<div>
<head>
<head>
</head>
<td>
</em>
</html>
</tr>
Cílem je do připraveného pole spočítat jednotlivé výskyty.
- Ukončovací varianta, tj. </xxxxxxx se bude ignorovat a nezapočítává se do výsledku.
- Je garantováno, že nejsou jiné než povolené řetězce, tj. obsahem vstupního souboru je jen povolená množina tagů. (viz. řádky 15 - 18), můžete na to spoléhat (viz generátor).
- Základní kostra pro pascal je součástí zadání (sorry pro uživatele C++Builderu, ale pokud se chcete zúčastnit, můžete mi poslat kostru pro C++Builder)
Např. v uvedeném příkladu se bude jako první počítat <li>.
kostra.zip - základní program, zajistí načtení dat z data.bin (získáno generátorem nebo ručně), výpočet času a výpis výsledků. Mezi řádky 34 a 38 je Vaše hrací pole. Výsledek bude v aiCount, nulování není kostrou zaručeno. asData je množina povolených tagů, jejich pořadí a texty se nesmí a nebudou měnit, tj. můžete na to spoléhat.
Na návrh diskutujících (Pepák a anonym) byla upravena kostra - používá se nyní QueryPerformanceCounter a minimum ze 40 běhů.
program Soutez;
{$APPTYPE CONSOLE}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
{$STRINGCHECKS OFF}
{$INLINE ON}
{$O+}
{$R-}
uses
Sysutils,
windows,
classes;
const
ciCount = 20;
asData : array [1..ciCount] of string =
('<body>', '<head>', '<html>', '<p>', '<table>', '<li>', '<ul>', '<div>', '<img>', //9
'<td>','<tr>', '<h1>', '<h2>', '<h3>', '<h4>', '<a>', '<em>', '<strong>',
'<code>', '<pre>'); //20
var
aiCount: array [1..ciCount] of integer;
const
LOOP_COUNT = 40;
var
pData: PByteArray;
f: TFileStream;
tick, tickend, frequency: Int64;
sOut:string;
x: Integer;
Loops: integer;
CurTime, TotalTime, MaxTime, MinTime: DWORD;
begin
f:= TFileStream.Create('data.bin', fmOpenRead );
try
GetMem(pData, f.Size);
f.Read(pData^, f.Size);
TotalTime := 0;
MaxTime := 0;
MinTime := $ffffffff;
for Loops := 1 to LOOP_COUNT do
begin
QueryPerformanceFrequency(frequency);
QueryPerformanceCounter(tick);
// zacatek souteze, predavani je zalezitosti programatora
// v pData jsou data
// zde si muzete hrat
QueryPerformanceCounter(tickend);
// konec souteze
CurTime := Round(1000*(tickend - tick)/frequency);
Inc(TotalTime, CurTime);
if CurTime < MinTime then
MinTime := CurTime;
if CurTime > MaxTime then
MaxTime := CurTime;
end;
writeln(format('Autor: Radek Červinka, kompilator:%f', [CompilerVersion]));
writeln(Format('Last time = [%d]', [CurTime]));
writeln(Format('Min time = [%d], Average time = [%d], Max time = [%d]',
[MinTime, TotalTime div LOOP_COUNT, MaxTime]));
for x := 1 to 20 do
Writeln(Format('%s = %d', [asData[x], aiCount[x]]));
FreeMem(pData);
finally
FreeAndNil(f);
end;
end.
Ceny
Hraje se na první místo dle času výpočtu. Pokud by se náhodou nedejbože stalo, že bych byl první (čemu ale opravdu nevěřím), cenu dle svého výběru získává druhý v pořadí.
Výběr je následující (jedna z variant + PDF verzi delphi.cz):
- 3x hrneček s logem Borland (archeologické kousky - ale je opravdu kvalitní a má tu správnou velikost na kafe - ideální do výbavy pro manželství)
- nebo vázanou knihu Delphi v kostce (1-5) (úplně nová)
- nebo epesní šiltovka s logem Embarcadero a uvedený hrneček
Poznámky
Osobně jsem použil Delphi 2007, v této úloze generuje zhruba stejně rychlý kód jako Delphi XE, jen je výsledné exe kratší.
Výsledné exe + zdrojové kódy mi zašlete a já Vám potvrdím přijetí. Pro antivirový test můžete použít virusscan.jotti.org.
Pořadí
Pro informaci: měření jsou na mém Core2Duo T8100 @ 2.10GHz.
Program očekává v adresáři patřičné vstupní data - viz generator.zip.
Výsledky jsou v samostatném článku.