Jawa / Говнокод #12067 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Введите число:");
        String data = "";
        Integer x;
        try {
            data = in.readLine();
        } catch (IOException ex) {
            System.err.println(ex.getLocalizedMessage());
            return;
        }
        try {
            x = Integer.parseInt(data);
        } catch(NumberFormatException ex) {
            System.out.println("Вы ввели  не число!");
            return;
        }
        if(x <= 0) {
            System.out.println("Число должно быть положительным!");
            return;
        }
        HashMap friends_nums = new HashMap<Integer, Integer>();
        for(int i = 0; i <= x; i++) {
            int s = 0;
            for(int y = 1; y < i; y++) {
                if(i % y == 0) { s += y; }
            }
            int t = 0;
            for(int y = 1; y < s; y++) {
                if(s % y == 0) { t += y; }
            }
            if(t == i && s != i && !friends_nums.containsValue(i)) { friends_nums.put(i, s); }
        }
        if(friends_nums.isEmpty()) {
            System.out.println("Дружественных пар не найдено!");
        } else {
            System.out.println("Найдены следующие дружественные числа:");
            Object[] one = friends_nums.keySet().toArray();
            Object[] two = friends_nums.values().toArray();
            for(int i = 0; i<friends_nums.size(); i++) {
                System.out.println(one[i] + " и " + two[i]);
            }
        }
    }

Дружественными числами называются два различных натуральных числа, для которых сумма всех собственных делителей первого числа (сумма всех делителей, отличных от самого числа) равна второму числу и сумма всех собственных делителей второго числа равна первому числу. Примеры дружественных чисел: 220 и 284. Делители числа 220: 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 (в сумме дают число 284); делители числа 284: 1, 2, 4, 71, 142 (в сумме 220). Примеры других пар дружественных чисел: 2620 и 2924, 17296 и 18416. Написать программу, которая по заданному натуральному числу N находит все пары дружественных чисел, не превосходящих N.

Запостил: JavaCoder JavaCoder, (Updated )

Комментарии (61) RSS

  • > строки 1-16
    Чтение целого числа давно пора оформить в функцию. В других лабах тоже пригодится.

    > for(int y = 1; y < i; y++) {
    Искать делители делением по самое число... как бы мягко выразиться... некрасиво. Но для мелких чисел как в задаче - конечно пофиг. Вычисление суммы делителей числа стоит вынести в функцию.

    > !friends_nums.containsValue(i)
    Чтобы убить одинаковые пары достаточно было тупого сравнения i<s или i>s. Хешмап это оверкилл. Да еще и заставили бедного хешмапа заниматься неподобающей ему операцией - проверкой того, что он содержит заданное значение.
    Ответить
    • >Чтение целого числа давно пора оформить в функцию. В других лабах тоже пригодится.
      И так потихоньку у тебя вырастает самописная библиотека для упрощения и обхода говен в стандартной библиотеке.

      >Хешмап это оверкилл
      Вот и выросло поколение, которое не уважает бит массивы.
      Ответить
      • вы уделяете слишком много внимания чуваку, который ухитрился написать, цитирую:
        > .keySet().toArray()
        > .values().toArray()
        Ответить
        • > .keySet().toArray()
          > .values().toArray()
          Что не сделаешь, чтобы не читать документацию.
          Ответить
      • > Вот и выросло поколение, которое не уважает бит массивы.
        Эм, это обо мне? ;(
        Ответить
  • divisors n = [x | x <- [1..(n `div` 2)], mod n x == 0]
    isFriendTo x y = x == (sum $ divisors y)
    isFriends x y = x `isFriendTo` y && y `isFriendTo` x
    Ответить
        • У тебя же сейчас ночь? Имхо хаскель вредно читать. Я после того как его начал читать - тоже перестал спать по ночам.
          Ответить
      • А если поступать не как автор исходного ГК, а так, как я написал в первом своем комменте - то ideone успевает посчитать аж 14 таких пар.

        http://ideone.com/m656Ec
        Ответить
            • Я считал не до половины.

              for ( int d = 2; d < upperLimit; ++d )
              upperLimit = (x / d);


              Так-что в итоге это до корня. Сразу до корня я не додумался.
              Ответить
              • >result += (x / d);
                >upperLimit = (x / d);
                Тоже кал, хоть в этом есть зачатки правильной идеи. Или компилер такое нынче хавает?

                Я бы еще попробовал разложить на степеня простых чисел и потом искать сочетания.
                Но лень.
                Ответить
                • Факторизация числа конечно быстрее, но вот как потом взять собственные множители из факторов...
                  Ответить
                  • Уникальные сочетания степеней.
                    Например довольное большое число:
                    2^3*3^4*11^2
                    i=2 for [0..3]
                    j=3 for [0..4]
                    k=11 for [0..2]
                    for each (s=i*j*k)
                    sum+=s;
                    Всего-то собрать 4*5*3=60 сумм.
                    Ответить
                • Запилил с разложением:
                  http://ideone.com/L0iWpQ

                  Тормозной хаскель снова порвал сишечку по производительности.

                  P.S. Лишнее подтверждение того, что алгоритм важнее микрооптимизаций.
                  Ответить
                    • А в чем разница? Что в джва раза?
                      >хаскель снова порвал сишечку по производительности.
                      И вообще не провоцируйте меня.
                      Ответить
                      • >А в чем разница? Что в джва раза?
                        Integer (BigInteger) => Int

                        Но походу этот козарь и ещё несколько борманд оставил в рукаве, чтобы резко обогнать сишку перед финишем.
                        Ответить
                    • Это хуёвый фикс. Не опускайся до уровня Си. Мы все-таки пишем высокоуровневую, надежную прогу, не зависящую от размера инта на платформе.
                      Ответить
                      • > Мы все-таки пишем высокоуровневую, надежную прогу, не зависящую от размера инта на платформе.

                        Сикодеры нервно курят в сторонке перед надёжным хаскеллом
                        Ответить
                  • Кстати, как я посмотрю тут можно запилить более эффективную функцию primes и получить ещё больший прирост.
                    Ответить
                    • Причем тут "делить/умножать на два сдвигом?".
                      Поясните мысль.
                      Это корень.

                      Насчет бинарной арифметики и сдвигов - пост ниже.

                      Там просто надо найти позицию младшей единицы, сдвинуть число, убрав всё младшие нули.
                      Потом пройтись по нечетным до корня (уже нечетного числа) и сложить.
                      После чего умножить на чудесный коэфициент.
                      Ответить
                      • Ну один фиг копеечная микрооптимизация.

                        Имхо стоит асимптотику оптимизнуть в алгоритме с разложением, а не задрачивать корни и сдвиги вместо делений...
                        Ответить
                        • >асимптотику оптимизнуть в алгоритме с разложением
                          Ну это проще простого, правда хацкель мне даже читать трудновато.
                          А писать своё лень.
                          Ответить
                          • Упростил код с разложением. Это будет последняя версия до тех пор, пока кто-нибудь не обгонит ее. 37 пар / 4.45s.
                            http://ideone.com/pBmRP3

                            > нормальный алгоритм типа этого
                            Ну так разложение что-то типа этого и есть. Считаем сколько раз c[i] встречается каждый из простых множителей p[i]. Затем применяем простенькую формулку product(1+p[i]...+p[i]^c[i]) и вычитаем из нее само число (т.к. его не считают своим же делителем).
                            Ответить
                            • >Это будет последняя версия до тех пор, пока кто-нибудь не обгонит ее. 37 пар / 4.45s.

                              http://ideone.com/mN3tO7

                              Ололо. Я тебя обогнал ничго не делая: 37 пар / 1.76s
                              Ответить
                            • Кстати, так я подозреваю, что есть момент с замедлением, из-за факторизации больших чисел из малого количества множителей.

                              Если найти более эффективный алгоритм факторизации, можно будет значительно ускорить алгоритм.
                              Ответить
                              • Как вариант - можно попробовать не разбивать числа на множители, а строить их. При этом смотреть не то, что сумма делителей одного числа, не включая его, дает другое и наоборот, а более простое но равносильное правило - сумма всех делителей одного числа (включая его самого) равна сумме всех делителей второго...
                                Ответить
          • >Выжал всё что мог из кода на C++
            > всё равно получилось медленнее, чем на хаскелле оО.
            Стыдоба ебучая.
            Ну ведь говно полное. Надо головой думать, например - искать количество делителей степени 2 - n, потом идти по нечетным до корня от деления на 2^n.
            Ну и потом умножать примерно на 2^(n)-1.

            А потом вот такие вот люди делают бенчи в которых жаба быстрей си, сисярп.assParallel() быстрее ассемблера, а хацкель быстрей плюсов.
            Ответить
            • Я не делаю бенчи.

              "Выжал всё что мог из кода на C++" - не значит, что я написал эффективный алгоритм.

              Напишите версию быстрее чем текущая (http://ideone.com/mcPaDf), раз уж код такое говно.
              Ответить
              • Инфа устарела. Самая быстрая версия http://govnokod.ru/12067#comment159272.

                P.S. Если прога на Си позиционируется как "быстрая" и не рвет прогу на хаскеле раз в 10 - то эта сишная прога говно. Я более чем уверен, что на си алгоритм с факторизацией отрабатывал бы на порядок быстрее чем на хаскеле.
                Ответить
                • Она была бы в n раз быстрее и в n раз больше.
                  Ответить
  • Просто нужно было очень быстро решить поставленную задачу. Забыл сразу добавить, что да, очень корявенько. Самый натуральный говнокод. Главное, что оно работает.
    Ответить
  • Из кoлeи выбилo кaпитaльнo и, приeхaв нa aвтoбусe oбрaтнo в Oзёры, купил в мaгaзинe вoдки, нaпился дoмa, в oднo лицo, дo свинскoгo сoстoяния.
    Ответить

Добавить комментарий

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8