Давайте сделаем немного «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.
Arnauld
источник
Можем ли мы получить входные данные в виде массива односимвольных строк? Можем ли мы предположить, что число никогда не будет больше 9?
fəˈnɛtɪk
@ fəˈnɛtɪk Относительно формата ввода: я бы сказал, нет, если только это не единственный приемлемый формат для вашего языка. Мы имеем дело с однозначными числами, а не числами. Так что да: это гарантированно будет <= 9, но вы можете встретить несколько цифр подряд.
Арно
Будет 1bbabли действительный вход (с ожидаемым результатом abbab)? Другими словами, могут ли ссылки обернуться вокруг строки?
Лука
@ Люк Хороший вопрос. Нет, 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

Haskell, 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);}
Steadybox
источник
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
Emigna
источник
Мне действительно нужно проверить, если вы уже ответили чаще, прежде чем начать.
Волшебная Урна Осьминога
@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), а затем замените самый левый метод match ( 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
Suever
источник
Приятного использования $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``

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

fənɛtɪk
источник
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, что заставляет его захватить предыдущий символ
fəˈnɛtɪk
x=>[...x].map((p,i,a)=>a[i]=1+p>9?a[i-1-p]:p).join``
l4m2
3

05AB1E , 27 17 байт

vyDdiU)DRXèU`X}}J

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

vy             }  # For each character
  Dd              #   Push is_number
    i         }   #   If it is
     U            #     Save save it
      )DR         #     Wrap the (reversed) stack into an array
         Xè       #     Get the character at the saved index
           U`X    #     Flatten the whole stack
                J # Join 
Райли
источник
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 символа

Джастин
источник
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" до "альпака")

математик наркоман
источник
1
@ Arnauld Нету. Извините, я недостаточно внимательно прочитал спецификацию. Скоро изменится
математик-наркоман
Кажется, есть ошибка. для 'Prog2am0in6 Puz0les7&1Cod74G4lf'вашей программы печатает Programming Puzzles &7Code1Golf! Я пытался с обеими ссылками TIO поделился!
Киртана Прабхакаран
@KeerthanaPrabhakaran Спасибо! Исправлено по стоимости 0 байт! (Мое альтернативное решение не сделало сокращение хотя)
математик наркоман
Это отличный подход!
Киртана Прабхакаран
Можете ли вы объяснить '/' <я <':'. Я знаю, это тестирование, если это число, но как оно работает?
Матиас К
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%

Titus
источник
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
TheFamilyFroot
источник
2

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

-2 байта благодаря @FrownyFrog

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

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

использования ⎕io←1

( ниже обозначено промежуточное значение в оценке)

⎕d это строка '0123456789'

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

11|⍵ по модулю - 11 становятся 0

≢⍵ длина

⍳≢⍵это 1 2 ...до≢⍵

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

наконец мы индексируем в исходную строку: (...)⊃¨⊂

СПП
источник
Как бы это выглядело как поезд?
FrownyFrog
@FrownyFrog действительно, короче
нгн
1

Python 2 , 83 80 байт

r=input()
for i in r:
 if'/'<i<':':r=r.replace(i,r[r.find(i)+~int(i)],1)
print r

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

  • сохранено 3 байта, но проверка ASCII вместо цифры! Спасибо math_junkie!
Киртана Прабхакаран
источник
1

Japt , 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 x 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
user5434231
источник
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

Благодарю ngn за вдохновение.

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), кажется, работают правильно.

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

FrownyFrog
источник