Розламіть код до комбінаційного блокування


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

Технічно так, це правильно, але я не думаю, що це викликає привабливий заголовок.
Rory McPerlroy

Відповіді:


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, ніж це
Rory McPerlroy

1
Що саме там сталося?
Війна

1
@DigitalTrauma: Звичайно, йти вперед. Рядок "99"фактично інтерпретується як масив [57 57]шляхом b; "xy"9bреалізується як 9 * ord(x) + ord(y). Я повинен додати це до своєї відповіді.
Денніс

4
10 000 ледве охоплює всі 2-символьні програми, якщо ми обмежимо можливі рішення для друку 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-байтних рішення! :)
Ingo Bürk

3
Або 4{Ar:--A%}*.
jimmy23013

6

Гольфскрипт (14 13 )

Спробуйте його онлайн тут

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

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

Для тієї ж кількості байтів ви можете зробити

~]{.10/- 10%}/

У Golfscript немає попередньо визначеної змінної зі значенням 10?
Оптимізатор

@Optimizer На жаль, ні. Дуже погано, адже наявність входу в стек було б перевагою перед CJam.
Інго Бюрк

Так, це може бути 10 символів у CJam (із введенням у стеці) або 11 у Golfscript (із попередньо визначеною змінною)
Оптимізатор

Я міг би мати 12 і в Golfscript, якби тільки мені не довелося залишати місце в - 10.
Інго Бюрк

1
Гей, навіть найкоротші мови мають свої короткі події: P
Optimizer

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
Денніс

@Dennis - Фантастичний! Тепер я шию і шию з гольфскриптом та APL!
Цифрова травма

6

C 64 63 56 або 61

Якщо вхід може бути переданий з файлу

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

Якщо вхід слід набрати stdin

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

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

Економія завдяки різноманітним коментарям нижче, а також використанню putchar замість printf


Класно. Ви можете зберегти кому, поставивши 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);}
Dennis

5

Пітон 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

Так, спасибі за це!
Soham Chowdhury

Чому ви використовуєте розуміння списку? Використовуйте 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()))).
Бакуріу

Я думаю, ти маєш рацію.
Soham Chowdhury

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.

Я думаю, що це перший раз, коли я написав a printfз чотирма %s і без коми (кома знаходиться в #define.)


#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)за цим a,b;main(){f;f;f;f;}буде на 18 байт коротше.
Денніс

@Dennis це велике вдосконалення, але в основному це зовсім інша програма. Я думаю, якщо хтось публікує це, це повинні бути ви, а не я. Я не впевнений, чи потрібний простір scanf, враховуючи те, що scanfслід проаналізувати пробіли лише як роздільник. Алхіміст має ще кращу ідею у C. Але, схоже, ви вже виграли його своєю відповіддю 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

Луа - 46 символів

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

Читає три символи одночасно (надайте мені малу милість введення пробілу в кінці), і ось хоча б a і b є рядком-y ... ba МАГІЧНОГО дозволяє їм зачати здорову дитину цілим числом. Чи перевіряє обгортання під час друку.

Як я це запускаю:


1
Чи можете ви надати приклад введення / виведення даних, не можу, змусити його працювати на Ideone
Rory McPerlroy

@ 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}))

Я люблю твою 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())

input()не працює в моєму інтерпретаторі Python 2.
Soham Chowdhury

@SohamChowdhury ви використовували коми?
feersum

2
О, ні, я цього не зробив. Це працює зараз. Що стосується бічної записки, я думаю, що вам потрібно взяти обмежений простір вхід на специфікацію.
Soham Chowdhury

3
Я згоден, вхід повинен бути обмежений
космосом

2

APL, 14

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

Пояснення
приймає дані з екрана. Значення, розділені пробілом, аналізуються як масив.
{...}¨для кожного числа подайте його у функцію.
⍎¨⍕⍵бере аргумент, створює масив його цифр.
--/обчислює одиниці мінус десятки.
10|мод 10.


1
Це може бути 14 символів, але це 24 байти .
Інго Бюрк


але для кодового гольфу ми розраховуємо в UTF-8, а не якийсь спеціальний шарс. Це просто лазівка ​​і зловживати ними можна дуже легко.
Інго Бюрк

1
@ IngoBürk Відповідно до meta.codegolf.stackexchange.com/a/961/6972 відповіді можуть бути кодовані в будь-якому кодуванні, якщо в ОП не вказано інше. Дійсно, існує кодова сторінка 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

2

Haskell 60 58

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

Однозначні цифри, справжня немезида в гольф Хаскелл.


2

Perl: 38 40

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

Вихід:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174

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). Важлива лише різниця між останнім та першим символьними кодами, а не самі цілі особи.


1

C # & LinqPad: 104

Util.ReadLine<string>("").Split(' ').Select(s =>(s[1]-s[0])).Aggregate("",(r,a)=>r+(a<0?10+a:a)).Dump();

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;
}
}

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 символів

Думав, я спробую спробувати гольф з кодом, так ось ось, моя перша спроба - напевно, можна більше пограти в гольф.

<?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']тхо. Відредагували мою відповідь.
Rory McPerlroy

Ну, це не потрібно. Він просто видає попередження. Це добре для цього веб-сайту. Але спробуйте це: <? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);. Це %10марно, і цей просто виглядає краще. Також ви можете отримати доступ до нього за допомогою file.php?n[]=xyxyxyxy. Це рішення становить 58 байт.
Ісмаїл Мігель

0

Пітон 3, 60

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

Введення та вихід точно так, як зазначено, хоча він не друкує контурний новий рядок. Тут є два цікавих хитрощі: 1) заміна двох дзвінків на int()один дзвінок на eval(), і 2) використання " join()get" a-b, а потім відмова від цього на b-aнеобхідне. На щастя, модуль оператора Python дає позитивні значення, навіть якщо перший аргумент є негативним!


Чому це було знято? Це прекрасно працює. (Btw, eval('-'.join(x))фокус геніальний.)
flornquake

@flornquake Дякую!
DLosc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.