# challenge от Macro-vision

Тема в разделе "WASM.HEAP", создана пользователем kaspersky, 2 июн 2009.

Статус темы:
Закрыта.
  1. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    короче, subj. мыщъх насчитал в задании 13 ошибок (не грамматических). кто больше? кстати, это же задание они мне еще год назад присылали. такое впечатление, что у них оно одно на всех ;) послал им ответ в виде трех строк на си ;)

    Write a function to remove C and C++ comments from an input string while leaving all other data intact.

    For performance reasons, your function should not allocate memory, must handle even very long strings, and must be written in standard C. If library calls are used, they must be present in the standard C library (both Microsoft and UNIX). C-style comments can span multiple lines.

    Function prototype:
    void removeComments(char *str)
    {
    }


    Assume allocation and deallocation of the string buffer str is handled by the caller, and that the string is terminated by '\0'

    Assume the string is ASCII.

    The source code of a legitimate C or C++ program, which compiles with no errors, should still compile with no errors after it has been processed by your function.

    Example input:
    Example C comment:
    /*
    * Comments start with /* and end with the opposite
    * (// is for C++ comments)
    */
    Example C++ comment:
    // C++ style comment
    // Another comment, can only be one line, unless terminated by \
    as in this case
    const char* url = "http://www.macrovision.com";
    char quote = '\'';


    Example output:

    Example C comment:

    Example C++ comment:


    const char* url = "http://www.macrovision.com";
    char quote = '\'';


    Bonus question:
    What does your function do with the following line of code?
    #define join(a,b) a/**/b
    Is this correct?
     
  2. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    минут десять уже сижу перед заданием, в голове давно сложилось и уложилось в несколько строк решение, в нём нашлось и исправилось несколько ошибок, но в самом задании ничего я так и не увидел .\

    интуиция подсказывает, что код, предоставленый в нём слишком мал, чтобы содержать такое количество ошибок, укажи хотя бы одну ?
     
  3. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    Comer_
    > интуиция подсказывает, что код, предоставленый в нём слишком мал,
    > чтобы содержать такое количество ошибок, укажи хотя бы одну ?
    void removeComments(char *str)

    вопрос: что будет если: removeComments("/* /* */ */");?
    си-комменты не могут быть вложенными (по стандарту), а нарушать стандарт нам вроде бы как не разрешали и мы должны вернуть ошибку. ну и как ее вернуть? не, ну вообще-то, если извратиться, то можно сделать *str = 0; т.е. "убить" строку, сигнализировав этим об ошибке ее разбора. но готов ли к этому материнский код? да и в спецификации на функцию об этом ничего не сказано... но даже если бы там был не void, а int, то все равно - не сказано в каком состоянии оставлять строку, если мы не можем продолжить ее разбор? обнулять ее или оставлять в неопределенном состоянии?

    бонусный вопрос: хз. какого ответа от нас требуют. по новому страндарту /**/ заменяется препроцессором на пробел, а для склеивания юзается ##. но во времена ветхозаветного си все было не так и это был такой трюк юзать /**/ для склейки в макросах.

    по умному: функция должна заменять /* - - - - */ на пробел, а встретив /**/ выдавать варнинг, ну или должен был ключ типа опции. или она должна детектить что это за прога. например, если прототипы функций объявлены в "дореволюцинном" стиле, то /**/ это склейка и после замены ее проблем все рухнет нахр.

    короче, ответ: по всему ясно, что в данном примере следует заменять /**/ на пробел, но это противорчечит новому завету и потому прежде чем это делать, нужно убедиться, что мы имеем право применять старый завет ;)

    кстати, ничего не сказано о поддержке переносов строк. MS-DOS? UNIX? Mac? все три поддерживать показывая свою эрудицию? в задании сказано - удалять комменты оставляя остальные данные не тронутыми. и тут с С++ комментариями выходит затык. неясно что делать с переносами. удалять их тоже или нет?
    возьмем ситуацию:
    int a; // this is a
    int b; /* this is b */

    если мы удалим перенос за //, то у нас получится int a; int b; что вообще-то работает, но данные оказались грязно полапаны. по уму нужно удалять перенос только если строка начинается с коммента (ну я так сделал), но опять-таки где это отражено в спецификации задания?!

    ладно бы дали голый прототип, а остальное типа думайте сами. так ведь нет - мелочи типа кто аллоцирует память и что строка завершается нулем они упоминают (когда это и так очевидно), а по настоящему критичные для реализации вещи - думай сам. кстати, опять не ясно, что им надо. если писать быстро, то мы получаем "красивое" и элегатное решение.

    while((p = find_start_of_comment(p, &type_of_comment)))
    if(pp = find_end_of_comment(p, type_of_comment))
    len = strlen(pp), memmove(p, pp, len), *(p + len) = 0;

    но оно ж тормозит как асфальтовый каток! а по хорошему писать надо во-первых, временно преобразуя строку к паскаль типу (в смысле хранить ее длину, забив на завершающийся ноль) и копировать в два прохода. сначала мы запоминаем начало/конец комментов, а затем их копируем. но для этого нужна память. а память нам выделять запрещено. ну тут все равно можно выкрутиться, но как ни крутись, а производительность все равно будет уже не та... а нас сразу ткнули носом - типа в целях производительности...

    короче вот такое задание. не спорю - внешне простая на вид штучка раскрывает человека на все 100%. насколько он глубоко знает си и как умеет решать инженерные проблемы. скажем, на определенном этапе он столкнулся с тем, что прототип неверный и ошибку возвращать все-таки нужно, но менять прототип нельзя, ибо он уже много где объявляен и вообще задокументирован. поэтому приходится доходить до *str = 0; - наверное, к единственному возможному в данном случае решению.

    кстати, на решение задачи дается 24 часа. охренеть. и что же можно все эти 24 часа делать?!
     
  4. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    ответ: наше дело - убрать комменты, так что оставить мы должны " */", посчитав комментом "/* /* */"

    стандарт си вобще неопределён - взять хотя бы недоразумения с порядком поступления переменных - отчего мы и имеем три тома трюков от криса )

    в самом деле неожиданность. но если бы опции было три (т.е. без "i choose not to choose life"), я бы выбрал CRLF, т.к. в основном он проявляет себя как наиболее универсальный.

    я думаю, переносы удалять не стоит вобще, даже если у нас
    // две строки
    // подряд закомменчены


    даа, задачка в самом деле интересная как ни глянь )
    спасибо за неё, буду подсовывать хакерам всяким разным .)

    ну, вот я последние.. восемь часов себя заставляю докодить этот кработрой противный, так что всякое бывает )
     
  5. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    Comer_
    > ответ: наше дело - убрать комменты, так что оставить мы должны " */",
    > посчитав комментом "/* /* */"
    ??? мсье, вы серьезно ???
    я бы еще понял, если бы вы решили вопрекри стандарту поддержать вложенные комменты убрав их полностью. но оставить кусок последнего комента это ж ни в какие ворота не лезет. тем более, что там сказано не убрать /* */ и '//', а C/C++ коменты, имеющие четкое определение.

    > стандарт си вобще неопределён
    стандарт тумаен местами. и кучу вещей оставляет на откуп реализаторам. но это в целом и общем. а в данном конкретном случае он предельно конкретен. коммент заменяется пробелом. и точка.

    > взять хотя бы недоразумения с порядком поступления переменных
    ну да. то есть нет. то есть это вообще мы уходим в перпендикуляр. если вы имеете ввиду порядок вычисления выражений при передаче их функции, то тут действительно - как компилятору удобнее. ну и что с того? если нужно задать четкий порядок - ну так его и можно задать ;)

    > в самом деле неожиданность. но если бы опции было три
    > (т.е. без "i choose not to choose life"), я бы выбрал CRLF,
    > т.к. в основном он проявляет себя как наиболее универсальный.
    угу. но вот только там упомянут юних. а значит, могут взят гнусь и проверить наш пример. на юниковых же строках. ну не на ms vc наше задание проверять ;) и так ясно что мы его на нем писали. я бы не стал поддерживать мак, т.к. его мало кто юзает, тем более даже не сам мак, а его стандарт строк, который уже не стандарт. но решил таки выпендриться и поддержал. но там еще другая проблема. в принципе никто не мешает засунуть в программу строку с любой комбинацией символов типа 0xD 0xA 0xA - почему нет? и как программа должна на них реагировать? кстати, чисто практическая задача. при работе с разными редакторами (типа вынь и никс) иногда возникает гадость в виде 0xD 0xA 0xA, но если она начинается с первой строки, то умные редакторы с ней справляются. а если же наша программа при удалении комментов оставит скажем 0xA, то редакторы обламаются. конечно, это уже из области частностей, но... если мы пишем коммерческое приложение, а макровижен не опен-соурсе разрабатывает, то мы должны учитывать все риски, включая эти. и при решении задания неплохо показать, что мы хорошие инженеры ;)

    > я думаю, переносы удалять не стоит вобще, даже если у нас
    > // две строки
    > // подряд закомменчены
    я думал над этим. потом счел, что в си++ комменте перенос все-таки является частью самого коммента. стандарт на этот счет ничего не говорит, ибо потому как перенос приравнивается к пробелу, так что все пучком. но как-то не красиво это выглядит когда мы оставляем кучу переносов. подумав немного, я их убрал, оставив перенос только в том случае, когда перед коментом что-то есть. даже напрягся и поддержал обработку ситуации когда есть только ; или табуляции или проблелы. в этом случае перенос так же убивается, хотя от меня этого никто и не требовал.

    > даа, задачка в самом деле интересная как ни глянь )
    макровижин вообще интересная фирма.

    > спасибо за неё, буду подсовывать хакерам всяким разным .)
    а потом тут люди грят, что я зря трачу время на собесодованиях и интервью. а вот я уверен, что не зря. потому как учусь ;) интересно же задачи решать! и тем более это ведь не экзамен, где нет квоты. это ближе к олимпиаде, где таки нужно решать кому дать место N, а кому N+M, где M не равно нулю ;) только в отличии от олимпиад, здесь нет понятия "блата" и "своих людей, которых нужно протащить", ну то есть не то, чтобы совсем нет, но в очень незначительной степени.

    > ну, вот я последние.. восемь часов себя заставляю докодить этот кработрой противный,
    > так что всякое бывает )
    ну я решал задание слушая музыку, читая эротическую новеллу "the toy", фикся баги в генераторе сигнатур для Snort, отвечая на письма, туссуясь здесь на форуме ну и листая документацию по арму. обложился четырьмя мониторами. оччень удобно. на одном - худ. литература, на другом - документация... и все это можно читать _раком_
     
  6. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    куда делось редактирование?! читать не раком, конечно, хотя конечно и раком тоже, а _разом_, но я о другом. мы тут упустили очень важный момент. в задании было сказано:

    The source code of a legitimate C or C++ program, which compiles with no errors, should still compile with no errors after it has been processed by your function.

    при попытке скормить компилятору /* /* */ */ мы получим егор такой-то и все - компилить не желаю. означает ли это, что проблема вложенных комментов тут не стоит? вопрос важный. если задание сформулировано правильно и мыщъх только хвостом махает, то это мыщъх тупой. так вот, мыщъх не тупой. программа может компилироваться ANSI компилятором и имееть вложенные комменты, но при этом разваливать наш парсер, если он сделан без их учета.

    плюс. еще одна недоговоренность постановки задачи. если источник данных - легитимная си/си++ программа, то в ней наверное могут быть и директивы условной компиляции, верно? они же легитимны!
    а что делать если:

    #undef hell
    #ifdef hell
    "
    "/*
    #endif

    main()
    {
    /* hi! I'm a c-comment, but I will survive, he-he! */
    // hi! I'm a c++ comment, but I will survive as well

    printf("hello, world!\n");
    }

    #ifdef hell
    */
    #endif


    кстати, проверьте программы синтаксической раскраски ;) они с ума сходят (которого у них нет)
     
  7. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..

    ну я решал задание слушая музыку, читая эротическую
    новеллу "the toy", фикся баги в генераторе сигнатур для
    Snort, отвечая на письма, туссуясь здесь на форуме ну
    и листая документацию по арму. обложился четырьмя
    мониторами. оччень удобно. на одном - худ. литература,
    на другом - документация... и все это можно читать _раком_
    это ужасно! я же завидую! .D

    ??? мсье, вы серьезно ???
    я бы еще понял, если бы вы решили вопрекри стандарту
    поддержать вложенные комменты убрав их полностью.
    но оставить кусок последнего комента это ж ни в какие
    ворота не лезет. тем более, что там сказано не убрать /* */
    и '//', а C/C++ коменты, имеющие четкое определение.

    ну а почему? компилятор бы это распознал именно так.
    тенболее нам сказали - "если конпилилось до обработки - должно и после", а до обработки такой код не стал бы конпилиться.

    если вы имеете ввиду порядок вычисления выражений при передаче
    их функции, то тут действительно - как компилятору удобнее.

    угу, к примеру вот оно.

    ну и что с того? если нужно задать четкий порядок - ну так его и можно задать ;)
    да в принципе ничего, просто таких неопределённостей в языке хватает, тут и получается - выпендрился где то с while(!function(failed)&&retries++<10){ ... }, порадовался, а через пару месяцев возникают аномалии в связи с переездом на конпилер, и половину "хитрого" кода приходится переписывать.
    что уж говорить о языках, если неопределённости есть даже в процессорах.

    > я думаю, переносы удалять не стоит вобще, даже если у нас
    > // две строки
    > // подряд закомменчены
    я думал над этим. потом счел, что в си++ комменте
    перенос все-таки является частью самого коммента

    ну давай судить логически(мы ж ведь программеры .D):
    вот у нас пустая строка, и строка со строчным комментом:
    32¦ ...

    33¦ return 0;
    34¦ }

    35]
    36] // kaka makaka
    37¦ int main(int,char**){

    38¦ ...

    чем они различны?
    обе имеют начало, обе завершаются CR(предположим).
    то есть комментарий по сути находится межу CR и CR, и вырезать мы должны только его, всё остальное - уже "наведение марафета".

    <щас будет девятичасовой бред>
    то есть, если действовать по противному методу, мы должны либо удалять перенос после строки,
    либо до строки, а прописывание проверок гипертрофируется в изобретение искусственного интеллекта
    </бред>
     
  8. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    мы тут упустили очень важный момент.
    я не упустил ¦)

    а что делать если:

    #undef hell
    #ifdef hell

    вот честное слово - об этом я подумал сразу же)
    но потом решил что к вопросу о дефайнах можно приставить вопрос о результатах их сравнений, а там уже и написание компилятора, и изобретение ИИ не за горами)

    да и к тому же - лучшая стратегия - действовать так, как действует компилятор.
    тем более, нам намекнули, что так оно и должно быть, когда говорили об успешных компиляциях исходника и результата.
     
  9. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    Comer_
    >> на другом - документация... и все это можно читать _раком_
    > это ужасно! я же завидую! .D
    разом ;) а не раком ;)

    > ну а почему? компилятор бы это распознал именно так.
    > тенболее нам сказали - "если конпилилось до обработки - должно и после",
    > а до обработки такой код не стал бы конпилиться.
    я только что отпостил по этому поводу (см. выше)

    > да в принципе ничего, просто таких неопределённостей в языке хватает,
    > тут и получается - выпендрился где то с while(!function(failed)&&retries++<10){ ... },
    > порадовался, а через пару месяцев возникают аномалии в связи с переездом
    > на конпилер, и половину "хитрого" кода приходится переписывать.
    не понял. а что за анамалии? компилер или konpiler?
    трюки с && я и сам нещадно использую типа if (a && (flag=1)) break;
    что значит if (a) {flag=1; break;} но тока без скобок. и все работает.

    > то есть комментарий по сути находится межу CR и CR,
    > и вырезать мы должны только его, всё остальное - уже "наведение марафета".
    ну это действительно вопрос вкуса. с другой стороны, если тебе реально нужна функция для удаления комментов, то оставление большого кол-ва пустых строк - не очень красиво.

    >> щас будет девятичасовой бред
    угу. я тоже больше суток не спал. а сейчас еще буду ехать за 200 км, чтобы получить посылку от амазона. блин, 29 числа заказал книги и посылка уже пришла. оперативно однако упса работает.


    > либо до строки, а прописывание проверок гипертрофируется
    > в изобретение искусственного интеллекта
    ну что-то вроде ;)
     
  10. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    это всё сайтех виноват! компилятор имелся в виду )
    ибо на разных компиляторах получается разный код.

    да не тому я завидую!! XD
     
  11. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    в смысле в случаях со всяческими ухищрениями и трюками .)
     
  12. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    Comer_
    > вот честное слово - об этом я подумал сразу же)
    > но потом решил что к вопросу о дефайнах можно приставить вопрос о результатах их
    > сравнений, а там уже и написание компилятора,
    все проще ;) дефейны идут лесом. мы их ставим в игнор. а вот конструкт вида
    "
    "/*

    по любому являет собой ошибку. она не проявляется на первом проходе препроцессора когда удаляются комментарии, а на втором проходе удаляются мертвый код и потому программа компилится. и тот факт, что транслятор не выдает ошибку не делает ему чести ;)

    конечно, это уже _совсем_ кромешный изврат, но по любому функция должна уметь возвращать ошибку.

    и еще одно соображение. даже если в спецификации функции указано, что к ней на вход поступает валидная си программа, это не значит, что так будет всегда в реальном мире. и не потому что какой-то придурок обязательно педераст невалидную программу (если так рассуждать, то и закладываться на то, что строка завершается нулем тоже нельзя), просто
    всякий более-менее сложный парсер не гарантирован от наличия ошибок в нем самом и потому дополнительный уровень контроля зачастую спасает людям жизнь ;)
     
  13. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    Comer_
    > да не тому я завидую!! XD
    вообще-то мониторов семь (в одной комнате :derisive:, но только пять из них включены, и на пятом сейчас бегает заставка S2K3, ну и отображается температура в комнате, так что он не в счет.

    а чего завидовать? парк техники у меня более чем скромный. самый быстрый компьютер 3.2ГГц. и памяти: на одном 512 мб, на других по 1 или 2 гб. дискового пространства правда много (счет идет на террабайты), ну а так - все очень дешевое. просто действительно удобно с мониторами. переключаться между окнами - это же сколько времени терять...
     
  14. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    ^_____________________________^ ыы+) пардон, не сдержалса)
     
  15. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    varnie
    опс. вот что значит делать сто дел сразу и нихуа не спать. (хорошо хоть не сказал "не с*ать :derisive:, ну не педераст, а передаст.
     
  16. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    kaspersky
    При всём уважении, но по-моему ошибки высосаны из пальца. Конечно чувствуется практик и хороший специалист, но многие вещи подразумеваются по умолчанию и не стоит искать того чего нет.
     
  17. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    kaspersky
    раком, педераст..
    поспал бы, ато мало ли .D
     
  18. nobodyzzz

    nobodyzzz New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2005
    Сообщения:
    475
    >кстати, проверьте программы синтаксической раскраски ;) они с ума сходят (которого у них нет)
    vim почти корректно все раскрасил, вот если удалить кавычки в conditianal блоке, то тогда да сходит с ума =)
    [​IMG]
     
  19. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    Booster, "если в коде нет ошибки - ищи ошибку" .)
    хорошо когда сразу видишь слабые места программы, а не собираешь с сотни машин отчёты о мемори-ликах и бсодах.
     
  20. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Бесконечный алгоритм.
     
Статус темы:
Закрыта.