Вход | Регистрация
 

Задачка (на последнюю пятницу зимы) про два числа из 5 цифр

Задачка (на последнюю пятницу зимы) про два числа из 5 цифр
Я
   1Сергей
 
26.02.21 - 15:22
Можно ли из цифр 1, 2, 3, 4, 5 составить одно двузначное и одно трехзначное число так, чтобы второе делилось на первое?
Каждая цифра должна быть использована ровно один раз.
   Momus
 
1 - 26.02.21 - 15:32
532 14
   1Сергей
 
2 - 26.02.21 - 15:33
(1) Верно. Но есть ещё одно решение
   Kigo_Kigo
 
3 - 26.02.21 - 15:34
123 и 45
   Kigo_Kigo
 
4 - 26.02.21 - 15:35
И докажи мне что оно не делится ))))
   1Сергей
 
5 - 26.02.21 - 15:35
(4) а чо там доказывать, если это очевидно
   Kigo_Kigo
 
6 - 26.02.21 - 15:37
тогда так, любая последовательность цифр делится на другую последовательность из приведенного ряда
   johnnik
 
7 - 26.02.21 - 15:38
(0) Любое число делится на любое (кроме нуля). В условии же не сказано, что оно должно делиться без дробного остатка
   1Сергей
 
8 - 26.02.21 - 15:39
начинается
   johnnik
 
9 - 26.02.21 - 15:51
Привычка :) А то иные клиенты в ТЗ не укажут какие-нибудь "мелкие" детали, вроде как "это же очевидно", а потом придираются.
   RomanYS
 
10 - 26.02.21 - 16:29
(2) 43 215
   SeriyP
 
11 - 26.02.21 - 16:31
Для Сотня3 = 1 По 5 Цикл
        Для Десяток3 = 1 по    5 Цикл
            Если Десяток3 = Сотня3 Тогда
                Продолжить;
            КонецЕсли;
            СтрДесятки = Строка(Сотня3)+Строка(Десяток3);
            Для    Единица3 = 1 по 5 Цикл
                Если Найти(СтрДесятки, Строка(Единица3)) Тогда
                    Продолжить;
                КонецЕсли;
                
                Число3 = Сотня3*100 + Десяток3*10 + Единица3;
                СтрЧисла3 = Строка(Число3);
                Для Десяток1 = 1 По 5 Цикл
                    Для Единица1 = 1 По 5 Цикл
                        Если Десяток1 = Единица1 Тогда
                            Продолжить;
                        КонецЕсли;
                        Если Найти(СтрЧисла3,Строка(Единица1)) или Найти(СтрЧисла3,Строка(Десяток1)) Тогда
                            Продолжить;
                        КонецЕсли;
                        
                        Число2 = Десяток1*10 + Единица1;
                        Если Число3%Число2 = 0 Тогда
                            Сообщить("Пара: " + Число3 + " / " + Число2);
                        КонецЕсли;
                    КонецЦикла;
                КонецЦикла
            КонецЦикла;
        КонецЦикла;
    КонецЦикла;
   hhhh
 
12 - 26.02.21 - 16:32
(7) Сергей у нас - магистр рассеянных наук из известной книги. Сколько ни пасал тем, обязательно или что-то забудет, или условие переврет.
   1Сергей
 
13 - 26.02.21 - 16:45
(10) правильно
(11) Прям один в один как у меня
   1Сергей
 
14 - 26.02.21 - 16:45
Для а1=1 по 5 Цикл
        
        Для а2=1 по 5 Цикл
            
            Если а1=а2 Тогда продолжить КонецЕсли;
            
            а=а1*10+а2;
            
            Для б1=1 по 5 Цикл
                Если б1=а1 или б1=а2 Тогда продолжить КонецЕсли;
                Для б2=1 по 5 Цикл
                    Если б2=б1 или б2=а1 или б2=а2 Тогда продолжить КонецЕсли;
                    Для б3=1 по 5 Цикл
                        Если б3=б1 или б3=б2 или б3=а1 или б3=а2 Тогда продолжить КонецЕсли;
                        
                        б=б1*100+б2*10+б3;
                        
                        Если б%а=0 Тогда
                            Сообщить(""+б+"/"+а+"="+(б/а));
                        КонецЕсли;
                        
                    КонецЦикла;
                КонецЦикла;
            КонецЦикла;
            
        КонецЦикла;
        
    КонецЦикла;
   RomanYS
 
15 - 26.02.21 - 16:45
(11)(13) у меня запросом))
   1Сергей
 
16 - 26.02.21 - 17:13
(15) валяй
   RomanYS
 
17 - 26.02.21 - 17:20
ВЫБРАТЬ
    1 КАК Ц
ПОМЕСТИТЬ ЦЦ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    3

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    4

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    5
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЦЦ11.Ц + 10 * ЦЦ12.Ц  КАК Ч1,
    ЦЦ21.Ц + 10 * ЦЦ22.Ц + 100 * ЦЦ23.Ц КАК Ч2
ПОМЕСТИТЬ ЧЧ
ИЗ
    ЦЦ КАК ЦЦ11
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЦЦ КАК ЦЦ12
        ПО ЦЦ11.Ц <> ЦЦ12.Ц
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЦЦ КАК ЦЦ21
        ПО (НЕ ЦЦ21.Ц В (ЦЦ11.Ц, ЦЦ12.Ц))
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЦЦ КАК ЦЦ22
        ПО (НЕ ЦЦ22.Ц В (ЦЦ11.Ц, ЦЦ12.Ц, ЦЦ21.Ц))
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЦЦ КАК ЦЦ23
        ПО (НЕ ЦЦ23.Ц В (ЦЦ11.Ц, ЦЦ12.Ц, ЦЦ21.Ц, ЦЦ22.Ц))
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЧЧ.Ч1,
    ЧЧ.Ч2
ИЗ
    ЧЧ КАК ЧЧ
ГДЕ
    ЧЧ.Ч2 / ЧЧ.Ч1 = (ВЫРАЗИТЬ(ЧЧ.Ч2 / ЧЧ.Ч1 КАК ЧИСЛО(15, 0)))
   Вафель
 
18 - 26.02.21 - 17:25
(14) эх даже алгоритм формирования перестановок не осилил
   Доктор Манхэттен
 
19 - 26.02.21 - 18:07
(0) На JS, без всяких FOR, IF, и изменения переменных, можно запустить в консоли браузера:

[1, 2, 3, 4, 5]
.map((digitA1, index, arr) => [ ...arr.slice(0, index), ...arr.slice(index + 1) ]
.map((digitA2, index, arr) => [ ...arr.slice(0, index), ...arr.slice(index + 1) ]
.map((digitB1, index, arr) => [ ...arr.slice(0, index), ...arr.slice(index + 1) ]
.map((digitB2, index, arr) => [ ...arr.slice(0, index), ...arr.slice(index + 1) ]
.map(digitB3 => [ digitB1 * 100 + digitB2 * 10 + digitB3, digitA1 * 10 + digitA2 ])))))
.flat(4)
.filter(item => item[0] % item[1] === 0);

Ответ:

532, 14
215, 43
   Ненавижу 1С
 
20 - 26.02.21 - 18:31
(7) есть общепринятая математическая терминология и условности. Разумеется здесь речь о целочисленном делении
   1Сергей
 
21 - 26.02.21 - 19:08
(18) для этого массивы надо использовать, а это лень
   1Сергей
 
22 - 26.02.21 - 19:53
//Решил рекурсивным перебором



Функция РекурсивныйПеребор(Цифры)
    
    Результат = Новый Массив();
    
    Если СтрДлина(Цифры)=1 Тогда
        Результат.Добавить(Цифры);
    ИначеЕсли СтрДлина(Цифры)>1 Тогда
        Для идн=1 по СтрДлина(Цифры) Цикл
            А=Сред(Цифры, идн, 1);
            Для Каждого Элемент из РекурсивныйПеребор(Лев(Цифры,Идн-1)+Сред(Цифры, Идн+1)) Цикл
                Результат.Добавить(А+Элемент);
            КонецЦикла;
        КонецЦикла;
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции



Для Каждого Вариант Из РекурсивныйПеребор("12345") Цикл
    А=Число(Лев(Вариант, 2));
    Б=Число(Сред(Вариант, 3));
    Если Б%А=0 Тогда
        Сообщить(""+Б+"/"+А+"="+(Б/А));
    КонецЕсли;
КонецЦикла;
   1Сергей
 
23 - 26.02.21 - 19:59
Примечательно что для цифр "23456" только один вариант - 364/52=7
а для "45678" аж пять вариантов:

658/47=14
576/48=12
784/56=14
684/57=12
546/78=7
   Доктор Манхэттен
 
24 - 26.02.21 - 20:00
То же самое как (18), только избавился от внешних констант digitA1, digitA2, digitB1, digitB2. Сделал функцию колбака чистой. Добавил рекурсию чтобы избавиться от повторений кода, но пришлось добавить одну проверку на окончание рекурсии, что хреново. Но лучше пока не придумал.

Так же вынес часть кода в отдельные функции, чтобы проще было читать:



const shuffle = (...digits) => (digit, index, arr) => arr.length === 1
    ? [ ...digits, digit ]
    : arr.filter(item => item !== digit).map(shuffle(...digits, digit));

const isDivided = numbers => numbers[0] % numbers[1] === 0;

const getNumbersFromDigits = digits => [ digits[0] * 100 + digits[1] * 10 + digits[2], digits[3] * 10 + digits[4] ];

[ 1, 2, 3, 4, 5 ]
    .map(shuffle())
    .flat(4)
    .map(getNumbersFromDigits)
    .filter(isDivided);
   Доктор Манхэттен
 
25 - 26.02.21 - 20:01
(22) Рекурсия, а все равно три цикла. В один цикл сможешь запихать?
   1Сергей
 
26 - 26.02.21 - 20:06
(25) можно, но зачем? Писанины будет раз в пять больше
   Доктор Манхэттен
 
27 - 26.02.21 - 20:07
(26) Надо придумать чтобы было меньше писанины.
   1Сергей
 
28 - 26.02.21 - 20:08
хм, есть идея
   1Сергей
 
29 - 26.02.21 - 20:18
// Без циклов


Функция РекурсивныйПеребор(Цифры, Число)
    
    Длина=СтрДлина(Цифры);
    
    Если Длина=1 Тогда
        Вариант = Число+Цифры;
        А=Число(Лев(Вариант, 2));
        Б=Число(Сред(Вариант, 3));
        Если Б%А=0 Тогда
            Сообщить(""+Б+"/"+А+"="+(Б/А));
        КонецЕсли;
    ИначеЕсли Длина>1 Тогда
        
        РекурсивныйПеребор(Сред(Цифры, 2), Число+Лев(Цифры, 1));
        РекурсивныйПеребор(Лев(Цифры,1)+Сред(Цифры, 3), Число+Сред(Цифры, 2,1));
        Если Длина>=3 Тогда
            РекурсивныйПеребор(Лев(Цифры,2)+Сред(Цифры, 4), Число+Сред(Цифры, 3,1));
        КонецЕсли;
        Если Длина>=4 Тогда
            РекурсивныйПеребор(Лев(Цифры,3)+Сред(Цифры, 5), Число+Сред(Цифры, 4,1));
        КонецЕсли;
        Если Длина=5 Тогда
            РекурсивныйПеребор(Лев(Цифры,4), Число+Сред(Цифры, 5,1));
        КонецЕсли;
        
    КонецЕсли;
    
КонецФункции

РекурсивныйПеребор("12345", "");
   Доктор Манхэттен
 
30 - 26.02.21 - 20:28
(29) Несколько раз повторяется Если Длина>=XXX Тогда
Зачем вообще рекурсия, если код повторяется и зависит от глубины рекурсии? От этого нужно избавляться.

Это число в условии можно вычислить внутри функции, и использовать для расчетов индексов внутри условия.
 
 
   1Сергей
 
31 - 26.02.21 - 20:30
(30) ну вот просто перебор цифр можно было бы сделать циклом, но тут действует аксиома Эскобара
   1Сергей
 
32 - 26.02.21 - 20:53
// Ещё упростил


Функция РекурсивныйПеребор(Цифры, Число="", Позиция=1)
    
    Длина=СтрДлина(Цифры);
    
    Если Длина=1 Тогда
        Вариант = Число+Цифры;
        А=Число(Лев(Вариант, 2));
        Б=Число(Сред(Вариант, 3));
        Если Б%А=0 Тогда
            Сообщить(""+Б+"/"+А+"="+(Б/А));
        КонецЕсли;
    ИначеЕсли Длина>1 И Позиция<=Длина Тогда
        
        РекурсивныйПеребор(Лев(Цифры,Позиция-1)+Сред(Цифры, Позиция+1), Число+Сред(Цифры, Позиция, 1));
        РекурсивныйПеребор(Цифры, Число, Позиция+1);
        
    КонецЕсли;
    
КонецФункции

РекурсивныйПеребор("12345");
   Доктор Манхэттен
 
33 - 26.02.21 - 20:57
(32) Во, уже лучше. Будет работать на произвольном количестве цифр?

Я сделал неограниченное количество цифр, но больше пяти результата никакого не выдает почему-то.
   Доктор Манхэттен
 
34 - 26.02.21 - 21:00
А, оказывается не на каждой комбинации есть результат. Вот так работает:

((arr) => {
    const shuffle = (...digits) => (digit, index, arr) => arr.length === 1
        ? [ ...digits, digit ]
        : arr.filter(item => item !== digit).map(shuffle(...digits, digit));

    const isDivided = numbers => numbers[0] % numbers[1] === 0;

    const nextDigit = (sum, item) => item + sum * 10;

    const getNumbersFromDigits = digits => [ digits.slice(0, digits.length / 2 + 1).reduce(nextDigit, 0), digits.slice(digits.length / 2 + 1).reduce(nextDigit, 0) ];

    return arr
        .map(shuffle())
        .flat(arr.length - 1)
        .map(getNumbersFromDigits)
        .filter(isDivided);
})([ 2, 3, 4, 5, 6, 7, 8 ])
   1Сергей
 
35 - 26.02.21 - 21:20
(33) По идее на любом



Тут, короче, меня понесло и я решил искать вариант по порядковому номеру


    Для Идн=0 по 119 Цикл
        
        Цифры="12345";
        
        Ч=Идн;
        
        Рез="";
        Для Позиция=-5 по -1 Цикл
            Рез=Рез+ВырезатьЦифру(Цифры,Ч%(-Позиция)+1);
            Ч=Цел(Ч/(-Позиция));
        КонецЦикла;
        
        Сообщить(Рез);
        
    КонецЦикла;

Функция ВырезатьЦифру(Цифры, Позиция)
    Результат = Сред(Цифры, Позиция, 1);
    Цифры = Лев(Цифры, Позиция-1)+Сред(Цифры, Позиция+1);
    Возврат Результат;
КонецФункции
   Доктор Манхэттен
 
36 - 27.02.21 - 23:53
(35) Если по чесноку, то я не вкурил по коду что это за лабуда. Чувак, можешь пояснить как оно работает?


Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.