Вызов Кода - Найдите Пароль

  • Автор темы JetBus
  • Обновлено
  • 22, Oct 2024
  • #1

Обычный N-значный кодовый замок состоит из N вращающихся дисков. На каждом диске по порядку вписаны цифры 0-9, и вам нужно повернуть их на правильный пароль, чтобы открыть его. Очевидно, что если вы не знаете пароль, вам нужно будет попробовать максимум 10Н раз, прежде чем разблокировать его. Это не интересно.

вызов кода - Найдите пароль

Итак, рассмотрим вариант кодового замка, назовем его замком раскрытия расстояния.

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

Одно движение определяется как поворот на одну позицию, например требуется 1 движение из

 
 
 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
 
to > 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 , и 9 движений из > to 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 .

Вызов

Учитывая замок, открывающий расстояние, пароль которого неизвестен, постарайтесь открыть замок с минимальным количеством попытки (не движения), сохраняя при этом программу не слишком длинной.

Правила и подсчет очков

  • Вам следует написать полную программу, которая вводит данные со стандартного ввода и выводит на стандартный вывод. Программа должна выполнять ввод/вывод следующим образом:
952
  • Ваша программа должна обрабатывать до N = 200 и должна выполняться менее 5 секунд на любом вводе.

  • Ведущие нули в выводе не следует опускать.

  • Для каждой длины имеется по 5 тестовых данных, поэтому общее количество тестовых данных равно 1000. Тестовые данные генерируются случайным образом.

  • Окончательный результат будет равен (общее количество догадок во всех тестовых данных) * ln (длина кода в байтах + 50). Побеждает наименьший результат. (ln – натуральный журнал)

  • Я запишу для вас программу. Если вы хотите знать, как я буду оценивать вашу программу, или вы хотите оценить ее самостоятельно, посмотрите предыдущие правки в этом посте.

  • Это испытание завершится 7 декабря 2017 г. в 14:00 UTC. Тогда я опубликую свое решение.

Запуск примера

Строки, начинающиеся с 137 represent input, and others represent program output.

Вы можете запомнить пароль и взаимодействовать со своей программой, чтобы проверить его.

899

Пример программы

РЕДАКТИРОВАТЬ: Возможно, указанный выше формат ввода/вывода был неясен. Вот пример программы на Python.

Python, 369 байт, общее количество попыток = 1005973, балл = 6073935

890

Благодаря Иона для упрощения задачи.

#code-challenge #атомный-код-гольф

JetBus


Рег
11 May, 2014

Тем
74

Постов
181

Баллов
561
  • 26, Oct 2024
  • #2

C, 388 374 368 байт, всего попыток = 162751, очков = 982280

 
 
 
 
 
 
 
 
 
 
 
 M=0:9
s1=c(-5,-3,-1,1,3,5,3,1,-1,-3)
s2=c(-4,-2,0,2,4,4,2,0,-2,-4)
f=function(L){S=rep(0,L)
v0=v(S)
X=S
for(i in c(1:L)){X[i]=5
v1=v0-v(X)
X[i]=4
v2=v0-v(X)
S[i]=M[s1==v1&s2==v2]
X[i]=0}
S}
 
||answer||

С# (.NET Core), 617 байт, всего попыток = 182255, очков = 1185166

f=file("stdin","r") w=function(b=1,A=X){cat(A,"\n",sep="");if(b){b=scan(f,n=1)};b} M=0:9 s1=c(-5,-3,-1,1,3,5,3,1,-1,-3) s2=s1+rep(c(1,-1),,,5) L=w(1,"") X=S=rep(0,L) v0=w() for(i in 1:L){X[i]=5 v1=v0-w() X[i]=4 v2=v0-w() S[i]=M[s1==v1&s2==v2] X=0*S} b=w(0,S)

Надеюсь, C# в этом формате подойдет вам. Это полноценная программа, поэтому должен быть способ скомпилировать ее в исполняемый файл. Дайте мне знать, если я могу что-нибудь сделать, чтобы облегчить задачу. Байты являются частью оценки, хотя тег Code Golf удален, поэтому в моем официальном сообщении удалены все ненужные пробелы и полезные имена. В моем объяснении ниже будут использованы фрагменты негольфированного кода:

Объяснение

Эта программа использует только один вспомогательный метод:

import sys class Lock: def __init__(self, number): self.lock = str(number) def l(self): #lengthOfNumber return len(self.lock) def c(self, guess): #check a guess guess = str(guess) guess = "0" * (len(self.lock) - len(guess)) + guess difference = 0 for i in range(len(self.lock)): d1 = abs(int(self.lock[i]) - int(guess[i])) d2 = 10 - d1 difference += d1 if d1 < d2 else d2 return difference def masterLock(): testdata = ["000","555","755","735","744","746"] for answer in testdata: yield Lock(answer) class LockIO: def __init__(self): self.lock = int(input()) def l(self): return self.lock def c(self, guess): guess = str(guess) guess = "0" * (self.lock - len(guess)) + guess print(guess) sys.stdout.flush() return int(input()) for l in masterLock(): # Write your code here that tries to guess it # When you're done testing you can unindent your code, # replace "for l in masterLock():" with "l = LockIO()" # and submit the code. # # Examples: # l.l() # returns the length of the lock # l.c("952") # returns the distance to the lock # l.c(952) # number also works pass

Это записывает предположение в стандартный вывод, а затем считывает расстояние со стандартного ввода. Программа также немедленно завершает работу, если угадана точная комбинация. Я так часто это называю. Далее первоначальная настройка:

N=int(input());o=0 def c(a): print("0"*(N-len(str(a)))+str(a)) return int(input()) for j in range(N):m={c(i):i for i in reversed(range(0,10**(j+1),10**j))};o+=m[min(m)] c(o)

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

case 3: guess[i] = 1; distance = newGuess(guess); difference = distance - prevDistance; if (difference > 0) { guess[i] = 9; distance -= 2; }

Для каждой цифры он угадывает 5, а затем принимает решение о следующем шаге в зависимости от того, как изменилось расстояние с момента предыдущего предположения (где эта цифра была 0).

3, 1, -1, -3

Если расстояние увеличилось на 5, то для этого расстояния будет правильным 0. Верните эту цифру на 0. Изменение записанного расстояния вручную предотвращает дополнительные предположения.

0

Если расстояние уменьшилось на 5, то 5 — правильная цифра, и мы сразу переходим к следующей цифре.

После этого дела идут сложнее. С использованием 5 and case -5: break; для моих первоначальных предположений означает, что оставшиеся возможности разности равны case 5: guess[i] = 0; distance -= 5; break; with 2 possibilities for each, which need 1 additional guess to distinguish. Each of these cases takes a similar form

guess[i] = 5; var distance = newGuess(guess); var difference = distance - prevDistance; var switchVar = difference; switch (switchVar)

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

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

Хотя это может быть ошибка, это работает, насколько я проверял вручную, но это не гарантия.

Ошибка найдена и устранена благодаря Колере Су.

 

Brummer


Рег
19 Jun, 2006

Тем
56

Постов
207

Баллов
527
  • 26, Oct 2024
  • #3

Python 2 и 3: 175 байт, общее количество попыток = 1005972, оценка = 5448445. for takes 30 attempts).

var lengthString = Console.ReadLine(); int length = int.Parse(l); var guess = new int[length]; var prevDistance = newGuess(guess);

Эта программа требует ceil(log(n))*10 попыток на комбинацию или каждая отдельная цифра занимает 10 попыток (т. е.

Огромное спасибо Colera Su за помощь с функциональностью ввода/вывода.Python-версия Challenge ().

Изменено ОП

static int newGuess(IEnumerable<int> guess) { foreach (var item in guess) { Console.Write(item); } Console.WriteLine(); var distanceString = Console.ReadLine(); var distance = int.Parse(distanceString); if (distance < 1) System.Environment.Exit(0); return distance; } ||answer||

Я написал версию кода блокировки внутри Python. Вы можете использовать его, если пытаетесь решить эту проблему на Python (как я). Следующее работает в Python 2 и 3. Гораздо разумнее было просто реализовать блокировку как класс, который можно протестировать, и я решил создать функцию-генератор для угадывания входных данных.Р

using System;namespace p{class C{static void Main(){var l=Console.ReadLine();int L=int.Parse(l);var g=new int[L];var p=n(g);for(int i=0;i<L;i++){g[i]=5;var d=n(g);var f=d-p;var s=f;switch(s){case 5:g[i]=0;d-=5;break;case-5:break;case 3:g[i]=1;d=n(g);f=d-p;if(f>0){g[i]=9;d-=2;}break;case 1:g[i]=2;d=n(g);f=d-p;if(f>0){g[i]=8;d-=4;}break;case-1:g[i]=3;d=n(g);f=d-p;if(f>0){g[i]=7;d-=4;}break;case-3:g[i]=4;d=n(g);f=d-p;if(f>-3){g[i]=6;d-=2;}break;}p=d;}n(g);}static int n(int[] g){foreach(var i in g){Console.Write(i);}Console.WriteLine();var s=Console.ReadLine();var d=int.Parse(s);if(d<1) Environment.Exit(0);return d;}}}

, 277 байт (score=1175356) 258 байт, всего попыток = 202999, очков = 1163205

Попробуйте онлайн!


Версия stdin-stdout, запрошенная ОП, без шаблонов.

Спасибо Colera Su за исправление первоначальной ошибки. Это немного более короткая версия, чем та, что в комментариях.Ниже представлено сообщение TIO для запуска серии тестов в TIO.

char s[999];i;G;H;t;n;h;e;R(x){scanf("%d",x);}W(i,x,a){printf((i-n?0:4)+"%0*d%0*d\n",i,x,n-i,0);R(a);}S(k,i){if(!(t=e=k>4?s[i]=48:k<1?s[i]=53:!G?H=k,G=i:0)){for(;t++<n;)putchar(48|t==i|t==G);puts("");R(&t);t==h?W(G,e=1,&t):0;s[G]=t>h?53+H:53-H,s[i]=t>h^e?53+k:53-k;G=0;}}main(){R(&n);for(W(n,0,&h);i++<n;S(t-h+5>>1,i))W(i,5,&t);s[G]=53+H,puts(s+1),s[G]=53-H,puts(s+1);}

Р

, 189 байт

Попробуйте онлайн!

Давайте рассмотрим вектор нулей в качестве первоначального предположения.

Давайте назовем V расстоянием между текущим предположением и решением.

 

Alisa1


Рег
02 May, 2007

Тем
59

Постов
174

Баллов
489
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно