Давайте зробимо кілька "deciph4r4ng"


58

У цьому виклику ваше завдання - розшифрувати рядок. На щастя, алгоритм досить простий: читаючи зліва направо, кожну зустрічну цифру N (від 0 до 9) необхідно замінити символом, який є перед ним N + 1 позиціями.

Приклад

Рядок введення "Prog2am0in6"буде декодований таким чином:

приклад

Отже, очікуваний вихід "Programming".

Роз'яснення та правила

  • Вхідний рядок буде містити символи ASCII виключно в діапазоні 32 - 126. Можна припустити, що він ніколи не буде порожнім.
  • Оригінальний розшифрований рядок гарантовано не містить жодної цифри.
  • Після того, як символ розшифрований, він може, в свою чергу, посилатися на наступну цифру. Наприклад, "alp2c1"слід розшифрувати як "alpaca".
  • Посилання ніколи не обертаються навколо рядка: на нього можуть посилатися лише попередні символи.
  • Ви можете написати або повну програму, або функцію, яка або друкує, або виводить результат.
  • Це кодовий гольф, тому найкоротша відповідь у байтах виграє.
  • Стандартні лазівки заборонені.

Тестові кейси

Input : abcd
Output: abcd

Input : a000
Output: aaaa

Input : ban111
Output: banana

Input : Hel0o W2r5d!
Output: Hello World!

Input : this 222a19e52
Output: this is a test

Input : golfin5 3s24o0d4f3r3y3u
Output: golfing is good for you

Input : Prog2am0in6 Puz0les7&1Cod74G4lf
Output: Programming Puzzles & Code Golf

Input : Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.
Output: Replicants are like any other machine. They're either a benefit or a hazard.

Чи можемо ми отримати вхід у вигляді масиву одиночних символьних рядків? Чи можна припустити, що число ніколи не буде більше 9?
fəˈnɛtɪk

@ fəˈnɛtɪk Щодо формату введення: Я б сказав «ні», якщо тільки це єдиний прийнятний формат для вашої мови. Ми маємо справу з одноцифровими, а не числами. Так що так: це гарантовано <= 9, але ви можете зустріти кілька цифр поспіль.
Арнольд

Чи 1bbabбуде правильним вхід (із очікуваним виходом abbab)? Іншими словами, чи можна посилання обернути навколо рядка?
Лука

@Luke Добре. Ні, 1bbabне вірно. Я додав пояснення з цього приводу.
Арнольд

Відповіді:


11

Желе , 9 7 байт

~ịṭṭµ@/

Спробуйте в Інтернеті!

Як це працює

~ịṭṭµ@/  Main link. Argument: s

    µ    Combine the four links to the left into a chain (arity unknown).
     @   Swap the chains arguments. This makes it dyadic.
      /  Reduce s by the chain with swapped arguments. It will be called with
         right argument r (the result of the previous call, initially the first 
         character) and left argument c (the next character of s).
~            Bitwise NOT of c. This maps a digit 'd' to ~d = -(d+1), but all 
             non-digit characters 'D' to 0.
  ṭ          Tack; append c to r.
 ị           Index; select the character of the result to the right at the
             index from the result to the left. Indexing is 1-based and modular,
             so 0 is the last character, -1 the second to last, etc.
   ṭ         Tack; append the resulting character to r.    

13

Java 7, 81 80 байт

void a(char[]a){for(int i=0;++i<a.length;)if(a[i]>47&a[i]<58)a[i]=a[i-a[i]+47];}

Спробуйте в Інтернеті!

Збережено 1 байт завдяки Андерсу Торнбладу . Перший символ не може бути цифрою, тому його не потрібно перевіряти, тобто ми можемо попередньо посилитись перед тим, як перевірити наш термін припинення.


2
Оскільки перший знак ніколи не міг містити цифру, не потрібно перевіряти його. Таким чином, ваш цикл може бути for(int i=0;++i<a.length;){замість цього, зберігаючи одну таблицю.
Андерс Торнблад

12

Хаскелл, 55 байт

o#c|c>'/',c<':'=o!!read[c]:o|1<2=c:o
reverse.foldl(#)[]

Приклад використання: reverse.foldl(#)[] $ "Prog2am0in6 Puz0les7&1Cod74G4lf"-> "Programming Puzzles & Code Golf". Спробуйте в Інтернеті!

Зменшіть рядок до зворотної копії самого себе з числами, заміненими відповідними символами. "зворотний", оскільки таким чином ми маємо простий доступ до рядка поки що при індексації чисел. Знову переверніть її.


1
Ого, я написав це точне рішення, але я його повільно розміщував :) Ну, принаймні зараз я знаю, що це було добре, +1
Лев

11

C, 46 байт

f(char*s){for(;*s++;)*s=s[(*s-52)/6?0:47-*s];}

Спробуйте в Інтернеті!


C,  52   49  48 байт

Завдяки @ l4m2 за збереження байта!

f(char*s){for(;*s++;)*s>47&*s<58?*s=s[47-*s]:0;}

Редагує рядок введення безпосередньо.

Спробуйте в Інтернеті!

Альтернативна 50-байтна версія:

f(char*s){for(;*s++;)*s=abs(*s-57)>9?*s:s[47-*s];}

Рекурсивна версія, 48 байт:

f(char*s){*s>47&*s<58?*s=s[47-*s]:0;*s++&&f(s);}

9

05AB1E , 11 байт

vydiÂyèëy}J

Спробуйте в Інтернеті!

Пояснення

v            # for each character y in input
 ydi         # if y is a digit
    Â        #    push a reversed copy of the string we've built up so far
     yè      #    push the character at index y in the reversed string
       ë     # else
        y    #    push y
         }   # end if
          J  # join stack to a single string
             # output top of the stack at the end of the loop

Мені дійсно потрібно перевірити, чи ви вже відповідали частіше перед початком.
Чарівний восьминіг Урна

@carusocomputing: Ви все ще можете придумати якийсь кращий трюк, ніж я використовував;)
Emigna

7

JavaScript (ES6), 59 53 байти

f=x=>/\d/.test(x)?f(x.replace(/\d/,(m,o)=>x[o+~m])):x

Збережено 7 байт завдяки fəˈnɛtɪk.

f=x=>/\d/.test(x)?f(x.replace(/\d/,(m,o)=>x[o+~m])):x

console.log(f("Prog2am0in6"));
console.log(f("abcd"));
console.log(f("a000"));
console.log(f("ban111"));
console.log(f("Hel0o W2r5d!"));
console.log(f("this 222a19e52"));
console.log(f("golfin5 3s24o0d4f3r3y3u"));
console.log(f("Prog2am0in6 Puz0les7&1Cod74G4lf"));
console.log(f("Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d."));


.charAt (...) можна замінити на [...] для економії 7 байт
fəˈnɛtɪk

x.charAt (...) еквівалентно x [...]
fəˈnɛtɪk

@ fəˈnɛtɪk Так, я думав, що я спробував це раніше, але це призвело до помилки. Дякую!
Том

1
o-m-1можна замінити на o+~m.
Ніл

2
Оскільки f називається рекурсивно, кількість символів програми повинна містити f=частину, тож це 54 байти, а не 52.
user5090812

5

Сітківка , 37 байт

Кількість байтів передбачає кодування ISO 8859-1.

\d
$*«»
r1+`(?<=(.)(?<-2>.)*)(«)*»
$1

Спробуйте в Інтернеті!

Пояснення

\d
$*«»

Замініть кожну цифру d на d « s, а потім - одну ». Нам потрібно останнє a), щоб ми могли розпізнати позиції, де d = 0 і b) як роздільник між сусідніми цифрами.

r1+`(?<=(.)(?<-2>.)*)(«)*»
$1

Неодноразово ( +) співставляйте регулярний вираз у першому рядку справа наліво ( r), а потім замініть найбільш лівий збіг ( 1) на заміну на другому рядку.

Сам регулярний вираз відповідає одній з наших нині одинакових цифр і підраховує кількість «s у групі 2. Подальший вигляд потім відповідає d символам, (?<-2>.)*перш ніж захоплювати згаданий символ у групі 1. Рядок «s, а »потім замінюється захопленим символом .


5

MATL , 21 19 17 16 байт

"@t4Y2m?UQ$y]]&h

Спробуйте в MATL Online!

Пояснення

        % Implicitly grab input as a string
"       % For each character in the input
  @     % Push that character to the stack
  t     % Make a copy of it
  4Y2   % Push the pre-defined array '0123456789' to the stack
  m     % Check if the current character is part of this array (a digit)
  ?     % If it is
    UQ  % Convert it to a number and add 1 (N)
    $y  % Make a copy of the element N-deep in the stack. MATL uses one-based indexing
        % So 1$y is the element at the top of the stack, 2$y is the next one down, etc.
  ]     % End of if statement
        % Non-digit characters remain on the stack as-is
]       % End of for loop
&h      % Horizontally concatenate the entire stack to form a string
        % Implicitly display the result

Приємного використання $yв новій версії!
Луїс Мендо

@LuisMendo Дякую! Мови на основі стека добре підходять для цього завдання
Suever

@LuisMendo На жаль, це можна було б скоротити ще більше, якби Uпрацювали лише для цифр. На жаль, 'e'Uурожай exp(1)інакше я міг би позбутися від цього 4Y2матеріалу
Suever

Ще одна з тих речей Октави ...
Луїс Мендо

4

JavaScript (ES6), 51 байт

f=
s=>s.replace(/\d/g,(c,i)=>a[i]=a[i+=~c]||s[i],a=[])
<input oninput=o.textContent=f(this.value)><pre id=o>

a використовується для зберігання замінених цифр для обробки цифр, що посилаються на інші цифри.


`` `s => s.replace (a = / \ d / g, (c, i) => a [i] = a [i + = ~ c] || s [i])` `
l4m2

3

Perl 5 , 34 байти

33 байти коду + -pпрапор.

s/\d/substr$_,-$&-1+pos,1/e&&redo

Спробуйте в Інтернеті!

s/\d/.../eзамініть першу цифру на ...оцінку як код Perl. ( ...маючи substr$_,-$&-1+pos,1в такому випадку. substr$_,-$&-1+pos,1повертає підрядок $_довжини 1за індексом -$&-1+pos, де $&число щойно збігається, і posє індекс початку матчу. Нам просто потрібно, redoякщо заміна була успішною, щоб замінити кожну цифру. (і результат неявно друкується завдяки -pпрапору).


Старий підхід, 47 байт:

44 байти коду + -Fпрапор.

map{$F[$i]=$F[$i-$_-1]if/\d/;++$i}@F;print@F

Спробуйте в Інтернеті!

Насправді прямо вперед. -Fпрапор розбиває введення кожного символу на @F. map{...}@Fповторюється @F(тобто кожен символ вводу). Якщо символ якщо цифра ( /\d/), то замінюємо його символом в індексі $i-$_-1. Це $iпоточна змінна індексу (яку ми підтримуємо, збільшуючи кожен бачений символ).


3

JavaScript ES6, 61 59 байт

Дякуємо @Luke за те, що ти граєш на 8 байт

x=>[...x].map((p,i,a)=>a[i]=/\d/.test(p)?a[i-1-p]:p).join``

Спробуйте в Інтернеті!


x.split``могло б бути [...x], [0-9]могло б \d, разом заощаджуючи 6B
Лука

Наразі десь є помилка, тому спочатку виправити це
fəˈnɛtɪk

x=>[...x].map((p,i,a)=>+p+1?a[i-1-p]:p).join``за 46 байт
Лука

Помилка для пробілів + "" дає 0, через що він
схоплює

x=>[...x].map((p,i,a)=>a[i]=1+p>9?a[i-1-p]:p).join``
l4м2


2

CJam, 13 байт

q{_A,s#)$\;}/

Демонстрація в Інтернеті

Це рішення використовує вбудований оператор CJam "копіювати n -й елемент на стек" $для здійснення декодування. Він починається з читання введення (з q), а потім циклічного перегляду символів із вхідного рядка та скидання їх на стек (з {}/). Однак усередині корпусу циклу він також дублює кожен символ після того, як він був поставлений на стек (з _), і перевіряє, чи є це цифрою, шукаючи його позицію #в рядку "0123456789", зручно представлений як A,s.

Результатом цього пошуку є або числове значення цифри, або, якщо символ не є цифрою, -1. Потім )оператор збільшує це значення на одиницю і $замінює його символьним струмом на стільки позицій під вершиною стека. Нарешті, \;просто видаляється копія поточного символу вводу, який ми зробили із _стека, оскільки він більше не потрібен.


2

Befunge-98 , 45 43 байт

::::#@~\1p:1g::'9`!\'/`*j;'/--1g\1p\1g#;,1+

Спробуйте в Інтернеті!

Ідея:

  1. Для кожного символу в рядку введення,
    1. Напишіть це у рядок 2
    2. Якщо це не число, просто виведіть його
    3. В іншому випадку знайдіть правильне значення, перепишіть його та виведіть його
::::            ; There's a counter on the stack, duplicate it 4 times  ;
    #@~         ; Get the next char of input, exiting if there is none  ;
       \1p      ; At the location (counter, 1), write the input char    ;
          :1g   ; Re-obtain the char. Stack is now [counter * 4, input] ;

::                ; Stack: [counter * 4, input * 3]      ;
  '9`!\'/`*       ; If !(input > '9') and (input > '/')  ;
                  ; IE If ('0' <= input && input <= '9') ;
           j;...; ; Then execute the ...                 ;

; Stack: [counter * 4, input] ;
; The ... branch:             ;

'/-             ; input -> int. (input -= '/')             ;
   -            ; counter - int(input) - 1                 ;
                ; Stack: [counter * 3, lookupPosition ]    ;
    1g          ; Get the char that we want to find        ;
      \1p\1g#   ; Overwrite the current char (not the old) ;

; Both branches: ;
,1+             ; Print the number and increment the counter ;

Я не зміг скоротити цю версію, але ця - 44 байти:

s #@~\3p:3g::'9`!\'/`*j;'/--3g#;:10g3p,1+:::

Думав, що я б поділився цим через акуратний трюк s- але зберігання лічильника на стеку призводить до цього покращення на 1 char



2

Python 2, 75 71 байт

s='';j=-1
for i in input():s+=s[j-int(i)]if'/'<i<':'else i;j+=1
print s

Спробуйте в Інтернеті!

Редагувати: Виправлено для значень ascii між 32-47 ; Виправлено для подвійного декодування (наприклад, "alp2c1" до "alpaca")


1
@Arnauld Nope. Вибачте, я недостатньо прочитав специфікацію. Невдовзі модифікую
математика наркоман

Здається, є помилка. для 'Prog2am0in6 Puz0les7&1Cod74G4lf'друку вашої програми Programming Puzzles &7Code1Golf! Я спробував з обома посиланнями TIO поділитися!
Keerthana Prabhakaran

@KeerthanaPrabhakaran Дякую! Виправлено ціною 0 байт! (Моє альтернативне рішення не вирізало)
математика наркоман

Це чудовий підхід!
Keerthana Prabhakaran

Чи можете ви пояснити '/' <i <':'. Я знаю, що це тестування, якщо це число, але як це працює?
Matias K

2

PHP 7,1 67 59 байт

while(_&$c=$argn[$i++])$t.=($c^"0")<"
"?$t[~+$c]:$c;echo$t;

Приймає дані від STDIN; запустіть як трубу -nRабо спробуйте в Інтернеті .

  • _&$c=$s[$i++]цикл через рядок (у _&$cрезультаті вийде щось, чого немає "0"; тому єдиним символом, який може порушити цикл, є порожній рядок = кінець вводу)
  • $c^"0" перемикання бітів 5 і 6 в коді ascii
  • <"\n" перевірити, чи результат <chr (10)
  • якщо так, то це цифра: друкувати попередній символ за індексом (і копіювати в поточний індекс)
  • ще друкуйте цього символу

Дякуємо @Christoph за економію 12%


1
Я знаю, що це стара відповідь, але: Негативні компенсації рядків! (і що $s=$argn...?)for(;_&$c=$argn[$i++];)$t.=($c^"0")<"\n"?$t[~+$c]:$c;echo$t;
Крістоф

2

Vim макро / натискання клавіш, 49 байт

^M представляють символ повернення (0x0A, 1 байт).

qqqqq/[0-9]^Myl:exe 'norm '.(@"+1).'h'^Mylnphx@qq@q

Пояснення

qqq                                                     clear register q
   qq                                                   record into q
     /[0-9]^M                                           move the cursor to the next digit
             yl                                         yank the digit
               :exe 'norm '.(@"+1).'h'^M                move the cursor left that number of characters plus one
                                        yl              yank the char
                                          n             go back to the digit
                                           p            paste the char 
                                            hx          delete the digit
                                              @q        recursive call
                                                q       stop recording
                                                 @q     run the macro

2

APL (Dyalog Classic) , 25 23 байти

-2 байти завдяки @FrownyFrog

((⊂⌷⊢)⍣≡⍳∘≢-11|⎕d∘⍳)⊃¨⊂

Спробуйте в Інтернеті!

використовує ⎕io←1

( нижче - проміжне значення в оцінці)

⎕d - це рядок '0123456789'

⎕d⍳⍵знаходить (у даному випадку на основі 1) індекси символів s у ⎕d; для нецифрового показника - 11

11|⍵ є модулем - 11 стають 0

≢⍵ - довжина

⍳≢⍵є 1 2 ...до≢⍵

таким чином, (⍳≢⍵)-11|⎕d⍳⍵дає нам вектор i індексів, куди нам слід шукати, щоб отримати отримані символи; однак деякі з цих індексів можуть перенаправлятись на інші (менші) індекси. Для обчислення транзитивного замикання (тобто ефективних показників) ми індексуємо вектор у себе ( ⊂⌷⊢потяг, еквівалентний (⊂i)⌷iабо i[i]) і повторюємо, поки він не стабілізується ( ⍣≡відомий як оператор фіксованої точки ).

нарешті індексуємо в початковий рядок: (...)⊃¨⊂


Як би це виглядало як поїзд?
FrownyFrog

@FrownyFrog дійсно, коротше
ngn


1

Джапт , 24 байти

£Xn >J?U=UhYUgJ+Y-X):PÃU

Спробуйте в Інтернеті!

Пояснення:

£Xn >J?U=UhYUgJ+Y-X):PÃU
£                     Ã    Iterate through the input (implicit U) 
                             X becomes the iterative item, Y becomes the index
 Xn                          Try parseInt(X)
    >J                       > -1
                               In this case, this checks if X is a digit
      ?                      If true:
       U=                      Set U to 
         UhY                     U with the char at index Y set to:     
            UgJ+Y-X               The index at -1+Y-X
                   ):        Else:
                     P         variable P (just a no-op in this case)
                       U   Finally, return U




1

JavaScript ES6, 54 байти

f=r=>[...r].reduce((a,s,i)=>a+(/\d/.test(s)?a[i+~s]:s))

f=r=>[...r].reduce((a,s,i)=>a+(/\d/.test(s)?a[i+~s]:s))

console.log(f("Prog2am0in6"));
console.log(f("abcd"));
console.log(f("a000"));
console.log(f("ban111"));
console.log(f("Hel0o W2r5d!"));
console.log(f("this 222a19e52"));
console.log(f("golfin5 3s24o0d4f3r3y3u"));
console.log(f("Prog2am0in6 Puz0les7&1Cod74G4lf"));
console.log(f("Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d."));


1
Ласкаво просимо до PPCG! Якщо вам не потрібна назва функції для рекурсивних дзвінків, неназвані функції є дійсними, тому ви можете зберегти два байти на f=.
Мартін Ендер

1

> <> (Риба), 108 байт (= сітка 9 х 12)

01-r>:0(\
"/"&::;?/
)?\v    \
":/v!?(":
")\ :>:"0
 !?\
${/  \ -1
&>\ ~{:&$
\ \ :"0"=
/\- 1}$/?
:v&//}~/~
 \o}\&$/ 

Спробуйте тут, щоб побачити рибу, яка плаває.

  • Додайте -1 до вхідного стеку, потім переверніть стек.
  • Цикл: Якщо верхнє значення дорівнює -1, то закінчуємо (ми пройшли цикл через усі символи). Інакше:
  • Поставте верхній символ у реєстр; перевірте, чи знаходиться в діапазоні "0" до "9". Якщо так:
    • поверніть стек на відповідну кількість місць
    • отримати персонаж, на який вказують
    • повернути назад і замінити номер символом з реєстру
  • Вихід; відновити цикл.

1

8086 машинного коду, 35 байт

00000000  be 82 00 ac 98 50 2c 30  3c 09 77 0c 4e 89 f7 4e  |.....P,0<.w.N..N|
00000010  29 c6 58 ac aa 89 fe 50  5a b4 02 cd 21 80 fa 0d  |).X....PZ...!...|
00000020  75 e1 c3                                          |u..|
00000023


1

Japt v2.0a0, 16 байт

r\d@=hYUgY-°X¹gY

Спробуй це


Пояснення

                     :Implicit input of string U
r                    :Replace
 \d                  :  RegEx /\d/g
   @                 :  Pass each match X at index Y through a function
     hY              :    Set the character at index Y in U
       UgY-°X        :    To the character at index Y-++X
    =        ¹       :    Reassign to U
              gY     :    Get the character at index Y

1

J , 20 байт

{~[:{~^:_#\-2+_1".,.

Спробуйте в Інтернеті

                  ,.  Each character on a separate row
              _1".    Convert to numbers, replacing non-numbers with -1
                         (it becomes one row again)
            2+        Add 2.
         #\           Prefix lengths (range 1..length)
           -          Subtract
  [:{~^:_             Index into itself as long as it changes the result
{~                    Index into the original string

Заслуга натхнення за натхнення.

22 байти

(],,{~1{._1-_1".[)/@|.

Це порт відповіді Желе.

                    |. The string backwards, because reduce is right-to-left.
            _1".[      The next character as a number (d), -1 if it's not a number,
                          and a space character produces an empty array.
         _1-           -1-d
      1{.              Take 1. If we have a nothing
                          at this point, that makes it a 0.
   ,                   Prepend the next character to the result of the previous call.
    {~                 Select the character. 0 is the first, _2 is second to last.
 ],                    Append the result.

В обох рішеннях версія, яку використовує TIO, інтерпретує сингл .як число 0, тому останній тест виявляється невдалим. Старіші версії (≤7), здається, працюють правильно.

Спробуйте в Інтернеті!

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