Автокликер Clickermann :: Форум

Основной раздел => Прочее => Topic started by: Vint on March 07, 2017, 04:10:57 PM

Title: Простое тестовое задание. Алгоритм Луна
Post by: Vint on March 07, 2017, 04:10:57 PM
Простое тестовое задание 1

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

Алгоритм Луна (https://ru.wikipedia.org/wiki/Алгоритм_Луна) — алгоритм вычисления контрольной цифры номера пластиковой карты в соответствии со стандартом ISO/IEC 7812
[spoiler]Не является криптографическим средством, а предназначен в первую очередь для выявления ошибок, вызванных непреднамеренным искажением данных (например, при ручном вводе номера карты, при приёме данных о номере социального страхования по телефону). Позволяет лишь с некоторой степенью достоверности судить об отсутствии ошибок в блоке цифр, но не даёт возможности нахождения и исправления обнаруженной неточности.

Наиболее распространённые применения для подсчёта контрольной цифры:
•   Номера всех банковских карт
•   Номера некоторых дисконтных карт
•   Коды социального страхования
•   IMEI-коды.
•   Расчёт контрольного знака единого 8-значного номера железнодорожного вагона на РЖД.
•   Расчёт ICCID (от англ. Integrated Circuit Card Id) — уникальный серийный номер SIM-карты.[/spoiler]
Оригинальный алгоритм, описанный разработчиком
[spoiler]1. Цифры проверяемой последовательности нумеруются справа налево.
2. Цифры, оказавшиеся на нечётных местах, остаются без изменений.
3. Цифры, стоящие на чётных местах, умножаются на 2.
4. Если в результате такого умножения возникает число больше 9, оно заменяется суммой цифр получившегося произведения — однозначным числом, то есть цифрой.
5. Все полученные в результате преобразования цифры складываются. Если сумма кратна 10, то исходные данные верны.
В примере: последняя цифра — контрольная. Для того, чтобы номер был верен в соответствии с алгоритмом Луна, контрольная цифра должна быть равна 7.
4  5  6  1     2  6  1  2     1  2  3  4     5  4  6  7
8     12       4     2        2     6        10    12
8     3        4     2        2     6        1     3

8+5+3+1 + 4+6+2+2 + 2+2+6+4 + 1+4+3+7 = 60
Сумма кратна 10 – значит номер верный.[/spoiler]


Ссылка на описание в википедии (https://ru.wikipedia.org/wiki/Алгоритм_Луна). Там же и описан алгоритм. Алгоритм очень простой.

Нужно сделать два скрипта. Или один общий.

1.   Скрипт проверки верности существующей контрольной цифры. Т.е. вводим номер с контрольной цифрой на конце. Результат должен быть в сообщении есть в номере ошибки или нет.
2.   Скрипт вычисления контрольной цифры и вывод номера уже с контрольной цифрой.

Скрипты должны быть не наброском «примерно так», а в уже законченном рабочем виде, чтобы ими можно было пользоваться. Вариант реализации – произвольный. Можно использовать массивы, можно не использовать. Для красоты и визуальной разбивки кода можно использовать деление на подпрограммы.
Понятно, что совсем новичкам достаточно будет сделать базовые функции. Массивы, подпрограммы, и остальное, можно оставить на будущее – на «вырост».


Какие команды Clickermann-а вероятно могут понадобиться (из справки):
[spoiler]Основные конструкции:
IF (expression) ... END_IF - проверяет истинность выражения и выполняет блоки инструкций в зависимости от результата
FOR ($var, expression, [step]) ... END_CYC - организует цикл с параметром
WHILE (expression) ... END_CYC - организует цикл с предусловием
SUB (sub_name, [$par1, ...]) ... END_SUB - описывает подпрограмму
WAITMS (delay) - приостанавливает выполнение сценария на несколько миллисекунд
HALT([close]) - полностью останавливает выполнение сценария

Работа с числами:
INT (num) - числовая функция; возвращает целую часть числа без округления. Так же используется для перевода строки в целое число
INC ($var, [value]) - увеличивает значение переменной

Диалоговые окна ввода/вывода:
INPUTBOX("message", "default", [delay]) - строковая функция; выводит диалоговое окно для ввода строки
DIALOGBOX("message", buttons, icon) - числовая функция; выводит диалоговое окно с текстом и кнопками
RADIOBOX("message", radio1, ...) - числовая функция; выводит диалоговое окно с переключателями

Функции работы со строками:
STRLEN ("str") - числовая функция; возвращает длину строки в символах
STRFILTER ("str", "set", mode) - строковая функция; возвращает отфильтрованную строку
STRCUT ("str", begin, size) - строковая функция; возвращает кусок строки
STRCONCAT ("str1", "str2", ...) - строковая функция; возвращает объединенную строку

Для отладки кода использовать вывод в лог и трей:
LOGSHOW (show, [x, y]) - скрывает/отображает окно лога программы
HINTPOPUP ("message", ["title"]) - выводит всплывающее сообщение в системный трей [/spoiler]
Полное описание команд и функций с примерами  можно посмотреть в справке.


Для примера берём номер из вики

Code: [Select]
4561 2612 1234 5467  - проверить, нет ли в номере ошибок
4561 2612 1234 546   - найти контрольную цифру, в данном случае «7»

Во вложении мой пример реализации Luhn_algorithm.cms. Код пока скрыт, но полностью рабочий.
Для Clickermann версии 4.12 build 001

При вводе удаляются все символы, кроме цифр. Если в буфере обмена есть цифры, при вводе они предлагаются как значение по умолчанию.
Если определяли контрольную цифру, по окончании число+кэта цифра помещены в буфер обмена.

Делайте свои варианты и выкладывайте. Можете и не выкладывать  :D.


Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Tochka on March 07, 2017, 07:15:02 PM
 :o Для новичков это слишком резкий старт.
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Vint on March 07, 2017, 07:23:42 PM
Так кажется. Там всё очень просто.
Половина кода это ввод-вывод данных.
Сам алгоритм - один цикл и пара тройка условий.
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Oraven on March 08, 2017, 08:41:00 AM
Нет, слово "Новички" здесь и рядом не стояло  ;D
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Tochka on March 08, 2017, 10:48:41 AM
Тут новички только познают, что не надо задавать в начале скрипта переменные с нулевыми значениями, а вы говорите Алгоритм Луна простое задание...
Задание - это очень хорошая идея. Только пусть продвинутые сдают зачет через личку, чтобы у новичков было время побуксовать и поднять лапки кверху  ;D
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Vint on March 08, 2017, 09:54:52 PM
Да как же так :-\. Я, когда натолкнулся на страницу в вики, сразу подумал, что задание довольно простое и подходит на роль обучающего, чтоб не тренироваться на синтетических заданиях высосанных из пальца.
И алгоритм придумывать не нужно, он описан в 5 пунктах. Где 4 первых пункта - это всего один цикл с двумя вложенными условиями.
Видать я текстом перегрузил  :)
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Tochka on March 09, 2017, 04:10:11 PM
Дядя Vint, а у вас нет в заначке для нас, новеньких, другого задания, скажем, из категории примитивных нулевых?  ::)
Сразу говорю, Примитивное квестовое задание 0 - найти справку Clickermann, я уже выполнила  ;D
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: i0 on March 09, 2017, 04:20:12 PM
а мне вот некогда в школу к дяде-винту
пичаль ;)
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Tochka on March 09, 2017, 04:25:02 PM
а мне вот некогда в школу к дяде-винту
пичаль ;)
А ещё активный участник называется... Как не стыдно прогуливать?  ;D
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Vint on March 09, 2017, 04:27:52 PM
Дядя Vint, а у вас нет в заначке для нас, новеньких, другого задания, скажем, из категории примитивных нулевых?  ::)
Сразу говорю, Примитивное квестовое задание 0 - найти справку Clickermann, я уже выполнила  ;D

Вот не мои 3 задания. Не знаю какой там уровень.
http://crapware.aidf.org/forum/index.php?topic=2369.0;topicseen
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Vint on March 09, 2017, 05:32:18 PM
Ладно. Вот ещё одно задание. Сам давно подумывал сделать и вот только что натолкнулся и вспомнил. Вполне себе бытовое и нужное.
https://www.codewars.com/kata/checking-groups

Гуглоперевод (https://translate.google.ru/?hl=ru&tab=wT#en/ru/Description%3A%0A%0AIn%20English%20and%20programming%2C%20groups%20can%20be%20made%20using%20symbols%20such%20as%20%22()%22%20and%20%22%7B%7D%22%20that%20change%20meaning.%20However%2C%20these%20groups%20must%20be%20closed%20in%20the%20correct%20order%20to%20maintain%20correct%20syntax.%0A%0AYour%20job%20in%20this%20kata%20will%20be%20to%20make%20a%20program%20that%20checks%20a%20string%20for%20correct%20grouping.%20For%20instance%2C%20the%20following%20groups%20are%20done%20correctly%3A%0A%0A(%7B%7D)%0A%5B%5B%5D()%5D%0A%5B%7B()%7D%5D%0AThe%20next%20are%20done%20incorrectly%0A%0A%7B(%7D)%0A(%5B%5D%0A%5B%5D)%0AA%20correct%20string%20cannot%20close%20groups%20in%20the%20wrong%20order%2C%20open%20a%20group%20but%20fail%20to%20close%20it%2C%20or%20close%20a%20group%20before%20it%20is%20opened.%0A%0AYour%20function%20will%20take%20an%20input%20string%20that%20may%20contain%20any%20of%20the%20symbols%20%22()%22%20%22%7B%7D%22%20or%20%22%5B%5D%22%20to%20create%20groups.%0A%0AIt%20should%20return%20True%20if%20the%20string%20is%20empty%20or%20otherwise%20grouped%20correctly%2C%20or%20False%20if%20it%20is%20grouped%20incorrectly.)

В принципе всё понятно, проверить правильность вложенности скобок в строке. Выдать ответ "правильно" / "неправильно".
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Tochka on March 09, 2017, 05:48:46 PM
Надеюсь, сайт не сломаю, пока правильно выполню...  ???
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Tochka on March 10, 2017, 02:18:35 PM
Спасибо. Увлекательно. Возможно, я потеряюсь на какое-то время.
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Qwerry on June 03, 2017, 12:52:34 AM
Если школа дяди-винта еще открыта, попробую показать результат.
 В принципе, задание и правда не очень сложное.  С отладкой немного помучалась. Предпочла все-таки  номер с начала анализировать - вроде для поиска контрольного числа это удобнее.
В общем,  получилось как-то так. Не факт, что всё рационально построено, но уже работает.

Какая там у вас восхитительная абракадабра! Даже возникло безумное желание расшифровать , а что на самом деле там написано.
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: vvm32 on June 03, 2017, 06:46:07 AM
Кстати, приятно, что винт сослался на мою тему(кликермен) с задачками. Я сейчас для одного сайта с книгами пишу скриптики для выкладывания файлов, и так далее. Все игры забросил. Кому будут нужны книги или баллы на twirpx.com - обращайтесь)
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: open_78 on June 05, 2017, 09:07:37 AM
[spoiler]Ура, мой алгоритм луны проверили!!!  А можете помочь с заданием со скобками? оно меня принципиально не хочет слушаться :([/spoiler]
Я ничего не проверял. Только посмотрел. Пусть Vint проверяет.  ;D
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Vint on June 05, 2017, 09:16:30 AM
Я ничего не проверял. Только посмотрел. Пусть Vint проверяет.  ;D
Ага, не проверял говоришь? А замечания дал, хоть и в другой теме
http://crapware.aidf.org/forum/index.php?topic=3251.msg22246#msg22246

И про циклы и про удаление массива и множественный UNDEFINE
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Vint on June 05, 2017, 10:39:59 AM
Проверка на буквы в ведённых данных с помощью умножения на 0. Как вариант для *.
А вот перевод строки в число неявно, когда она попадает в массив иногда даёт ошибку в этом коде. Пробел попадает в массив и преобразуется в логический "0".

Есть же STRFILTER. Им можно оставить только цифры. Ошибку выводить не будет при опечатке, просто пропустит букву. Но зато можно вводить код для наглядности с разделением на разряды
Code: [Select]
4561 2612 1234 5467или через TAB
Code: [Select]
4561 2612 1234 5467
А так я ввёл с пробелами и выдало неправильный результат - 2
Ошибку тоже не показало
[spoiler]
Code: [Select]
9:30:54 последний символ *
9:30:54 анализируемая карта 4561 2612 1234 54670
9:30:54 0 n = 4
9:30:54 1 n = 5
9:30:54 2 n = 6
9:30:54 3 n = 1
9:30:54 4 n = 
9:30:54 5 n = 2
9:30:54 6 n = 6
9:30:54 7 n = 1
9:30:54 8 n = 2
9:30:54 9 n = 
9:30:54 10 n = 1
9:30:54 11 n = 2
9:30:54 12 n = 3
9:30:54 13 n = 4
9:30:54 14 n = 
9:30:54 15 n = 5
9:30:54 16 n = 4
9:30:54 17 n = 6
9:30:54 18 n = 7
9:30:54 19 n = 0
9:30:54 0-4
9:30:54 8
9:30:54 2-6
9:30:54 3
9:30:54 4-
9:30:54  *2
9:30:54 6-6
9:30:54 3
9:30:54 8-2
9:30:54 4
9:30:54 10-1
9:30:54 2
9:30:54 12-3
9:30:54 6
9:30:54 14-
9:30:54  *2
9:30:54 16-4
9:30:54 8
9:30:54 18-7
9:30:54 5
9:30:54 Поиск  контрольного числа для 4561 2612 1234 5467*
9:30:54 сумма без последнего числа, sum1= 38
9:30:54 верное контрольное число 2
9:30:54     Исправленный номер 4561 2612 1234 54672 скопирован в буффер обмена.
9:31:00 Введенный номер карты: 4561 2612 1234 54670
9:31:00 20 символов в номере
9:31:00 0 odd, флаг для нечетно
[/spoiler]

А в целом хорошо. Вариант со звёздочкой удобней и наглядней, чем мой простой переключатель.
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Qwerry on June 06, 2017, 11:51:00 AM
Совсем не учла этот вариант. Зато дальше с первой попытки смогла выловить ошибку  ;D Достаточно было ввести номер через "-", чтоб предложили остановить.

Quote
Есть же STRFILTER.
Признаться, я только вчера  STRFILTER  в действии увидела ::) Так что назовем это повторением вчерашнего урока)

Спасибо, поправила :) Заодно в лог кинула сообщение про "возможную ошибку", если строчка после фильтра уменьшилась.
Title: Re: Простое тестовое задание. Алгоритм Луна
Post by: Атеист on December 01, 2017, 08:46:15 PM
Ладно. Вот ещё одно задание. Сам давно подумывал сделать и вот только что натолкнулся и вспомнил. Вполне себе бытовое и нужное.
https://www.codewars.com/kata/checking-groups

Гуглоперевод (https://translate.google.ru/?hl=ru&tab=wT#en/ru/Description%3A%0A%0AIn%20English%20and%20programming%2C%20groups%20can%20be%20made%20using%20symbols%20such%20as%20%22()%22%20and%20%22%7B%7D%22%20that%20change%20meaning.%20However%2C%20these%20groups%20must%20be%20closed%20in%20the%20correct%20order%20to%20maintain%20correct%20syntax.%0A%0AYour%20job%20in%20this%20kata%20will%20be%20to%20make%20a%20program%20that%20checks%20a%20string%20for%20correct%20grouping.%20For%20instance%2C%20the%20following%20groups%20are%20done%20correctly%3A%0A%0A(%7B%7D)%0A%5B%5B%5D()%5D%0A%5B%7B()%7D%5D%0AThe%20next%20are%20done%20incorrectly%0A%0A%7B(%7D)%0A(%5B%5D%0A%5B%5D)%0AA%20correct%20string%20cannot%20close%20groups%20in%20the%20wrong%20order%2C%20open%20a%20group%20but%20fail%20to%20close%20it%2C%20or%20close%20a%20group%20before%20it%20is%20opened.%0A%0AYour%20function%20will%20take%20an%20input%20string%20that%20may%20contain%20any%20of%20the%20symbols%20%22()%22%20%22%7B%7D%22%20or%20%22%5B%5D%22%20to%20create%20groups.%0A%0AIt%20should%20return%20True%20if%20the%20string%20is%20empty%20or%20otherwise%20grouped%20correctly%2C%20or%20False%20if%20it%20is%20grouped%20incorrectly.)

В принципе всё понятно, проверить правильность вложенности скобок в строке. Выдать ответ "правильно" / "неправильно".

Годная оказалась задача (3 in 1). Одним решением поднял на Codewars целый уровнь. :) Функция подходит для решения трёх кат разных уровней.
Вот они все: (может еще есть, я не искал, может кому пригодится)
Checking Groups (https://www.codewars.com/kata/54b80308488cb6cd31000161) (6 kyu)
Valid Parentheses (https://www.codewars.com/kata/52774a314c2333f0a7000688) (5 kyu)
Valid Braces (https://www.codewars.com/kata/5277c8a221e209d3f6000b56) (4 kyu)

Решал эту задачу на JavaScript. Для Clickermann соответственно тоже написал подпрограмму groupCheck($s) + оригинальные тесты из задачи "Checking Groups".

[spoiler= Ката "Checking Groups" (решение)]
Code: (clickermann) [Select]
#name "Checking Groups" // Clickermann v4.12 (build 001)

// Задача "Checking Groups" - https://www.codewars.com/kata/checking-groups

//-------------------------------- Test Cases:
//
// Тестовые строки от авторов задачи. Копируем их в массив (вместе с комментариями и прочим "мусором") для проверки своего решения.
// Как оказалось (после выполнения задания), тестовые строки не содержат никаких символов кроме скобок, но мы их добавим.

$arr[0] = "Test.expect(groupCheck('()'), 'That group was matched correctly');"
$arr[1] = "Test.expect(groupCheck('({})'), 'That group was matched correctly');"
$arr[2] = "Test.expect(groupCheck('[[]()]'), 'That group was matched correctly');"
$arr[3] = "Test.expect(groupCheck('[{()}]'), 'That group was matched correctly');"
$arr[4] = "Test.expect(groupCheck('([])'), 'That group was matched correctly');"
$arr[5] = "Test.expect(groupCheck('{}([])'), 'That group was matched correctly');"
$arr[6] = "Test.expect(groupCheck('{[{}[]()[]{}{}{}{}{}{}()()()()()()()()]{{{[[[((()))]]]}}}}(())[[]]{{}}[][][][][][][]({[]})'), 'That group was matched correctly');"
$arr[7] = "Test.expect(groupCheck(''), 'That group was matched correctly');"
//
$arr[8] = "Test.expect(!groupCheck('{(})'), 'That group was matched incorrectly');"
$arr[9] = "Test.expect(!groupCheck('[{}{}())'), 'That group was matched incorrectly');"
$arr[10] = "Test.expect(!groupCheck('{)[}'), 'That group was matched incorrectly');"
$arr[11] = "Test.expect(!groupCheck('[[[]])'), 'That group was matched incorrectly');"
$arr[12] = "Test.expect(!groupCheck('()[]{]'), 'That group was matched incorrectly');"
$arr[13] = "Test.expect(!groupCheck('{([]})'), 'That group was matched incorrectly');"
//
$arr[14] = "Test.expect(!groupCheck('[])'), 'That group was left open or prematurely closed');"
$arr[15] = "Test.expect(!groupCheck('([]))'), 'That group was left open or prematurely closed');"
$arr[16] = "Test.expect(!groupCheck('{{))'), 'That group was left open or prematurely closed');"
$arr[17] = "Test.expect(!groupCheck('{}{'), 'That group was left open or prematurely closed');"
$arr[18] = "Test.expect(!groupCheck('{'), 'That group was left open or prematurely closed');"
$arr[19] = "Test.expect(!groupCheck(']'), 'That group was left open or prematurely closed');"
$arr[20] = "Test.expect(!groupCheck('{{{{{{{{{{{((((((([])))))))}}}}}}}}}}'), 'That group was left open or prematurely closed');"
//
$arrsize = ARRSIZE($arr)

//-------------------------------- Решение (было бы другим, если бы задание было правильно сформулировано)

SUB(groupCheck, $s)
   
   $s = STRFILTER($s, "[({})]", 1)
   
   $check = 1
   
   WHILE( (STRLEN($s) > 0) & ($check > 0) )
      $lastStrLength = STRLEN($s)
      $s = STRREPLACE($s, "()", "")
      $s = STRREPLACE($s, "{}", "")
      $s = STRREPLACE($s, "[]", "")
      $check = $lastStrLength - STRLEN($s)
   END_CYC
   
   IF(STRLEN($s))
      LOGWRITE ("false")
   ELSE
      LOGWRITE ("true")
   END_IF
   
   //   LOGWRITE ( !!STRLEN($s) ) // 0 - true, 1 - false
   
END_SUB

//-------------------------------- Тесты

LOGCLEAR

FOR($i = 0, $i < $arrsize)
   
   groupCheck($arr[$i])
   
END_CYC


HALT
[/spoiler]

Прикрутил себе в подпись бейджик Codewars. Как видно хвалиться пока нечем, это начало. Надеюсь будет работать как мотиватор.
Присоединяйтесь! :)