PŘEVOD ČÍSLA

    1. Zadání

    Vytvořte program, který načte číslo ze standardního vstupu v soustavě se základem Z1 a převede jej do soustavy se základem Z2.

    2. Technická specifikace

    Vytvořte platformě nezávislou aplikaci, která načte vstupní výraz ve formátu [XXX]Z1=Z2, Kde XXX je libovolná (libovolné dlouhá, i několik gigabajtů) posloupnost znaků 0-9 případně A-Z přípustných pro číselnou soustavu se základem Z1. Z2 je soustava, do níž má být načtené číslo převedeno a vypsáno na standardní výstup. Základy soustav Z1 a Z2 mohou byt od 2 až po 36 (znak reprezentující hodnotu 35 bude Z)

    Příklad vstupního souboru:

    [1012222121310101]4 = 32

    Takové číslo uvedené mezi [] reprezentuje hodnotu ve čtyřkové soustavě (soustavě se základem 4) a má se převést do soustavy se základem 32.

    Program si nemůže vytvářet žádný dočasný soubor a nemůže se v souboru pohybovat jinak než sekvenčním načtením tohoto souboru pomocí funkce read.

    Program musí být vytvořen v jazyce ANSI C (ne C++). Ze systémových volání nebo knihovních funkcí může používat pouze funkce read, write, malloc, free. Žádné jiné funkce nejsou povolené (žádné fread, fwrite, getchar, realloc ...).

    3. Vstup

    Vstupem je soubor s výrazem [číslo] z1 = z2, který bude přesměrován na standardní vstup.

    4. Výstup

    Výstupem je číslo v soustavě se základem z2 ve formátu [číslo] z2.

    5. Hodnocení

    Hodnotit se bude funkčnost, efektivnost (rychlost běhu i paměťové nároky), přehlednost kódu a dokumentace.

    6. Referenční implementace

    Pro ty, co si myslí, že úloha je snadná, přikládáme testovací soubory i s časem, který dosáhla referenční implementace vytvořená společností ESET. Zájemce, kteří realizují převod pomocí nejznámějšího způsobu, postupným dělením převáděného čísla základem soustavy do níž se číslo převádí, bychom chtěli upozornit, že tento algoritmus má složitost n^2. Což znamená, že již převod čísla s počtem číslic 100.000 (sto tisíc) bude pro ně výkonově velmi náročný. Referenční implementace dosáhla při převodu tohoto čísla čas 0,026 s. Což je 26 tisícin sekundy.

    Referenční implementace využívala jen jedno jádro procesoru. Vzhledem k povolenému API ani není možne využít paralelizace. Tato referenční implementace nebude figurovat ve výsledném žebříčku. Uvítáme i řešitele, jejichž řešení dokáže v rozumném čase (do hodiny) převést číslo s 100.000 číslicemi. Zájemce o tablet však bude muset poslat řešení, které dokáže převést i číslo s jednou miliardou číslic.

    Parametry testovacího prostředí:

    • CPU: Intel Core i5 2,67 GHz
    • RAM: 4GB
    • OS: Linux x86_64

    Tabulka s časy, kterých dosáhla referenční implementace s:

    file time  
    10.000 digits (4.29KB) 0,005s Result (4.22KB)
    100.000 digits (42.1KB) 0,026s Result (41.47KB)
    1.000.000 digits (420KB) 0,274s Result (414KB)
    10.000.000 digits (4.1MB) 4,526s Result (4.04MB)
    100.000.000 digits (41.0MB) 73,527s Result (40.44MB)
    1.000.000.000 digits (410MB) 1078,013s Result (405MB)

     

    PS: Referenční implementaci lze překonat i při použití známých algoritmů, nechali jsme vám rezervu;).

    Nápověda:
    google: modern computer Arithmetic
    Kapitola o převodu mezi soustavami není ta nejpodstatnější v případě, že chcete být nejrychlejší.

    Vaše postřehy /analýzy/ řešení zasílejte na následující adresu: numbertransfer@eset.sk

    Výsledky

    Vítěz: Matej Fajnor

    Pro určení pořadí v tabulce se nepoužívají zveřejněné soubory ale jiné. Provádí se ze soustavy, jejímž základem je prvočíslo a převod je také do soustavy, jejímž základem je prvočíslo. Z toho důvodu uvádíme i rychlost referenční implementace. Referenční implementace ale nezasahuje do výsledného pořadí. Do tabulky nebyly zařazeny řešení, které nedodržují specifikaci (používají i jiné systémové volání/ knihovní funkce než povolené read, write, malloc a free, využívají knihovny třetích stran, připadne, nerespektují formát vstupu a výstupu.

    Jméno Verze 1.000 10.000 100.000 1.000.000 10.000.000 100.000.000 1.000.000.000
    Referenční implementace 1 0.004 0.026 0.033 0.262 3.741 62.686 898.383
    Matej Fajnor10.0020.0240.1181.42517.795246.9635374.21
    Jan Katrenic50.0050.0310.2423.10437.631598.06813222.586
    Timotej Stanek20.0230.0510.7217.69494.0781031.204SF
    Jan Katrenic30.0060.0470.3414.22961.8031160.743 
    Jan Kacer20.0020.0150.2165.147156.5893611.415 
    Jan Sugarek50.0040.0360.2475.288150.8084361.096 
    Jan Sugarek40.0040.0190.02918.636317.90811874.927 
    Martin Durkac50.0520.0620.3211.044936.653  
    Marian Repasan30.0040.0240.62834.7041675.387  
    Viliam Simovic20.0120.1664.967127.0284256.086  
    Dusan Durech20.0030.0341.361133.68713300.918  
    Lukas Slebodnik10.0230.0521.77174.333   
    Peter Ertl20.0030.0473.409338.441   
    Martin Durkac30.0120.21818.7841883.973   
    Martin Durkac40.0420.0670.49SF   
    Ondra Gersl10.0140.54953.7545352.113   
    Peter Laszlo10.0150.6765.6936637.302   
    Zsitva Tibor10.0261.267126.419    
    Juraj Kavka10.0332.423242.694    
    Jaroslav Tobik10.0463.64745.527    
    Lukas Bejda13.713>1800     
    Martin Durkac1>600      
    Martin Durkac2>600      

     

    Druhá tabulka obsahuje řešení, jejichž časy byly změřeny, avšak vyžadovaly úpravu ze strany ESET-u z důvodů uvedených v posledním sloupci. Řešení jsou seřazeny sestupně podle jména řešitele.

    Jméno Verze 1.000 10.000 100.000 1.000.000 10.000.000 100.000.000 1.000.000.000 Problém
    Cseke Gabriel10.0140.14413.02SF   Špatný parsing + segmentation fault
    Jan Niznansky10.041.804180.314SF   Špatný parsing + segmentation fault
    Lukas Bejda20.18816.901     Špatný parsing
    Lukas Judicak20.0130.42240.567    Špatný parsing
    Martin Ludvik20.004ZV     Špatný parsing + segmentation fault
    Martin Tkacik10.0371.061105.039    Špatný parsing
    Michal Puheim10.0331.231122.056    Nepovolené funkce
    Michal Repisky10.0120.49736.808    Špatný parsing
    Milos Stofa10.0210.0210.1551.6922.268ZV Poslední výsledek je chybný
    Milos Stofa20, 0030.0310.1461.69423.016471.164Not testedChyba pri malých císlech - segmentation fault
    Peter Fabian10.0120.35329.763    Chyba pri malých císlech - segmentation fault
    Peter Zarnay1       Nesplnena specifikace, nepovolené funkce, nacítání není rešeno pres standardní vstup, napevno zadaná délka vstupního retezce
    Pool10.0170.0310.4875.53661.0521218.761 Chyba pri malých císlech - segmentation fault
    Samuel Brezani20.0040.0230.93688.592   Špatný parsing
    Tomáš Kuzma10.0070.0582.332223.178   Špatný parsing