Взломать код для кодового замка

22

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

Кодовый замок

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

Если каждой строке в замке присваивается номер, начинающийся со строки 0 для строки комбинации (строка, которая разблокирует блокировку) до строки 9. Например, если числа в строке 4 равны 5336, то комбинация для разблокировки будет такой 1992.

К сожалению, замки уже были упакованы, и ваш вид каждого замка скрыт, поэтому вы можете видеть только цифры на разных строках замка.

Соревнование

Учитывая 4 пары цифр, где первая цифра целого числа представляет номер строки, а вторая цифра представляет число, которое появляется в этой строке, определите комбинацию для блокировки. Например, если вы введете:

57 23 99 45

Тогда он должен вывести:

2101

Или

25 78 63 15

а также

3174

Предположим, что входными данными всегда будут 4 натуральных числа в форме `25 64 72 18.

Это , поэтому выигрывает самая короткая программа по количеству байтов.

Также это мой первый вопрос, поэтому любые отзывы приветствуются.

Рори Макперлрой
источник
Я думаю, что вам нужно уточнить вход. Вы говорите « Дано 4 пары целых чисел », а затем приводите пример 57 23 99 45. Это не четыре пары целых чисел: это четыре целых числа. И некоторые ответы предполагают, что они получают это как строку, в то время как другие предполагают, что она получена готовой как 4 дюйма.
Питер Тейлор
Я не согласен, тот факт , что указанные четыре пары целых чисел сделали формат ввода очистить, 57 представляет собой целое число пара 5 и 7, а не целое число 57. Мое первым предположение было то , что линия была 57 и сочетание было 23
Qwerty01
1
Как насчет "пар цифр"? Это было бы намного яснее и точнее (а также работает с ведущими 0буквами).
пушистый
Технически, правильным термином будет блокировка перестановки . Большинство «кодовых блокировок» фактически являются блокировками перестановки, потому что порядок цифр имеет значение.
nyuszika7h
Технически да, это правильно, но я не думаю, что это бросается в глаза.
Рори Макперлрой,

Ответы:

32

CJam, 9 8 байтов

ea9fbAf%

Читает пары цифр как аргументы командной строки. Чтобы попробовать код в Интернете , изменения eaв lS/читать с моделируемой STDIN.

Пример запуска

$ cjam <(echo ea9fbAf%) 57 23 99 45; echo
2101
$ cjam <(echo ea9fbAf%) 25 78 63 15; echo
3174

Как это работает

Код символа цифры d составляет 48 + d . Таким образом, учитывая двузначную строку xy, базовое число 9 дает 9 * (48 + x) + (48 + y) = 10 * (48 + x) + y - x ≡ y - x (mod 10) .

ea       " Push the array of command-line arguments.                                      ";
  9fb    " Mapped base 9 conversion; replace each string 'xy' with (9 * ord(x) + ord(y)). ";
     Af% " Take the results modulo 10.                                                    ";
Деннис
источник
Черт возьми, ты не можешь позволить кому-то еще победить, нет? : P
Оптимизатор
Я не думаю, что мы получим лучший ответ CJam, чем этот
Рори Макперлрой,
1
Что только что произошло там?
война
1
@DigitalTrauma: Конечно, давай. Строка "99"фактически интерпретируется как массив с [57 57]помощью b; "xy"9bреализован как 9 * ord(x) + ord(y). Я должен добавить это к моему ответу.
Деннис
4
10 000 едва охватывает все двухсимвольные программы, если мы ограничиваем возможные решения для печати ASCII.
Деннис
13

CJam, 13 12 11 символов

Благодаря user23013, его теперь до 11 символов :)

4{Ar:--A%}*

Пояснения:

4{       }*     "Run the code block 4 times";
   r            "Read the next input token (whitespace separated)";
    :-          "Subtract 2nd number from the first treating r as a 2 numbered string";
  A   -         "Subtract the result of above from 10";
       A%       "Take modulus of 10 and store it on stack";

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

Я знаю, что это может быть в гольф больше. Но это моя первая настоящая попытка в CJam, и я ограничен опытом :)


В качестве альтернативы, другие методы могут сделать то же самое в 1 дополнительном символе:

l~]{_A/-A%}/     // My previous solution

или

4{ri_A/-A%}*     // As pointed out by Ingo

или

ea{i_A/-A%}/     // If input is passed through command line
оптимизатор
источник
Я ждал этого. Что ж, на следующей неделе ...
Сохам Чоудхури
Первые три символа могут быть альтернативно l~]. Я чувствую, что парсинг ввода должен быть возможен менее чем с тремя, но я никогда раньше не использовал CJam: /
Ingo Bürk
4{ri_A/-A%}*на один байт короче.
Инго Бюрк
1
Ах, или то, что вы сделали из моего предыдущего комментария. Ну, теперь есть два 12-байтовых решения! :)
Инго Бюрк
3
Или 4{Ar:--A%}*.
jimmy23013
6

Golfscript (14 13 )

Попробуйте онлайн здесь

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

~]{.10:^/-^%}/

Для того же количества байтов вы можете сделать

~]{.10/- 10%}/
Инго Бюрк
источник
Нет предопределенной переменной со значением 10 в Golfscript?
Оптимизатор
@Optimizer К сожалению, нет. Жаль, потому что наличие входных данных в стеке было бы преимуществом по сравнению с CJam.
Инго Бюрк
Да, это может быть 10 символов в CJam (с вводом в стеке) или 11 символов в Golfscript (с предварительно определенной переменной)
Optimizer
У меня также может быть 12 в Golfscript, если только мне не нужно будет оставлять место - 10.
Инго Бюрк
1
хех, даже самый короткий из языков имеют короткие приезды: P
Оптимизатор
6

GNU dc , 14 байтов

Заимствование умной базы 9 Денниса трюк :

9i[?A%nd]dxxxx

Входные целые числа читаются из STDIN, по одному в строке.

Объяснение:

9i                # Set input radix to 9
  [     ]         # push a macro, defined thus:
   ?              #   read number from STDIN and push
    A             #   push literal 10
     %            #   calculate number mod 10
      n           #   print, with no newline
       d          #   duplicate macro
         d        # duplicate macro
          xxxx    # execute the macro 4 times    

Выход:

$ for i in 57 23 99 45; do echo $i; done | dc ./combolock.dc
2101$ 
$ for i in 25 78 63 15; do echo $i; done | dc ./combolock.dc
3174$ 
$ 

Предыдущий ответ, 18 байт:

Потому что я думал, что смогу приблизиться к языкам "игры в гольф" с этим (но не сделал):

[A?A~--A%n]dddxxxx
Цифровая травма
источник
1
Вы можете сохранить байт:9i[?A%nd]dxxxx
Деннис
@ Денис - Фантастика! Теперь у меня все в порядке со скриптом для гольфа и APL!
Цифровая травма
6

C 64 63 56 или 61

Если вход может быть передан из файла

main(a){while(scanf("%d",&a)>0)putchar(48+(a-a/10)%10);}

Если ввод должен быть введен в стандартный ввод

i;main(a){for(;i++-4;putchar(48+(a-a/10)%10))scanf("%d",&a);}

Считывает четыре числа в цикле, а затем обрабатывает каждое, вычитая первую цифру из значения и печатая результат по модулю 10.

Экономия благодаря различным комментариям ниже, а также использованию putchar вместо printf

Alchymist
источник
Круто. Вы можете сохранить запятую, поставив scanfснаружи, for()как этоa,i;main(){for(;i++-4;printf("%d",(a-a/10)%10))scanf("%d",&a);}
Level River St
Вы также можете сохранить 2 байта, используя a*.9вместоa-a/10
rev
@steveverrill Мне нравится. Настолько сосредоточенный на помещении всего в цикл for, что я пропустил это
Алхимик
1
@AcidShout Извините - это не работает. Например, 78 * .9 = 70.2, а 78 - 78/10 = 71. Также использование .9 увеличивает аргумент до двойного, поэтому я не могу взять мод.
Алхимик
Вы можете сэкономить несколько байтов, используя whileцикл и объявив aв качестве аргумента main:main(a){while(scanf("%d",&a)>0)printf("%d",(a-a/10)%10);}
Деннис
5

Python 3, 64

Непосредственная.

print(''.join([(i-i//10)%10 for i in map(int,input().split())]))

Это может быть короче, если мне разрешат напечатать, скажем, [2, 1, 0, 1]вместо этого ( 46 ):

print([i%10-i//10 for i in map(int,input().split())])
Сохам Чоудхури
источник
Вы можете сохранить некоторые, беря str((i-i//10)%10)непосредственно вместо того, чтобы использовать секунду map(). Я тоже начал с генераторов, но обнаружил, что реальный forцикл оказался короче.
DLosc
Да, спасибо за это!
Сохам Чоудхури
Почему вы используете списки? Используйте genexps , чтобы сохранить 2 символов: print(''.join((i-i//10)%10for i in map(int,input().split()))). Кроме того, если пробела allowd на выходе вы можете избежать joinи использования кортежа распаковки: print(*((i-i//10)%10for i in map(int,input().split()))).
Бакуриу
Я полагаю, вы правы.
Сохам Чоудхури
4

С 92

#define a(n) ,(10+v[n][1]-*v[n])%10
main(int c,char**v){printf("%d%d%d%d"a(1)a(2)a(3)a(4));}

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

Я думаю, что это первый раз, когда я написал printfс 4 %с и без запятой (запятая в #define.)

Уровень реки St
источник
#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)затем a,b;main(){f;f;f;f;}будет на 18 байт короче.
Деннис
@ Денис, это большое улучшение, но это в основном совершенно другая программа. Я думаю, если кто-то публикует это, это должен быть ты, а не я. Я не уверен, если пространство в scanfнеобходимо, учитывая, что scanfпредполагается анализировать пробелы только в качестве разделителя. У Алхимика есть еще лучшая идея в Си. Но похоже, что вы уже выиграли его с ответом Cjam.
Уровень Река Сент
Да, я начал с того, что заметил, что пробел после a(n)может быть пропущен, затем я заметил, что размещение printf("%d%,...)вашего макроса сэкономит несколько байтов, и, наконец, я немного увлекся ... - Пространство необходимо, так как %cчитает символ, любой характер, поэтому на втором прогоне он будет хранить 32 в a. - Победить CJam с C должно быть сложно. printf()уже так долго, как мой ответ ...
Деннис
4

Java - 203 байта

Просто потому , что имеет быть запись Java, я увидел хорошую возможность дать этот код , играя в гольф шанс (первое представление когда - либо).

class M{public static void main(String[] a){String r="";for(int i=0;i<4;i++){int l=Byte.valueOf(a[i].substring(1));int f=Byte.valueOf(a[i].substring(0,1));r+=(l-f<0)?l-f+10:l-f;}System.out.print(r);}}

Если есть место для некоторых улучшений, я буду рад узнать о них ;-)

шлифовальная машинка
источник
Вы можете найти [подсказки] и получить различные советы по игре в гольф, чтобы начать работу :)
Оптимизатор
Хорошо, спасибо! Проверка некоторых советов помогла мне сбрить 13 байтов :)
Сандер
3

Lua - 46 символов

while''do a,b=io.read(1,1,1)print((b-a)%10)end

Читает по три символа за раз (даю мне небольшую милость ввода пробела в конце), и даже если a и b являются string-y ... ba MAGICALUALY позволяет им представить целое число здорового ребенка. Проверяет ли обтекание во время печати.

Как я запускаю это:

AndoDaan
источник
1
Не могли бы вы привести пример ввода / вывода данных, не могу заставить его работать Ideone
Рори Макперлрой,
@ Harry12345 Ах, прости за это. Anarchy Golf думает о том, как реализовать stdinput. Я мог бы, вероятно, закодировать это лучше, но, Лу, это ужасно. Я опубликовал пример моего запуска программы.
AndoDaan
3

JavaScript ES6 - 53 43 байта

f=n=>n.replace(/.. ?/g,a=>(1+a[1]-a[0])%10)

Довольно простая функция, использует регулярные выражения для получения чисел. Попробуйте это на http://jsfiddle.net/efc93986/1/ . Если функции не разрешены, автономная программа на 52 байта:

alert(prompt().replace(/.. ?/g,a=>(1+a[1]-a[0])%10))

Поскольку ES6 в настоящее время работает только в Firefox, следующий код работает в любом современном браузере, размером 70 байт:

alert(prompt().replace(/.. ?/g,function(a){return(1+a[1]-a[0])%10}))
NinjaBearMonkey
источник
Я люблю твой 1+.
Нил
1
В вопросе говорится, чтобы принять допустимый ввод, так что вы можете использовать ...?вместо /\d+ ?. Пробел после возврата можно опустить. Кроме того, поскольку не был указан конкретный ввод-вывод, вы должны иметь возможность использовать функцию.
Деннис
1
a-a[0]вместо того, 1+a[1]-a[0]чтобы работать, а также.
Деннис
2

Python 2 - 33 байта

for i in input():print(i-i/10)%10

Принимает разделенный запятыми пользовательский ввод. Например, вход:

29,26, 31, 88

Выход:

7
4
8
0

Если выходные данные необходимы, чтобы точно соответствовать примеру, то это намного дольше. 47 байт:

print"%d"*4%tuple((i-i/10)%10 for i in input())
feersum
источник
input()не работает в моем интерпретаторе Python 2.
Сохам Чоудхури
@ SohamChowdhury ты использовал запятые?
февраля
2
О нет, я не Это работает сейчас. С другой стороны, я думаю , что вы должны принять разделенный пробелами ввод в соответствии со спецификацией.
Сохам Чоудхури
3
Я согласен, вход должен быть ограничен в пространстве
Rory McPerlroy
2

APL, 14

10|{--/⍎¨⍕⍵}¨⎕

Объяснение
берет ввод с экрана. Разделенные пробелом значения анализируются как массив.
{...}¨для каждого числа, введите его в функцию.
⍎¨⍕⍵принимает аргумент, создайте массив из его цифр.
--/рассчитывает единицы минус десятки.
10|мод 10.

TwiNight
источник
1
Это может быть 14 символов, но это 24 байта .
Инго Бюрк
но для кода гольф мы считаем UTF-8, а не какую-то специальную кодировку. Это было бы просто лазейкой и могло быть очень легко оскорблено.
Инго Бюрк
1
@ IngoBürk Согласно meta.codegolf.stackexchange.com/a/961/6972 ответы могут быть закодированы в любой кодировке, если в OP не указано иное. Действительно, есть кодовая страница IBM для символов APL, которая представляет собой однобайтовое отображение, и это именно то, что Dyalog использовал для использования до Unicode 3.0. Если вы настаиваете на Unicode, что если я придумаю новый язык, который использует символы не-Unicode? Как бы вы посчитали байты для этого?
TwiNight
Я мог бы поклясться, что по умолчанию был UTF-8. 14 байт, то есть.
Инго Бюрк
2

J - 20 15

Форма без глагола (как утверждение вместо определения функции) на 5 символов короче:

10|-~/|:10#.inv

Форма глагола, который является хорошим поездом :

10|[:-~/[:|:10#.inv]

Этот глагол используется в примерах ввода:

   10|-~/|:10#.inv 57 23 99 45
2 1 0 1
   10|-~/|:10#.inv 25 78 63 15
3 1 7 4

rotd =: 10|[:-~/[:|:10#.inv] NB. verb form

   rotd 25 78 63 15
3 1 7 4
   rotd 57 23 99 45
2 1 0 1
jpjacobs
источник
2

Haskell 60 58

main=interact$show.map((\x->mod(x-x`div`10)10).read).words

Односимвольные цифры, настоящая враг в игре в Haskell.

Zeta
источник
2

Perl: 38 40

print abs($_-int$_/10)%10for split" ",<>

Выход:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174
Riymus
источник
1
1. Подчеркивание - это синтаксис уценки, поэтому ваш код немного запутался. Чтобы предотвратить это, сделайте отступ кода с четырьмя пробелами. 2. absне обязательно; x - x/10не может быть отрицательным. 3. Если вы используете флаги -040pe(обычно насчитывающие 5 байтов) для перебора входных данных, разделенных пробелами, вы можете сократить свой код до $_=($_-int$_/10)%10. 4. Если вы предпочитаете избегать флагов командной строки, вы все равно можете сохранить несколько байтов, установив $/=$;и удалив вызов split.
Деннис
1

Рубин, 35 байт

$*.map{|n|a,b=n.bytes;$><<(b-a)%10}

объяснение

Ввод принимается в качестве аргументов командной строки. String#bytesвозвращает массив целых чисел (коды символов ASCII). Важна только разница между последним и первым символьным кодом, а не сами целые числа.

britishtea
источник
1

C # & LinqPad: 104

Util.ReadLine<string>("").Split(' ').Select(s =>(s[1]-s[0])).Aggregate("",(r,a)=>r+(a<0?10+a:a)).Dump();
EvilFonti
источник
1

C ++ 118

int main()
{
int a,b,c;
for(int i=0; i<4; i++)
{
cin>>a;
b=a/10;
a=a%10;
c=a-b;
if(c<0)c+=10;
cout<<c;
}
}
bacchusbeale
источник
1. Не уверен насчет других компиляторов, но GCC требует #include<iostream>и std::до, cinи cout. 2. Вам не нужно условное, если вы опустите a=a%10. 3. Вам не нужны переменные bи c, перевод строки и (с небольшой модификацией) скобки вокруг цикла for.
Деннис
1
@ SeanD: Пожалуйста, не одобряйте изменения, которые изменяют код. В этом конкретном случае редактирование сделало ответ недействительным. Также удалена первая строка, которая должна присутствовать во всех ответах.
Деннис
1
(CC @TeunPronk)
Деннис
Ответы @Dennis на этом сайте обычно не содержат строк препроцессора. Я опустил строки #include<iostream>иusing namespace std;
bacchusbeale
Я знаю, что обычно не включается в число байтов, но я думаю, что они должны присутствовать в ответе.
Деннис
1

PHP - 90 символов

Я подумал, что я бы попробовал Code Golf, поэтому вот моя первая попытка - возможно, больше играть в гольф.

<?php $a=array(57,23,99,45);foreach($a as$b){echo abs(substr($b,0,1)-substr($b,1,1)%10);}

58 персонажей (любезно предоставлено Исмаилом Мигелем)

for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);

Доступ к файлу с помощью

file.php?n=57239945
Рори Макперлрой
источник
Попробуйте этот код: <? for($i=0;$i<4;)echo abs($_GET[n][$i]%10);длиной 44 символа. Доступ из браузера с помощью file.php?n[]=xx&n[]=yy&n[]=xy&n[]=yx. (непроверенный код)
Исмаэль Мигель
Хорошая идея, $_GETно она показывает 57% 10, и мне нужно (5-7)% 10
Рори Макперлрой,
Попробуйте это: <? for($i=0,$a=$_GET[n];$i<4;++$i)echo abs($a[$i][0]-$a[$i++][1]%10);. К сожалению, это 65 байт. (забыл $iинкремент на последнем) Или вы можете попробовать <? for($i=0;$i<8;)echo abs($_GET[n][$i++]-$_GET[n][$i++]%10);получить доступ к браузеру, используя file.php?n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=yдлину 61 байт.
Исмаэль Мигель
Да, второй работает, нужно сделать, но $_GET['n']. Отредактировал мой ответ.
Рори Макперлрой,
Ну, это не обязательно. Это просто выдает предупреждение. Это хорошо для этого сайта. Но попробуйте это: <? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);. Это %10бесполезно, и этот просто выглядит лучше. Кроме того, вы можете получить к нему доступ, используя file.php?n[]=xyxyxyxy. Это решение имеет длину 58 байт.
Исмаэль Мигель
0

Python 3, 60

for x in input().split():print(-eval('-'.join(x))%10,end='')

Ввод и вывод точно так, как указано, хотя он не печатает завершающий перевод строки. Здесь есть два интересных трюка: 1) замена двух вызовов на int()один вызов eval(), и 2) использование join()для получения a-b, а затем отрицание его при b-aнеобходимости. К счастью, оператор Python по модулю дает положительные значения, даже если первый аргумент отрицательный!

DLosc
источник
Почему это было отвергнуто? Работает отлично. (Кстати, eval('-'.join(x))трюк блестящий.)
Flornquake
@flornquake Спасибо!
DLosc