Решение алгоритмических задач на базе 1С:Предприятие | Новый выпуск Algo1C

28.01.25

Разработка - Математика и алгоритмы

Решаем новые задачи по программированию на 1С!

Добро пожаловать на новый выпуск рубрики "Algo1C", в которой я стараюсь регулярно решать новые задачи по программированию и делиться своими решениями с вами!

Цель рубрики заключается в тренировке практик по применению различных алгоритмов, в поддержании навыка "Писать код" в тонусе ну и само собой немного поразвлечься!


Что было раньше:

В предыдущей части (нажмите на строку) мы решили:

В этой части вас ждут еще более интересные алгоритмические задачи. Давайте приступим!

Перед началом чтения решения задачи хочу призвать каждого к самостоятельному решению задачи, чтобы после вы могли сравнить своё решение с моим и обсудить это в комментариях. Буду рад послушать ваше мнение!


Решение новых задач:

 
 Задача 1

 Платформа: CodeWars

 Название задачи: SQL easy regex extraction (SQL: Легкое выделение с помощью регулярных выражений)

 Ссылка на задачу: https://www.codewars.com/kata/5c0ae69d5f72394e130025f6 (Нажмите на строку)

 Сложность: 7 kyu (7 / 8)

 Тэги: Регулярные выражения, Фундаментальные, Data Science

 Оригинальное описание задачи:

You'll have a table like the following:
name 	        greeting
Austin Gaylord 	Hola que tal #4702665
Kacie Zulauf 	Bienvenido 45454545 tal #470815 BD. WA470815

In this practice you'll need to extract from the greeting column the number preceeded by the # symbol and place it in a new column named user_id.

name 	        greeting 	                                  user_id
Austin Gaylord 	Hola que tal #4702665 	                        4702665
Kacie Zulauf 	Bienvenido 45454545 tal #470815 BD. WA470815 	470815

NOTE: To keep it simple assume that the user_id will be having varchar type

Пояснение:

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

Вполне себе понятное описание, давайте попробуем решить:


Решение:

Для начала предлагаю разделить всю строку из второй колонки на отдельные куски. Как мы можем заметить, идентификатор всегда разделен от самого предложения пробелами. Затем останется лишь проверить каждый элемент на то, начинается он с решетки или нет. Если же начинается, вырезаем его из второй колонки и добавляем в новую. Вот какой в итоге получился код:

 ИсходнаяТаблица = Новый ТаблицаЗначений;
ИсходнаяТаблица.Колонки.Добавить("Имя");
ИсходнаяТаблица.Колонки.Добавить("Приветствие");
//
НоваяСтрока = ИсходнаяТаблица.Добавить();
НоваяСтрока.Имя = "Austin Gaylord";
НоваяСтрока.Приветствие = "Hola que tal #4702665";
//
НоваяСтрока = ИсходнаяТаблица.Добавить();
НоваяСтрока.Имя = "Kacie Zulauf";
НоваяСтрока.Приветствие = "Bienvenido 45454545 tal #470815 BD. WA470815";

////Решение
ИсходнаяТаблица.Колонки.Добавить("ИдентификаторПользователя");
Для Каждого Стр Из ИсходнаяТаблица Цикл
	ТекущийМассив = СтрРазделить(Стр.Приветствие," ");
	Для Каждого ПодСтр Из ТекущийМассив Цикл
		Если Сред(ПодСтр,1,1) = "#" Тогда
			Стр.Приветствие = СтрЗаменить(Стр.Приветствие,ПодСтр,"");
			Стр.ИдентификаторПользователя = ПодСтр;
			Прервать;
		КонецЕсли;
	КонецЦикла;
КонецЦикла;
Вывод = ИсходнаяТаблица[0].Имя + " " + ИсходнаяТаблица[0].Приветствие + " " + ИсходнаяТаблица[0].ИдентификаторПользователя;

Результат:

Austin Gaylord Hola que tal  #4702665

Таблица успешно обновлена, идентификаторы пользователей теперь в отдельный колонках. Идём дальше!

 
 Задача 2

 Платформа: CodeWars

 Название задачи: Guess the Word: Count Matching Letters (Угадай слово: Посчитай схожие буквы)

 Ссылка на задачу: https://www.codewars.com/kata/5912ded3f9f87fd271000120 (Нажмите на строку)

 Сложность: 7 kyu (7 / 8)

 Тэги: Строки, Игры, Головоломки

 Оригинальное описание задачи:

Consider a game, wherein the player has to guess a target word. All the player knows is the length of the target word.

To help them in their goal, the game will accept guesses, and return the number of letters that are in the correct position.

Write a method that, given the correct word and the player's guess, returns this number.

For example, here's a possible thought process for someone trying to guess the word "dog":

count_correct_characters("dog", "car"); #0 (No letters are in the correct position)
count_correct_characters("dog", "god"); #1 ("o")
count_correct_characters("dog", "cog"); #2 ("o" and "g")
count_correct_characters("dog", "cod"); #1 ("o")
count_correct_characters("dog", "bog"); #2 ("o" and "g")
count_correct_characters("dog", "dog"); #3 (Correct!)

The caller should ensure that the guessed word is always the same length as the correct word, but since it could cause problems if this were not the case, you need to check for this eventuality:

#Raise an exception if the two parameters are of different lengths.
You may assume, however, that the two parameters will always be in the same case.

Пояснение:

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

Например, если загаданное слово "dog" то при попытке использовать догадку "bog" программа в ответ должна сообщить что буквы "O" и "G" правильно угаданы и расположены верно.

Звучит интересно, давайте приступим к решению задачи:


Решение:

В условиях задачи не описано наше отношение к регистрам. Отсюда предлагаю предположить что игра всегда проходит в одном и том же регистре, поэтому сводить регистр догадки к регистру загаданного слова не будем. Также утверждается что догадки всегда будут одной и той же длины что и загаданное слово но на всякий случай автор предлагает нам сообщить игроку если он ошибся с длиной. Для начала сразу проверим ситуацию где догадка верна. Далее если она не верна уже проверяем длину догадки на соответствие длине загаданного слова. Затем, при соответствии длин слов, проверяем каждую букву на соответствие с помощью цикла, число итераций которого равно длине обоих слов. Далее все найденные буквы собираем в массив и выводим пользователю в качестве подсказки. Вот какой в итоге получился код:
 ЗагаданноеСлово = "dog";
Догадка = "bog";
//
ПравильныеБуквы = Новый Массив;
Если ЗагаданноеСлово <> Догадка Тогда
	Если СтрДлина(ЗагаданноеСлово) = СтрДлина(Догадка) Тогда
		Для НомерБуквы = 1 По СтрДлина(ЗагаданноеСлово) Цикл
			Если Сред(ЗагаданноеСлово, НомерБуквы, 1) = Сред(Догадка, НомерБуквы, 1) Тогда
				ПравильныеБуквы.Добавить(Сред(ЗагаданноеСлово, НомерБуквы, 1));
			КонецЕсли;
		КонецЦикла;
		//
		Если ПравильныеБуквы.Количество() <> 0 Тогда
			Вывод = СтрСоединить(ПравильныеБуквы," and ")
		Иначе
			Вывод = "No letters are in the correct position";
		КонецЕсли;
	Иначе
		Вывод = "Incorrent legth";
	КонецЕсли;
Иначе
	Вывод = "Correct!";
КонецЕсли;

Результат:

o and g

Занимательная получилась задачка, условия выполнены, всё работает. Продолжаем!

 
 Задача 3

 Платформа: CodeWars

 Название задачи: Simple Fun #18: Candles (Простое веселье #18: Свечи)

 Ссылка на задачу: https://www.codewars.com/kata/5884731139a9b4b7a8000002 (Нажмите на строку)

 Сложность: 7 kyu (7 / 8)

 Тэги: Головоломки

 Оригинальное описание задачи:

When a candle finishes burning it leaves a leftover. makeNew leftovers can be combined to make a new candle, which, when burning down, will in turn leave another leftover.

You have candlesNumber candles in your possession. What's the total number of candles you can burn, assuming that you create new candles as soon as you have enough leftovers?

Example

For candlesNumber = 5 and makeNew = 2, the output should be 9.

Here is what you can do to burn 9 candles:

burn 5 candles, obtain 5 leftovers;
create 2 more candles, using 4 leftovers (1 leftover remains);
burn 2 candles, end up with 3 leftovers;
create another candle using 2 leftovers (1 leftover remains);
burn the created candle, which gives another leftover (2 leftovers in total);
create a candle from the remaining leftovers;
burn the last candle.
Thus, you can burn 5 + 2 + 1 + 1 = 9 candles, which is the answer.

Input/Output

  • [input] integer candlesNumber

    The number of candles you have in your possession.

    Constraints: 1 ≤ candlesNumber ≤ 50.

  • [input] integer makeNew

    The number of leftovers that you can use up to create a new candle.

    Constraints: 2 ≤ makeNew ≤ 5.

  • [output] an integer

 

Пояснение:

В условиях задачи нам рассказывают про свечи. Описывается процесс создания новой свечи из уже расплавившейся свечи. В качестве исходных данных нам будет даваться текущее количество свечей а также количество свечей, необходимых для создания новой свечи. Цель задачи заключается в том чтобы выяснить, придерживаясь ранее описанных принципов восстановления свечей, сколько в итоге свеч можно получить.

Например:

Дано 5 свечей а число свечей, необходимое для создания новой свечи, равно 2

Это значит что в конце у нас останется 5 остатков от горения свечи (воск и прочее). Это значит что из этих остатков мы можем собрать еще 2 новые свечи, один остаток остается нетронутым. После того как погаснут эти свечи у нас на руках остается 3 остатка горения, из которых мы можем собрать еще одну свечу. Как только эта потухнет, у нас уже остется 2 остатка, из которых мы уже собираем последнюю свечу.

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

5 + 2 + 1 + 1 = 9

Логика думаю всем понятна, давайте приступим к решению:


Решение:

Для начала опишем переменные, в которых будем хранить количество использованных свеч и количество остатков. Далее напишем цикл, который будет исполняться до тех пор, пока у нас не останется свеч. Затем в каждой итерации обновляем исходное количество свет, которое будет являться результатом деления ((Остатки + Исходное количество) / Количество свеч для восстановления) без остатка а остаток будет равен остатку от деления тех же переменных. Ну и затем выводим количество использованных свеч. Вот какой в итоге получился код:
 ИсходноеКоличествоСвеч = 5;
КоличествоСвечДляВосстановления = 2;
//
Сгорело = 0;
Остатки = 0;
Пока ИсходноеКоличествоСвеч Цикл
	Сгорело = Сгорело + ИсходноеКоличествоСвеч;	
	ИсходноеКоличествоСвеч = Цел((Остатки + ИсходноеКоличествоСвеч) / КоличествоСвечДляВосстановления);
	Остатки = (Остатки + ИсходноеКоличествоСвеч) % КоличествоСвечДляВосстановления;
КонецЦикла;
//
Вывод = Сгорело;

Результат:

9

Как мы можем заметить, результат отображается правильно. Можем идти дальше!

 
 Задача 4

 Платформа: CodeWars

 Название задачи: ScholarStem: Unit 6- Baby count! (Scholar stem: Задача 6 - Количество младенцев)

 Ссылка на задачу: https://www.codewars.com/kata/5702f077e55d30a7af000115 (Нажмите на строку)

 Сложность: 7 kyu (7 / 8)

 Тэги: Фундаментальные

 Оригинальное описание задачи:

A local birthing center is interested in names!

They have arrays of all the baby names they see each year, but the lists are sooo long! They don’t know how to calculate how many times one name is used.

Given an array of names and a specific name string, return the number of times that specific name appears in the array.

count_name( ["Tom","Bob","Harry","Bob"] , "Bob") # should return 2, since "Bob" shows up 2 times in the array

Пояснение:

Суть задачи максимально проста. Наша с вами задача заключается в том чтобы посчитать количество одинаковых имён детей в роддоме. В качестве входных данных мы будем получать массив а также имя, количество вхождений которого мы должны будем посчитать!

Суть думаю ясна. Давайте попробуем решить:


Решение:

Для решения задачи можем воспользоваться встроенными методом у Таблицы значений "НайтиСтроки", которая в качестве параметра получает структуру с именем колонки и значением. Далее у полученного в результате применения предыдущего метода объекта вызываем метод "Количество" и выводим. В итоге получаем количество вхождений. Вот какой в итоге получился код:

 ИсходныеДанные = Новый ТаблицаЗначений;
ИсходныеДанные.Колонки.Добавить("Имя");
НС = ИсходныеДанные.Добавить();
НС.Имя = "Tom";
НС = ИсходныеДанные.Добавить();
НС.Имя = "Bob";
НС = ИсходныеДанные.Добавить();
НС.Имя = "Harry";
НС = ИсходныеДанные.Добавить();
НС.Имя = "Bob";
//
ИскомоеЗначение = "Bob";
//
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Имя",ИскомоеЗначение);
Вывод = ИсходныеДанные.НайтиСтроки(ПараметрыОтбора).Количество();

Результат:

2

Простая задачка с быстрым решением. Перейдем к последней задаче!

 
 Задача 5

 Платформа: CodeWars

 Название задачи: We Have Liftoff (Полетели)

 Ссылка на задачу: https://www.codewars.com/kata/53d6387b83db278202000802 (Нажмите на строку)

 Сложность: 7 kyu (7 / 8)

 Тэги: Фундаментальные, Массивы, Сортировка, Строки

 Оригинальное описание задачи:

You have an array of numbers 1 through n (where 1 <= n <= 10). The array needs to be formatted correctly for the person reading the countdown of a spaceship launch.

Unfortunately, the person reading the countdown only knows how to read strings. After the array is sorted correctly make sure it's in a format he can understand.

Between each number should be a space and after the final number (n) should be the word 'liftoff!'

Example:

# Given
instructions = [8,1,10,2,7,9,6,3,4,5]
# Should return
"10 9 8 7 6 5 4 3 2 1 liftoff!"

Пояснение:

По условию задачи нам дан неотсортированный массив из чисел, которые должны быть использованы при обратном отсчете во время запуска ракеты. От нас требуется отсортировать этот массив и затем собрать его в одну строку, добавив в конец слово "litoff/Полетели". Ну и затем вывести.
Звучит просто, давайте приступим к решению!

Решение:

Для удобства давайте загрузим данные из массива в список значений, чтобы затем воспользоваться его методом для сортировки. После сортировки выгрузим обратно всё это в исходный массив и затем с помощью функции "СтрСоединить" получим строку из значений массива. Ну и под конец просто присоединить строчку "litoff". В итоге получился вот такой код:

 ИсходныйМассив = Новый Массив;
ИсходныйМассив.Добавить(8);
ИсходныйМассив.Добавить(1);
ИсходныйМассив.Добавить(10);
ИсходныйМассив.Добавить(2);
ИсходныйМассив.Добавить(7);
ИсходныйМассив.Добавить(9);
ИсходныйМассив.Добавить(6);
ИсходныйМассив.Добавить(3);
ИсходныйМассив.Добавить(4);
ИсходныйМассив.Добавить(5);
//
ОтсортированныеДанные = Новый СписокЗначений;
ОтсортированныеДанные.ЗагрузитьЗначения(ИсходныйМассив);
ОтсортированныеДанные.СортироватьПоЗначению();
//
ИсходныйМассив = ОтсортированныеДанные.ВыгрузитьЗначения();
Вывод = СтрСоединить(ИсходныйМассив, " ") + " litoff";

Результат:

1 2 3 4 5 6 7 8 9 10 litoff

Занимательная задача с простым решением!

 
 Новое в конфигурации Algo1C:

Заключение:

Ну что ж, пока на этом всё, надеюсь, статья была увлекательной для вас, благодарю за внимание.

Подключайтесь к решению алгоритмических задач вместе со мной, делитесь вашим мнением и решениями в комментариях! Увидимся в новой статье!

Алгоритмы Математика CodeWars LeetCode Algo1C Задачи

См. также

Математика и алгоритмы Программист Платформа 1C v8.2 1C:Бухгалтерия Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    4935    stopa85    12    

39

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    9936    user1959478    54    

37

Математика и алгоритмы Разное Платформа 1С v8.3 1C:Бухгалтерия Россия Абонемент ($m)

Расширение (+ обработка) представляют собою математический тренажер. Ваш ребенок сможет проверить свои знание на математические вычисление до 100.

2 стартмани

29.09.2023    4780    maksa2005    8    

26

Математика и алгоритмы Инструментарий разработчика Программист Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    12505    8    SpaceOfMyHead    20    

62

Математика и алгоритмы Программист Платформа 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    6031    RustIG    9    

25

Механизмы платформы 1С Математика и алгоритмы Программист Платформа 1С v8.3 Россия Бесплатно (free)

В статье анализируются средства платформы для решения системы линейных уравнений в 1С. Приводятся доводы в пользу некорректной работы встроенных алгоритмов, а значит потенциально некорректного расчета себестоимости в типовых конфигурациях.

23.11.2022    5139    gzharkoj    14    

25

Математика и алгоритмы Программист Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    9401    7    kalyaka    11    

44
Оставьте свое сообщение