Re[3]: Программист в стартап $1500-3500
От: LuciferMoscow Россия  
Дата: 17.06.07 15:24
Оценка:
Здравствуйте, Правдоруб, Вы писали:

aqt>>Особенно понравились выделенные фрагменты, которые Вы советуете взять на вооружение. Так держать!

П>Заголовок там звучит как
А то, что бывают разные кодировки Вы слышали?!
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[2]: Программист в стартап $1500-3500
От: WolfHound  
Дата: 17.06.07 21:13
Оценка:
Здравствуйте, machine3000, Вы писали:

M>Если не в лом, гляньте на сколько бачей примерно автор кода у вас бы потянул.

Ради интереса переписал на немерле
Забирает данные из stdin, отдает в stdout, дебужную информацию и ошибки пишет в stderr
using System;
using System.IO;
using System.Collections.Generic;
using SCG = System.Collections.Generic;

using Nemerle.Collections;
using Nemerle.Utility;
using Nemerle.Text;

public class Converter
{
    [Record]
    class Unit
    {
        public Name : string;
        public Weight : double;
        public Cluster : Cluster;

        public override ToString() : string
        {
            $"Unit($Name, $Weight)";
        }
    }

    class Cluster
    {
        private _units : Hashtable.[Unit, byte] = Hashtable.[Unit, byte]();
        public Units : SCG.ICollection.[Unit]
        {
            get { _units.Keys; }
        }
        public Add(unit : Unit) : void
        {
            _units.Add(unit, 0);
        }
    }

    public Add(weight : double, name : string, weightTo : double, nameTo : string) : void
    {
        WriteLine($"$((weight, name, weightTo, nameTo))");

        def doubleEq(d1 : double, d2 : double)
        {
            def d = d1 - d2;
            if (d < 0)
                d >= -double.Epsilon;
            else
                d <= double.Epsilon;
        }
        def addUnit(name, cluster, weight)
        {
            def unit = Unit(name, weight, cluster);
            _unitNameToUnit[name] = unit;
            cluster.Add(unit);
        }
        def mergeClusters(cluster1, cluster2, weight : double)
        {
            def merge(cluster1, cluster2, weight)
            {
                foreach (unit2 in cluster2.Units)
                    addUnit(unit2.Name, cluster1, unit2.Weight * weight);
            }
            // Заливаем единици из меньшего кластера в больший.
            // Таким образом алгоритм получается O(N*log(N)) в худшем случае.
            if (cluster1.Units.Count > cluster2.Units.Count)
                merge(cluster1, cluster2, weight);
            else
                merge(cluster2, cluster1, 1 / weight);
        }
        def weight = weightTo / weight;
        match (_unitNameToUnit.Get(name), _unitNameToUnit.Get(nameTo))
        {
        | (Some(unit), Some(unitTo)) => // Известны обе единици измерения
            WriteLine($"($unit, $unitTo)");
            if (InSameCluster(unit, unitTo))
            {
                // Если в одном кластере проверяем не протеворечит ли новое значение тому что уже есть.
                when (!doubleEq(weight, unitTo.Weight / unit.Weight))
                    throw Exception("Invalid data.");
            }
            else
            {
                // Если в разных кластерах сливаем кластеры
                mergeClusters(unit.Cluster, unitTo.Cluster, weight * unit.Weight / unitTo.Weight);
            }

        | (Some(unit), None) => // Известна одна из единиц измерения. Создаем вторую и помещаем ее в кластер первой.
            WriteLine($"($unit, None)");
            addUnit(nameTo, unit.Cluster, unit.Weight * weight);

        | (None, Some(unitTo)) =>
            WriteLine($"(None, $unitTo)");
            addUnit(name, unitTo.Cluster, unitTo.Weight / weight);

        | (None, None) => // Не известны обе единици измерения.
            WriteLine("(None, None)");
            def cluster = Cluster();
            addUnit(name, cluster, 1.0);
            addUnit(nameTo, cluster, weight);
        }

        def clusters()
        {
            def clusters = Hashtable();
            foreach (unit in _unitNameToUnit.Values)
                clusters[unit.Cluster] = 0;
            clusters.Keys;
        }
        foreach (cluster in clusters())
            WriteLine($"..$(cluster.Units)");
        WriteLine("");
    }

    public getConversionWeight(name : string, nameTo : string) : option[double]
    {
        match (_unitNameToUnit.Get(name), _unitNameToUnit.Get(nameTo))
        {
        | (Some(unit), Some(unitTo)) when InSameCluster(unit, unitTo) =>
            Some(unitTo.Weight / unit.Weight)
        | _ =>
            None()
        }
    }

    public convert(value : double, name : string, nameTo : string) : double
    {
        match (getConversionWeight(name, nameTo))
        {
        | Some(weight) => value * weight;
        | _            => throw Exception("Invaluid conversion.");
        }
    }
    
    static InSameCluster(u1 : Unit, u2 : Unit) : bool
    {
        u1.Cluster : object == u2.Cluster : object;
    }

    static WriteLine(line : string) : void
    {
        Console.Error.WriteLine(line);
    }

    _unitNameToUnit : Hashtable.[string, Unit] = Hashtable.[string, Unit]();
}

public module UnitConvertor
{
    public ReadAllLinesLazy(this text : TextReader) : SCG.IEnumerable.[string]
    {
        def loop(line)
        {
        | null =>
            ()
        | line =>
            yield line;
            loop(text.ReadLine())
        }
        loop(text.ReadLine())
    }
    public Main() : int
    {
        System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo("");
        def process(input : TextReader, output : TextWriter)
        {
            def converter = Converter();
            def processLine(line)
            {
                def writeResult(w1, n1, w2, n2)
                {
                    output.WriteLine($"$w1 $n1 = $w2 $n2");
                }
                regexp match (line)
                {
                // Ищем строку вида "1 day = 24.0 hour"
                | @"\s*(?<w1>\S+)\s+(?<n1>\S+)\s*=\s*(?<w2>\S+)\s+(?<n2>\S+)\s*" =>
                    match (w1, n1, w2, n2)
                    {
                    | (w1, n1, "?", n2) =>
                        def w1 = double.Parse(w1);
                        def w2 = converter.convert(w1, n1, n2);
                        writeResult(w1, n1, w2, n2);
                    | ("?", n1, w2, n2) =>
                        def w2 = double.Parse(w2);
                        def w1 = converter.convert(w2, n2, n1);
                        writeResult(w1, n1, w2, n2);
                    | (w1, n1, w2, n2) =>
                        converter.Add(double.Parse(w1), n1, double.Parse(w2), n2);
                    }

                // Пропускаем пустые строки
                | @"\s*" => (); 

                // Ругаемся на строки не подходящие под шаблон
                | _ => throw Exception("Invalid input.");
                }
            }
            mutable lineNumber = 0;
            foreach (line in input.ReadAllLinesLazy())
            {
                try
                {
                    ++lineNumber;
                    processLine(line);
                }
                catch
                {
                | ex is Exception =>
                    throw Exception($"Error ta line $lineNumber", ex);
                }
            }
        }

        try
        {
            process(Console.In, Console.Out);
            0;
        }
        catch
        {
        | ex is Exception =>
            Console.Error.WriteLine(ex);
            -1;
        }
    }
}

stdin
1 day = 24.0 hour 
60 minute = 1 hour 
10.0 glob = 1 decaglob
1000 msecond = 1 second 
1.0 gigaglob = 1000 megaglob
1.0 kiloglob = 1000 glob
1000 kiloglob = 1 megaglob
1 minute = 60 second 
1 hour = 3600 second 

2 hour = ? second
? hour = 86400 second
1 day = ? second
000.001 day = ? msecond

20.0 glob = ? decaglob

? gigaglob = 100000000000 decaglob

stdout
2 hour = 7200 second
24 hour = 86400 second
1 day = 86400 second
0.001 day = 86400 msecond
20 glob = 2 decaglob
1000 gigaglob = 100000000000 decaglob

stderr
(1, day, 24, hour)
(None, None)
Unit(day, 1), Unit(hour, 24)

(60, minute, 1, hour)
(None, Unit(hour, 24))
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440)

(10, glob, 1, decaglob)
(None, None)
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440)
Unit(glob, 1), Unit(decaglob, 0.1)

(1000, msecond, 1, second)
(None, None)
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440)
Unit(glob, 1), Unit(decaglob, 0.1)
Unit(msecond, 1), Unit(second, 0.001)

(1, gigaglob, 1000, megaglob)
(None, None)
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440)
Unit(glob, 1), Unit(decaglob, 0.1)
Unit(msecond, 1), Unit(second, 0.001)
Unit(gigaglob, 1), Unit(megaglob, 1000)

(1, kiloglob, 1000, glob)
(None, Unit(glob, 1))
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440)
Unit(glob, 1), Unit(decaglob, 0.1), Unit(kiloglob, 0.001)
Unit(msecond, 1), Unit(second, 0.001)
Unit(gigaglob, 1), Unit(megaglob, 1000)

(1000, kiloglob, 1, megaglob)
(Unit(kiloglob, 0.001), Unit(megaglob, 1000))
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440)
Unit(glob, 1), Unit(decaglob, 0.1), Unit(kiloglob, 0.001), Unit(gigaglob, 1E-09), Unit(megaglob, 1E-06)
Unit(msecond, 1), Unit(second, 0.001)

(1, minute, 60, second)
(Unit(minute, 1440), Unit(second, 0.001))
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440), Unit(msecond, 86400000), Unit(second, 86400)
Unit(glob, 1), Unit(decaglob, 0.1), Unit(kiloglob, 0.001), Unit(gigaglob, 1E-09), Unit(megaglob, 1E-06)

(1, hour, 3600, second)
(Unit(hour, 24), Unit(second, 86400))
Unit(day, 1), Unit(hour, 24), Unit(minute, 1440), Unit(msecond, 86400000), Unit(second, 86400)
Unit(glob, 1), Unit(decaglob, 0.1), Unit(kiloglob, 0.001), Unit(gigaglob, 1E-09), Unit(megaglob, 1E-06)


Запускаю так
app.exe < _in > _out 2> _err
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Программист в стартап $1500-3500
От: WolfHound  
Дата: 17.06.07 22:20
Оценка:
Здравствуйте, WolfHound, Вы писали:

M>>Если не в лом, гляньте на сколько бачей примерно автор кода у вас бы потянул.

WH>Ради интереса переписал на немерле
Что-то у меня на ночь глядя замкнуло. В классе Cluster Hashtable не нужен. Достаточно List.
    class Cluster
    {
        private _units : List.[Unit] = List.[Unit]();
        public Units : SCG.ICollection.[Unit]
        {
            get { _units; }
        }
        public Add(unit : Unit) : void
        {
            _units.Add(unit);
        }
    }
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Программист в стартап $1500-3500
От: ihatelogins  
Дата: 17.06.07 22:38
Оценка:
Здравствуйте, kikap, Вы писали:

N>>1. Software process (хоть какой) присутствует?

K>Процесс очень простой — ad hoc. И другого пока применить невозможно. Но качество результирующего кода таково что я давно такого не видел. Если вы владеете вопросом и сможете внедрить какой-то процесс, который поможет разработке — you're very welcome.

N>>2. Сколько минимум часов в неделю?


K>40. Мы скорее уволим человека, который не справляется с работой, чем будем заставлять его перерабатывать. Это просто не окупается. С другой стороны есть люди, которые работают взахлеб по 100 часов в неделю, а потом неделю бездельничают.


100 часов? В неделю?

Что касается 40 часов, то ваша цель — это 40 часов работы или выполнение плана?
Re[3]: Программист в стартап $1500-3500
От: machine3000  
Дата: 19.06.07 14:22
Оценка:
Здравствуйте, WolfHound, Вы писали:

...


А если порядок задания правил конвертации будет примерно таким:

1 ax = 2 ay
1 bx = 2 cy
1 dx = 2 ey
1 fx = 2 gy

1 ax = 2 bx
1 dx = 2 fx

1 ax = 2 dx

только не 7 штук, а, скажем, 2^24-1, то, по-моему, "mergeClusters" тут будет умножать и умножать... Не линейная сложность короче.
Re[4]: Программист в стартап $1500-3500
От: WolfHound  
Дата: 19.06.07 15:25
Оценка:
Здравствуйте, machine3000, Вы писали:

M>только не 7 штук, а, скажем, 2^24-1, то, по-моему, "mergeClusters" тут будет умножать и умножать... Не линейная сложность короче.

Сложность у алгоритма O(N*log(N)) в худшем случае. И я об этом написал.
Доводить ее до линейной в данном случае не имеет смысла ибо 2^24-1 единиц измерения да чтобы еще и измеряли одно и тоже... такого не бывает впринципе.
За то мое решение было написано за вечер в перерывах между чтением RSDN, его легко понять и легко расширять (обрати внимание насколько легко я добавил возможность ? быть не только справа от = но и слева). Да на С++ получилось бы несколько (всетки немерле болие мощьный язык) хуже но не сильно.
Так что не нужно переусложнять задачу.
И вобще задачи нужно решать самым простым способом которым можно получить приемлемое решение.
Кстати что-то мне подсказывает что мое решение легко поймут даже те кто немерле не знает. А вот разобраться в твоем...
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Программист в стартап $1500-3500
От: machine3000  
Дата: 20.06.07 06:34
Оценка:
Здравствуйте, WolfHound, Вы писали:

...

Да, похоже умение придумывать линейные алгоритмы на хрен никому не упало. Вот так вот — век живи, век учись. Знал бы прикуп, жил бы ... в Зеленограде.
Re[6]: Программист в стартап $1500-3500
От: WolfHound  
Дата: 20.06.07 07:30
Оценка:
Здравствуйте, machine3000, Вы писали:

M>Да, похоже умение придумывать линейные алгоритмы на хрен никому не упало. Вот так вот — век живи, век учись. Знал бы прикуп, жил бы ... в Зеленограде.

Не правильный вывод.
Оно не нужно там где не нужны линейные алгоритмы ценой усложнения решений.
Те если (как в данном случае) с линейным алгоритмом возьни сильно больше чем с O(N*log(N)), а толку 0 то в топку линейный алгоритм.
Кстати первая версия вобще была O(N^2). Но тк преобразование в O(N*log(N)) стоило лишь незначительного усложнения mergeClusters я это сделал.
Если бы это было сложнее то я скорей всего бы забил ибо предпологаемый (в реальной жизни я бы уточнил) сценарий использования такой что
1)Единиц измерения очень мало.
2)Вопросов на которые нужно ответить очень много.
Те скорость инициализации особого значения не имеет, а ответ на вопрос имеет у меня сложность O(1).

Короче хороший программист это не тот кто только и умеет что придумывать линейные решения, а тот кто может быстро оценить несколько решений и выбрать лучшее соотношение цена/качество.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Программист в стартап $1500-3500
От: machine3000  
Дата: 20.06.07 08:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Короче хороший программист это не тот кто только и умеет что придумывать линейные решения, а тот кто может быстро оценить несколько решений и выбрать лучшее соотношение цена/качество.


"цена/качество" можно оценить только в каком-то глобальном контексте. Например, если знать, что конвертировать будут валюты, то и говорить не о чем. А если речь идёт о тестовом задании, то его цель, очевидно, выяснить возможности кандидата. И мне казалось, что демонстрация возможностей в данном случае не возбраняется. Тем более, что так задача выглядит подозрительно простой для такой вакансии.
Re[8]: Программист в стартап $1500-3500
От: WolfHound  
Дата: 20.06.07 08:57
Оценка: +1 :)
Здравствуйте, machine3000, Вы писали:

M>"цена/качество" можно оценить только в каком-то глобальном контексте. Например, если знать, что конвертировать будут валюты, то и говорить не о чем. А если речь идёт о тестовом задании, то его цель, очевидно, выяснить возможности кандидата. И мне казалось, что демонстрация возможностей в данном случае не возбраняется. Тем более, что так задача выглядит подозрительно простой для такой вакансии.

Вот они и выяснили что ты на ровном месте усложняешь решение...
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Программист в стартап $1500-3500
От: kikap Россия http://www.kika.ru
Дата: 24.10.07 15:16
Оценка: 5 (1)
up. Нужен еще один человек.

Объявление в общем и целом остается в силе, единственное что теперь нам нужен скорее алгоритмический человек, с неплохим запасом скажем в области теории графов и комбинаторики. Если Вы представляете себе как работает в юниксе gated и в принципе способны его написать (идеально — полностью автономно, но годится и под чутким руководством), то Вы похожи на человека, который нам нужен

Отладочный лог прошлой процедуры найма людей на работу можно почитать тут: http://kika.livejournal.com/tag/joboffer
там есть немного обценной лексики, но беззлобно

Люди без московской прописки, женщины, геи, лесбиянки, негры, удаленщики, курящие, пьющие и проч — welcome, we are equal opportunity employer. Главное чтобы Вы были вменяемы, способны к самостоятельной работе, умели задавать нормальные вопросы и задавать каждый вопрос только один раз. Ну и не боялись делать что-то что Вы раньше не делали.
Re[2]: Программист в стартап $1500-3500
От: machine3000  
Дата: 24.10.07 15:35
Оценка:
Здравствуйте, kikap, Вы писали:

K>Объявление в общем и целом остается в силе, единственное что теперь нам нужен скорее алгоритмический человек, с неплохим запасом скажем в области теории графов и комбинаторики. Если Вы представляете себе как работает в юниксе gated и в принципе способны его написать (идеально — полностью автономно, но годится и под чутким руководством), то Вы похожи на человека, который нам нужен


А что это за фигня такая — gated?
Re[3]: Программист в стартап $1500-3500
От: dmz Россия  
Дата: 24.10.07 16:12
Оценка:
K>>Если Вы представляете себе как работает в юниксе gated и в принципе способны его написать (идеально — полностью автономно, но годится и под чутким руководством), то Вы похожи на человека, который нам нужен

M>А что это за фигня такая — gated?

Не заморачивайся, люди, не умеющие пользоваться google ему не подойдут, я думаю
Re[2]: Программист в стартап $1500-3500
От: BulatZiganshin  
Дата: 24.10.07 16:45
Оценка:
Здравствуйте, kikap, Вы писали:

K>Люди без московской прописки, женщины, геи, лесбиянки, негры, удаленщики, курящие, пьющие и проч — welcome, we are equal opportunity employer.


а если всё это одновременно?
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: Программист в стартап $1500-3500
От: kikap Россия http://www.kika.ru
Дата: 24.10.07 16:57
Оценка:
Здравствуйте, machine3000, Вы писали:
M>А что это за фигня такая — gated?

Уууу, это такааая...ТАКАААЯ программа! Ее используют в цереу и эфэсбе. И еще в гугле.
Re[3]: Программист в стартап $1500-3500
От: kikap Россия http://www.kika.ru
Дата: 24.10.07 16:58
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:
K>>Люди без московской прописки, женщины, геи, лесбиянки, негры, удаленщики, курящие, пьющие и проч — welcome, we are equal opportunity employer.
BZ>а если всё это одновременно?

И гей и лесбиянка? Ну по крайней мере на собеседование надо пригласить, посмотреть.
Re[4]: Программист в стартап $1500-3500
От: BulatZiganshin  
Дата: 24.10.07 19:42
Оценка:
Здравствуйте, kikap, Вы писали:

K>Здравствуйте, BulatZiganshin, Вы писали:

K>>>Люди без московской прописки, женщины, геи, лесбиянки, негры, удаленщики, курящие, пьющие и проч — welcome, we are equal opportunity employer.
BZ>>а если всё это одновременно?

K>И гей и лесбиянка? Ну по крайней мере на собеседование надо пригласить, посмотреть.


праивльный ответ был бы "гей без московской прописки? прописку дадим, дадим..."
Люди, я люблю вас! Будьте бдительны!!!
Re[4]: Программист в стартап $1500-3500
От: machine3000  
Дата: 25.10.07 07:34
Оценка:
Здравствуйте, kikap, Вы писали:

K>Уууу, это такааая...ТАКАААЯ программа! Ее используют в цереу и эфэсбе. И еще в гугле.


Да, а вдруг цереу, эфэсбе и гугл используют лишь тот факт, что этой программой пользуются другие.
Re[4]: Программист в стартап $1500-3500
От: vitali_y Беларусь www.stopka.us
Дата: 25.11.07 03:02
Оценка:
Sorry за офтопик — если речь о CQG — это говноконтора — не растраивайся. Они себя везде хвалят — но это не правда — они плохие — я серьезно 100%
Re[3]: Программист в стартап $1500-3500
От: Commentateur Россия  
Дата: 25.11.07 03:48
Оценка:
Здравствуйте, kikap, Вы писали:

K>Здравствуйте, nerpabc, Вы писали:


N>>1. Software process (хоть какой) присутствует?

K>Процесс очень простой — ad hoc. И другого пока применить невозможно.

Вам никогда не приходило, что разумнее сначала нанимать аналитика для написание спек и архитектора для проектирования архитектуры, а уже потом искать программеров, которые станут это реализовывать?

Знаете как это выглядит? Вы приводите на стройплощадку прораба c инженером и говорите "нужно построить 20-этажный дом с магазином на первом этаже. Чертежей пока нет, как сделаете первый этаж, может, нарисуем". Что они вам скажут?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.