Форум программистов, компьютерный форум, киберфорум
Наши страницы
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
vvm28
Учусь всегда.
524 / 109 / 42
Регистрация: 22.12.2013
Сообщений: 831
Записей в блоге: 15
Завершенные тесты: 1
1

Проверить утверждение мудреца. Сократить код

24.01.2019, 11:33. Просмотров 2676. Ответов 52

Проверить утверждение мудреца. Сократить код

Здравствуйте.
Вы скорее всего видели утверждение этого мудреца. Оно часто встречается в социальных сетях.
Задача проверить это утверждение на всех двузначных целых числах.

Я быстро набросал такой код:
Кликните здесь для просмотра всего текста

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
 * 
 */
package testMudr;
 
/**
 *
 * @author vvm
 */
public class TestMudr {
 
    public static void main(String[] args) {
        int x, y;// в нашем случае это двузначные целые числа. прогонять от 10 до 99
        int mudrTrue = 0;// счетчик правды
        int mudrFalse = 0; // счетчик лжи
        int myCout = 0;
        /*мотаем циклы*/
        for (x = 10; x <= 99; x++) {
            for (y = 10; y <= 99; y++) {
               
                myCout++;
                System.out.print(myCout + ".   ");
                myFor(x, y); // вывод x и y, просто вывод на экран для x=  y = 
 
                if (x * y == myResult(x, y)) {
                    t(); // если совпадает выводим "Правда"
                    mudrTrue++; // увеличиваем счетчик правды на единицу
                } else {
                    f(); // если не совпадает выводим "Ложь"
                    mudrFalse++;// увеличиваем счетчик лжи на единицу
                }
            }
        }
        System.out.println(); // перевод на новую строку
        System.out.println("Итог: ");
        System.out.println("Мудрец сказал правду " + mudrTrue + " раз");
        System.out.println("Мудрец соврал " + mudrFalse + " раз");
    }
 
    // результат вычисления мудреца
    public static int myResult(int x, int y) {
 
        int minus_x = 100 - x;
        int minus_y = 100 - y;
        int plus = minus_x + minus_y;
        int hundr_minus_summ = 100 - plus;
 
        int begin = hundr_minus_summ; // начало 
        int end = minus_x * minus_y; // окончание числа
        String strResult = String.valueOf(begin) + String.valueOf(end);
        //String strResult = String.valueOf(begin);
        // strResult+=String.valueOf(end);
        int result = Integer.parseInt(strResult);
        return result;
    }
 
    public static void myFor(int x, int y) {
        System.out.print("для x = " + x + "  y = " + y + " ");
    }
 
    public static void t() {
        System.out.println("Правда!");
    }
 
    public static void f() {
        System.out.println("Ложь!");
    }
 
}


Получилось довольно длинно. Как можно сократить код?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.01.2019, 11:33
Ответы с готовыми решениями:

Сократить код
Добрый вечер! Можно ли как-нибудь сократить код? public void newDesign(JPanel panel) { for...

Конвертер валют - сократить код
Как лучше реализовать конвертер валют, чтобы меньше было кода и вложенных if или case switch?

Написать матрицу через цикл или как сократить код
Здравствуйте , не знаю поймёте вы или нет, но можно ли написать матрицу после &quot;int A =&quot; с помощью...

Проверить истинно ли утверждение
Даны натуральное число N, массивы целых чисел A(30), B(40), C(N). Проверить, истинно ли...

Проверить утверждение, что Множества А и В совпадают
Создать два множества А и В с произвольным количеством элементов, содержащих целые числа в...

52
KEKCoGEN
Эксперт Java
2260 / 2105 / 538
Регистрация: 28.12.2010
Сообщений: 8,306
24.01.2019, 12:15 2
Цитата Сообщение от vvm28 Посмотреть сообщение
Я быстро набросал такой код:
Цитата Сообщение от vvm28 Посмотреть сообщение
Как можно сократить код?
написать код медленно и вдумчиво например
0
_ViPeR_
603 / 481 / 171
Регистрация: 02.03.2010
Сообщений: 1,191
24.01.2019, 12:17 3
Это не мудрец... Это какой то британский ученый едрёна корень...
А вообще у вас программа некорректно работает, например для x=99 и y=99 утверждение "мудреца" верно, только при умножении остатков после вычитания из 100, если получается однозначное число, нужно 0 добавить (так что программа еще и удлинится ).
Работает эта фича, пока остатки от вычитания из сотни не начинают превышать 9, дальше работают более сложные правила.
1
Aviz__
1009 / 781 / 185
Регистрация: 17.02.2014
Сообщений: 4,493
24.01.2019, 13:08 4
vvm28, так?
Java
1
2
3
4
5
6
7
8
9
10
    private static int getResidual00(int num) {return 100 - num;}
 
    private static String getMultFromSolomon(int first, int second) {
        return "" + getResidual00(getResidual00(first) + getResidual00(second)) +
                getResidual00(first)*getResidual00(second);
    }
 
    public static void main(String[] args) {
        System.out.println(getMultFromSolomon(97, 96));
    }
1
24.01.2019, 13:08
ViktorFX
300 / 201 / 53
Регистрация: 11.12.2016
Сообщений: 966
24.01.2019, 16:09 5
vvm28, Можно сократить чтобы вся программа поместилась в оператор вывода.
Там можно еще на пару строк сократить код убрав проверочный вывод, + ускорить работу программы.
Оставляю для проверки.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.stream.IntStream;
 
public class CheckOldSof{
 
    public static void main(String[] args){
        System.out.println("\nUtverzhdenije : " + (IntStream.range(10,100)
            .filter(i -> { return IntStream.range(i,100)
               .filter( j -> {
                   int j1=100-j, i1 = 100-i, ij =i1*j1, s1=100-(i1+j1), s = s1*100+ij;
                   System.out.printf("%d * %d =? %d",i, j, s);
                   System.out.println(s==(i*j)? ": true " : ": false ");
                   return s==(i*i);
               }).sum() == 0? true: false;}).sum() == 0));
    }
}
Добавлено через 6 минут
Надо исправить, вместо return s==(i*i); надо return s==(i*j);
1
vvm28
Учусь всегда.
524 / 109 / 42
Регистрация: 22.12.2013
Сообщений: 831
Записей в блоге: 15
Завершенные тесты: 1
24.01.2019, 16:19  [ТС] 6
Цитата Сообщение от _ViPeR_ Посмотреть сообщение
А вообще у вас программа некорректно работает, например для x=99 и y=99 утверждение "мудреца"
Спасибо за замечание. Наспех писал. Позже поправлю код.
Спасибо всем, кто принял участие.
0
ViktorFX
300 / 201 / 53
Регистрация: 11.12.2016
Сообщений: 966
24.01.2019, 16:50 7
vvm28, У меня к сожалению не совсем верно.
Выводы верные, последняя строка нет.
Объясняю, у меня было изначально
Java
1
2
3
4
5
6
        IntStream.range(10,100)
                .forEach(i ->  IntStream.range(i,100).forEach( j -> {
                       int j1=100-j, i1 = 100-i, ij =i1*j1, s1=100-(i1+j1), s = s1*100+ij;
                       System.out.printf("%d * %d =? %d",i, j, s);
                       System.out.println(s==(i*j)? ": true " : ": false ");
                }));
Здесь вывод выводит нормально, но поскольку forEach это "конечная станция", мне пришлось взять фильтр.
Последняя строка }).sum() == 0? true: false;}).sum() == 0)); неверна и соответствено утверждение тоже, но промежуточные результаты верны. Надо переделать

Добавлено через 12 минут
Исправил, + закоментил строку чтобы увидеть как реагирует программа на вероятные ошибки.
Сейчас все ок!
Java
1
2
3
4
5
6
7
8
9
        System.out.println("\nUtverzhdenije : " + (IntStream.range(10,100)
            .filter(i -> { return IntStream.range(i,100)
               .filter( j -> {
                   int j1=100-j, i1 = 100-i, ij =i1*j1, s1=100-(i1+j1), s = s1*100+ij;
                   System.out.printf("%d * %d =? %d",i, j, s);
//                   j = j==90? j+1:j;
                   System.out.println(s==(i*j)? ": true " : ": false ");
                   return s==(i*j);
               }).count() == (100-i)? true: false;}).count() == 90));
0
vvm28
Учусь всегда.
524 / 109 / 42
Регистрация: 22.12.2013
Сообщений: 831
Записей в блоге: 15
Завершенные тесты: 1
11.02.2019, 23:53  [ТС] 8
Тут цель какая? На самом деле цель не опровергнуть вброс мема социальных сетей.
А наиболее быстрый, понятный анализ полученных нами данных.
1
vvm28
Учусь всегда.
524 / 109 / 42
Регистрация: 22.12.2013
Сообщений: 831
Записей в блоге: 15
Завершенные тесты: 1
01.07.2019, 19:42  [ТС] 9
PS. Мой код выше не учитывает ведущие нули второй части искомого числа.
И в случаях когда вторая часть искомого числа больше 99-ти, алгоритм тоже дает сбой.
0
alicesmagic
211 / 109 / 21
Регистрация: 24.08.2016
Сообщений: 800
02.07.2019, 00:42 10
А у меня вот так получилось:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class WiseMan {
    static int getFactor(int a) {
        int result = 10;
        while((a /= 10) != 0) result *= 10;
        return result;
    }
    
    public static void main(String[] args) {
        int pref, suff, wiseman, trueCount = 0;
        for (int i = 10; i <= 99; i++) 
            for (int j = 10; j <= 99; j++) {
                pref = 100 - ((100 - i) + (100 - j));
                suff = (100 - i) * (100 - j);
                wiseman = pref * getFactor(suff) + suff;
                if (i * j == wiseman) trueCount++;
                System.out.println(i + " x " + j + " = " + i * j +
                "\tпо схеме: " + wiseman + "   \t" + (i * j == wiseman));
            }
        System.out.println("Схема сработала без ошибки " + trueCount + 
                " раз из " + 90 * 90 + " тестовых вычислений");
    }
}
Из 8100 раз мудрец правильно посчитал только 513 раз.

И еще вопрос у меня. В консоль (на эклипсе) выводятся не все значения. Не пойму, то ли там лимит какой установлен. В данном случае выводятся строки начиная только с i = 78 и j = 25. Если выводить меньше инфы в методе println(), то на консоль выводится больше строк. Почему так?
0
Gungala
bakayaro konoyaro
678 / 348 / 123
Регистрация: 18.08.2013
Сообщений: 1,432
Записей в блоге: 1
02.07.2019, 00:46 11
alicesmagic3d, да, в эклипсе есть ограничение на вывод строк. Правда, не знаю какое. В какой-то момент он прост самые старые выведенные строки стирает
1
alicesmagic
211 / 109 / 21
Регистрация: 24.08.2016
Сообщений: 800
02.07.2019, 02:12 12
Цитата Сообщение от Gungala Посмотреть сообщение
да, в эклипсе есть ограничение на вывод строк. Правда, не знаю какое. В какой-то момент он прост самые старые выведенные строки стирает
Gungala, спасибо! Значит мне не почудилось
Цитата Сообщение от vvm28 Посмотреть сообщение
PS. Мой код выше не учитывает ведущие нули второй части искомого числа
vvm28, а какие ведущие нули могут быть при произведении двух чисел?
Цитата Сообщение от vvm28 Посмотреть сообщение
в случаях когда вторая часть искомого числа больше 99-ти, алгоритм тоже дает сбой.
Так может это не алгоритм дает сбой, а сама эта странная схема?

Добавлено через 59 минут
Эх... косяк у себя нашла. Учитывая, что a * b = b * a, вычислений должно быть не 8100, а только 4095.
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class WiseMan {
    static int getFactor(int a) {
        int result = 10;
        while((a /= 10) != 0) result *= 10;
        return result;
    }
    
    public static void main(String[] args) {
        int pref, suff, wiseman, trueCount = 0;
        for (int i = 10; i <= 99; i++) 
            for (int j = i; j <= 99; j++) {
                pref = 100 - ((100 - i) + (100 - j));
                suff = (100 - i) * (100 - j);
                wiseman = pref * getFactor(suff) + suff;
                if (i * j == wiseman) trueCount++;
                System.out.println(i + " x " + j + " = " + i * j +
                "\tпо схеме: " + wiseman + "   \t" + (i * j == wiseman));
            }
        System.out.println("Схема сработала без ошибки " + trueCount + 
                " раз из 4095 тестовых вычислений");
    }
}

И только 260 из них дадут правильный результат.
0
vvm28
Учусь всегда.
524 / 109 / 42
Регистрация: 22.12.2013
Сообщений: 831
Записей в блоге: 15
Завершенные тесты: 1
02.07.2019, 11:12  [ТС] 13
alicesmagic3d,

можно раскрыть скобки:

pref = 100 — ( 100-i + 100 — j ) = 100 — 100 + i — 100 + j = i -100 + j = i + j — 100; //немного сократили код и расчеты
suff = (100 — i) * (100 — j) = 10000- 100j -100i +i*j; // здесь может и нет смысла раскрывать скобки.
0
alicesmagic
211 / 109 / 21
Регистрация: 24.08.2016
Сообщений: 800
02.07.2019, 13:53 14
Цитата Сообщение от vvm28 Посмотреть сообщение
можно раскрыть скобки
vvm28, можно, конечно, но на мой взгляд, без раскрытых скобок код более наглядно описывает картинку.

Вообще, мне просто захотелось решить эту задачу без стрингов. И, вроде бы, получилось

Добавлено через 13 минут
Кстати, такой вопрос. Можно ли считать этот код более эффективным в плане использования памяти и скорости выполнения, нежели код, где используется конвертирование в стринг + конкантенация + обратное конвертирование?
0
Welemir1
Автоматизируй это!
2338 / 1450 / 498
Регистрация: 30.03.2015
Сообщений: 5,335
02.07.2019, 14:27 15
Цитата Сообщение от alicesmagic3d Посмотреть сообщение
мне просто захотелось решить эту задачу без стрингов.


Цитата Сообщение от alicesmagic3d Посмотреть сообщение
Кстати, такой вопрос. Можно ли считать этот код более эффективным в плане использования памяти и скорости выполнения, нежели код, где используется конвертирование в стринг + конкантенация + обратное конвертирование?
да, джава оптимизирована под юзание инта (а тут еще и конвертации), но ты кстати можешь потестить хотя бы по времени выполнения
2
alicesmagic
211 / 109 / 21
Регистрация: 24.08.2016
Сообщений: 800
02.07.2019, 14:43 16
Цитата Сообщение от Welemir1 Посмотреть сообщение
можешь потестить хотя бы по времени выполнения
хмм.. попробую... а со стрингами да, каламбур получился

Кстати, для меня стало открытием, что строку кода: String strResult = String.valueOf(begin) + String.valueOf(end);
Можно вот так красиво упростить: String strResult = "" + begin + end;
0
Gungala
bakayaro konoyaro
678 / 348 / 123
Регистрация: 18.08.2013
Сообщений: 1,432
Записей в блоге: 1
02.07.2019, 15:11 17
Цитата Сообщение от alicesmagic3d Посмотреть сообщение
Кстати, для меня стало открытием, что строку кода: String strResult = String.valueOf(begin) + String.valueOf(end);
Можно вот так красиво упростить: String strResult = "" + begin + end;
На самом деле, было бы лучше сделать вот так String strResult = String.valueOf(begin).concat(String.valueOf(end));
0
alicesmagic
211 / 109 / 21
Регистрация: 24.08.2016
Сообщений: 800
02.07.2019, 15:13 18
Цитата Сообщение от Gungala Посмотреть сообщение
На самом деле, было бы лучше сделать вот так String strResult = String.valueOf(begin).concat(String.valueOf(end));
Обоснуете как-то?
0
Gungala
bakayaro konoyaro
678 / 348 / 123
Регистрация: 18.08.2013
Сообщений: 1,432
Записей в блоге: 1
02.07.2019, 15:19 19
alicesmagic3d, в обоих случаях, что вы написали, при, эм, склеивании строк будет создаваться StringBuilder, а эт тип неоч эффективно. Если треубется соединить всего лишь две строки, то лучше использовать метод concat(), ибо он сработает быстрее

Добавлено через 3 минуты
кхм
1
alicesmagic
211 / 109 / 21
Регистрация: 24.08.2016
Сообщений: 800
02.07.2019, 15:53 20
Gungala, довольно убедительно. Спасибо!

Добавлено через 30 минут
Welemir1, измерения скорости меня порадовали:
Без стрингов: 0,0010 сек
Со стрингами: 0,0100 сек
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.time.LocalDateTime;
class SpeedTest {
    public static void main(String[] args) {
        int pref, suff, wiseman;
        double t1, t2;
        LocalDateTime pic;
 
        // ИСПЫТАНИЕ без стрингов
        pic = LocalDateTime.now();
        t1 = pic.getMinute() * 60 + pic.getSecond() + pic.getNano() / 1e9;
        
        for (int i = 10; i <= 99; i++) 
            for (int j = i; j <= 99; j++) {
                pref = 100 - ((100 - i) + (100 - j));
                suff = (100 - i) * (100 - j);
                wiseman = pref * getFactor(suff) + suff;
            }
        
        pic = LocalDateTime.now();
        t2 = pic.getMinute() * 60 + pic.getSecond() + pic.getNano() / 1e9;
        System.out.printf("Без стрингов: %.4f сек", t2 - t1);
 
        // ИСПЫТАНИЕ со стрингами
        pic = LocalDateTime.now();
        t1 = pic.getMinute() * 60 + pic.getSecond() + pic.getNano() / 1e9;
        
        for (int i = 10; i <= 99; i++) 
            for (int j = i; j <= 99; j++) {
                wiseman = Integer.parseInt(getMultFromSolomon(i, j));
            }
        
        pic = LocalDateTime.now();
        t2 = pic.getMinute() * 60 + pic.getSecond() + pic.getNano() / 1e9;
        System.out.printf("\nСо стрингами: %.4f сек", t2 - t1);
    }
    
    static int getFactor(int a) {
        int result = 10;
        while((a /= 10) != 0) result *= 10;
        return result;
    }
    
    static int getResidual00(int num) {return 100 - num;}
     
    static String getMultFromSolomon(int first, int second) {
        return "" + getResidual00(getResidual00(first) + getResidual00(second)) +
                getResidual00(first)*getResidual00(second);
    }
}
1
02.07.2019, 15:53
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2019, 15:53

Слишком длинный типовой код в UserForm VBA. Как сократить код?
Программа выдает ошибку о слишком длинном коде. 1. Есть форма, в форме Multipage с 30 вкладками,...

Проверить утверждение о произведении четырех последовательных целых чисел
Необходимо составить код для консольного приложения С# по четырем задачам: 3) Произведение четырех...

Проверить, верно ли утверждение, что каждое из чисел А и В - нечетное
Всем привет. Ребят помогите пожалуйста, вот такое условие : Составить программу, предусматривающую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.