Обычный N-значный кодовый замок состоит из N вращающихся дисков. Каждый диск имеет цифры 0-9, вписанные по порядку, и вам нужно повернуть их на правильный пароль, чтобы открыть его. Очевидно, что если вы не знаете пароль, вам нужно будет попробовать не более 10 N раз, прежде чем его разблокировать. Это не интересно
Итак, давайте рассмотрим вариант кодового замка, назовите его блокирующим расстояние.
При каждой неудачной попытке открыть замок, открывающий расстояние, он ответит минимальное количество движений, чтобы разблокировать.
Одно движение определяется как вращение на одну позицию, например, требуется 1 движение от 890
до 899
и 9 движений от 137
до 952
.
Соревнование
Учитывая блокирующую дистанцию блокировку с неизвестным паролем, попробуйте открыть блокировку с минимальным количеством попыток (не перемещений), не допуская слишком долгого выполнения программы.
Правила и оценки
- Вы должны написать полную программу, которая вводит из stdin и выводит в stdout. Программа должна выполнять ввод / вывод следующим образом:
Start
Input an integer N (number of digits) from stdin
Do
Output a line containing decimal string of length N (your attempt) to stdout
Input an integer K (response of the lock) from stdin
While K not equal 0
End
Ваша программа должна обрабатывать до N = 200 и работать на любом входе менее 5 секунд.
Начальные нули в выходных данных не должны быть опущены.
Для каждой длины 5 тестовых данных, поэтому общее количество тестовых данных равно 1000. Тестовые данные генерируются случайным образом.
Окончательный результат будет (общее количество предположений во всех тестовых данных) * ln (длина кода в байтах + 50). Самый низкий балл побеждает. (натуральный бревно)
Я оценю программу для вас. Если вы хотите знать, как я буду оценивать вашу программу, или вы хотите оценить ее самостоятельно, посмотрите предыдущие изменения в этом посте .
Это испытание закончится в 2017/12/07 14:00 UTC. Я опубликую свое решение тогда.
Пример выполнения
Строки, начинающиеся с >
представления ввода, а другие представляют вывод программы.
Вы можете иметь пароль в уме и взаимодействовать с вашей программой, чтобы проверить его.
> 3 # 3-digit lock. The hidden password is 746
000 # 1st guess (by program)
> 11 # response to the 1st guess
555 # 2nd guess
> 4 # ...
755
> 2
735
> 2
744
> 2
746 # finally the correct answer! The program attempts 6 times.
> 0 # this is not necessary
Пример программы
РЕДАКТИРОВАТЬ: Может быть, формат ввода / вывода выше не было ясно. Вот пример программы на Python.
Python, 369 байт, общее количество попыток = 1005973, оценка = 6073935
import sys
N = int(input()) # get the lock size
ans = ''
for i in range(N): # for each digit
lst = []
for j in range(10): # try all numbers
print('0' * i + str(j) + '0' * (N - i - 1)) # make a guess
result = int(input()) # receive the response
lst.append(result)
ans += str(lst.index(min(lst)))
print(ans) # output the final answer
Спасибо Ионе за упрощение задачи.
источник
162751*ln(388+50)=989887
.C # (.NET Core) , 617 байт, всего попыток = 182255, оценка = 1185166
Надеюсь, C # в этом формате работает для вас. Это в форме законченной программы, поэтому должен быть способ компиляции в исполняемый файл. Дайте мне знать, если я могу что-нибудь сделать, чтобы было легче. Байты являются частью оценки, даже если тег Code Golf удален, поэтому мое официальное представление удаляет все ненужные пробелы и полезные имена. Мое объяснение ниже будет использовать фрагменты кода без ключа:
объяснение
Эта программа использует только один вспомогательный метод:
Это записывает предположение в стандартный вывод, а затем считывает расстояние от стандартного ввода. Это также немедленно завершает программу, если предположение является точной комбинацией. Я это часто называю. Далее начальная настройка:
Получается длина комбинации, затем начинается угадывание со всеми 0. После этого он перебирает каждую цифру в
for
цикле.Для каждой цифры он угадывает 5, а затем принимает решение о следующем шаге, основываясь на том, как изменилось расстояние со времени предыдущего предположения (где эта цифра была 0).
Если расстояние увеличилось на 5, то 0 было правильным для этого расстояния. Установите эту цифру обратно на 0. Изменение записанного расстояния вручную предотвращает дополнительные предположения.
Если расстояние уменьшилось на 5, то 5 - правильная цифра, и мы сразу же переходим к следующей цифре.
После этого все сложно. Использование
5
и0
для моих начальных догадок означает, что оставшиеся возможности различий имеют3, 1, -1, -3
2 варианта для каждого, для различения которого требуется 1 дополнительное предположение. Каждый из этих случаев принимает аналогичную формуНекоторые числа меняются, но по сути мы пробуем одну из двух возможностей и проверяем, было ли изменение правильным для этой цифры. Если это не так, тогда другая цифра верна, поэтому мы устанавливаем эту цифру, а затем корректируем разницу вручную.
Этот метод означает, что нам нужно, самое большее, 1 предположение для начальных 0, 2 догадки на цифру, а затем 1 последнее предположение, чтобы последняя цифра не провалилась.
Это может быть ошибкой, это работает, насколько я проверял вручную, но это не гарантия.Ошибка обнаружена и устранена благодаря Colera Suисточник
37
. Выход:00, 50, 30, 75, 75
(да, два 75 с).<
с>
в каждомif
дюйме ,switch
кажется , чтобы исправить ошибку. Если это то, что вы хотите, ваш счет182255*ln(617+50)=1185166
.Python 2 и 3: 175 байт, общее количество попыток = 1005972, оценка = 5448445
Эта программа принимает ceil (log (n)) * 10 попыток на комбинацию или каждая цифра занимает 10 попыток (то есть,
333
30 попыток).Огромное спасибо Colera Su за помощь в работе с функциями ввода / вывода.
Python-версия Challenge ( изменена OP ).
Я написал версию кода блокировки внутри Python. Вы можете пойти дальше и использовать, если вы пытаетесь решить эту проблему в Python (как я). Следующее работает в Python 2 и 3. Было гораздо больше смысла просто реализовать блокировку как класс, с которым вы можете протестировать, и я решил создать функцию генератора для угадывания входных данных.
источник
LockIO
класс неправильно. Я отправил запрос на редактирование. Во-вторых, я думаю, что вы неправильно поняли критерий оценки. Оценка рассчитывается по тестовым данным, сгенерированным генератором, а не по примеру (я выполнил вашу программу, и общее количество составляет 1005972). Природный журнал также отсутствует. В-третьих, я указал, что вам нужно предоставить полную программу, поэтому вы должны также включить этуLockIO
часть в число байтов. Кроме того, вам необходимо вывести окончательный результат, который также учитывается в счете.Lock
иmasterLock
только для удобства тестирования.LockIO
это то, что вам действительно нужно отправить, поскольку он использует требуемый формат ввода / вывода.R ,
277 байтов (оценка = 1175356)258 байтов, всего попыток = 202999, оценка = 1163205Попробуйте онлайн!
Версия стандартного ввода-вывода, запрошенная OP, без шаблонов. Спасибо Колере Су за исправление первоначальной ошибки. Это немного более короткая версия, чем в комментариях.
Здесь ниже представление TIO для запуска серии тестов в TIO
R 189 байт
Попробуйте онлайн!
Давайте рассмотрим вектор нулей как начальную догадку. Назовем V расстоянием между текущим предположением и решением. Для каждой позиции вам нужно только проверять изменения в V, когда вы заменяете 0 на 5 и на 4. На самом деле, различия между изменением 0 на 5 перечислены в моем векторе s1. Различия между изменением 0 на 4 перечислены в моем векторе s2. Как вы видите, эти два вектора однозначно отображают цифры решения.
Таким образом, общее количество тестов составляет
3 * L2 * L + 1, где L - длина кода: начальная проверка на все нули, затем две проверки на каждую цифру, одна на 5 и одна на 4.Улучшение с фактора 3 до фактора 2 было вдохновлено представлением Камиля Дракари.
Остальная часть представления TIO является образцом для R. Представление TIO показывает время выполнения и общее количество операций на 1000 циклов с L = 1 ... 200, 5 повторов для каждого значения L.
источник
Error in scan(n = 1) : scan() expected 'a real', got 'S=rep(0,L)'
при выполнении.scan(file=file("stdin"),n=1)
работает. Эта программа (такая же, как ваша, только что исправила ввод / вывод) получила оценку202999*ln(277+50)=1175356
.202999*ln(258+50) != 202999*ln(277+50)