让我们做一些“ enciph5r47g”


35

这是让我们做一些“ deciph4r4ng”的逆过程


在这个挑战中,您的任务是加密字符串。幸运的是,该算法非常简单:从左向右读取,每个典型的书写字符(ASCII范围32-126)必须替换为数字N(0-9),以表示它与字符N + 1相同之前的位置。例外是该字符未出现在原始字符串的前10个位置内。在这种情况下,您只需简单地再次打印字符。有效地,您应该能够从原始挑战中撤消操作。

输入字符串"Programming"将以这种方式编码:

例1

因此,预期输出为"Prog2am0in6"

澄清和规则

  • 输入字符串将仅包含32-126范围内的ASCII字符。您可以假设它永远不会为空。
  • 保证原始字符串不包含任何数字。
  • 字符一旦被编码,就可以由随后的数字来引用。例如,"alpaca"应编码为"alp2c1"
  • 引用永远不会环绕字符串:只能引用以前的字符。
  • 您可以编写完整的程序或函数,以打印或输出结果。
  • 这是代码高尔夫,所以最短的答案以字节为单位。
  • 禁止出现标准漏洞。

测试用例

Input : abcd
Output: abcd

Input : aaaa
Output: a000

Input : banana
Output: ban111

Input : Hello World!
Output: Hel0o W2r5d!

Input : this is a test
Output: this 222a19e52

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

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

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

6
我看到您的测试用例总是使用最低位数进行替换。如果存在多种可能性,这是必需的行为,还是我们也可以使用更高的数字?
Leo

@Leo您可以使用任何想要的0-9数字,只要它是有效的即可。
Engineer Toast

这就像是向前移动的编码器,但没有移动:)
管道

Answers:


6

05AB1E20 19 18字节

-2感谢Emigna

õ¹vDyåiDykëy}?yìT£

在线尝试!

õ                  # Push an empty string
 ¹v y              # For each character in input
   D               # Duplicate the string on the stack (call this S)
     åi            # If this character is in S
       Dyk         #   Push the index of that that character 
          ë }      # Else
           y       #   Push the character 
             ?     # Print without newline
              yì   # Prepend this character to S
                T£ # Remove all but the first 10 elements from S

我认为)¹vDyåiDykëy}?y¸ìT£效果也不错。
Emigna

实际上,将您的答案与我的答案相结合,得出的结果õIvDyåiDykëy}?yìT£是18 :)
Emigna

@Emigna随时更新:)
Riley

如果没有您的回答,我不会想到的,所以您应该拥有它。做得好!
Emigna

@Emigna我想这很公平。谢谢!
莱利

12

视网膜24 23字节

(.)(?<=\1(.{0,9}).)
$.2

在线尝试!

一个相当简单的正则表达式替换。我们匹配每个字符,并尝试在其之前找到0-9个字符的副本。如果找到它,我们将其替换为匹配该副本必须匹配的字符数。

结果与测试用例并不完全匹配,因为该用例使用最大可能的数字而不是最小可能的数字。


4
变长的后向作弊:p
Dada

8
@Dada变长的向后看是启发的方式。
Martin Ender

可悲的是...如果您很无聊,请随时在Perl中实现它们!
达达

根据OP对原始任务的评论,“只要有效,您就可以使用任何想要的数字0-9。” ...因此,最大的可能有效
Doktor J

@DoktorJ是的,我在OP添加该说明后更改了它。
Martin Ender

8

JavaScript(ES6),74 57 54字节

多亏了ETHproductions节省了3个字节,p=/./g而不是p={}(由Neil启发)

s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-11?~i:c)

测试用例


由于保证该字符串不包含数字,您可以使用s代替p吗?
尼尔,

find通过使用lastIndexOf,我能够超越您的原始版本,考虑到它的长度为11个字母,这有点令人惊讶。)
Neil

@Neil我现在不在电脑前,但是由于JS字符串是不可变的,所以我认为这不起作用。
Arnauld

2
我可以确认在字符串文字上设置属性无效。但是...看起来它确实可以与正则表达式一起使用,所以我认为您可以s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)节省3个字节。
ETHproductions'Apr

1
@YOU我真的不知道这里发生了什么,但是事实证明,我在上次编辑时为所有浏览器引入了一个错误。现在,此问题已解决。感谢您的关注!
Arnauld

7

Haskell72 66字节

感谢Laikoni打高尔夫球6个字节!

(a:r)%s=last(a:[n|(n,b)<-zip['0'..'9']s,b==a]):r%(a:s)
e%s=e
(%"")

在线尝试!

该函数%在其第二个参数中保持部分处理的字符串相反,因此它可以在此字符串的前10个元素中搜索要检查的字符的出现情况。提交包含一个未命名的函数(%""),该函数使用空字符串作为第二个参数来调用前一个函数。


f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])保存两个字节。
Laikoni '17

等待,f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]节省更多。
Laikoni'4-4-7

在旅途中进行颠倒而不是使用会reverse节省一个字节:在线尝试!
Laikoni'4-4-7

@Laikoni谢谢你,太好了!
Leo


3

Perl 5,36个字节

35个字节的代码+ -p标志。

s/(\D)(.{0,9})\K\1/length$2/e&&redo

在线尝试!

一些解释:
目标是替换一个非数字字符(\D但它对应\1于我的正则表达式中的向后引用),该字符前面的组长度(少于10个字符(.{0,9})和相同的字符((\D)... \1)开头.{0,9}length$2)。并且redo当字符被替换时。


显然.*不需要,在替换数字确定之前的范围内的任何有效字符。
colsw

@ConnorLSW是的,我刚刚看到挑战的更新并修改了我的答案,谢谢指出。
Dada

3

Python 2,89 84字节

m=input()[::-1];j=1;t=''
for i in m:s=m[j:].find(i);t=[i,`s`][0<s<10]+t;j+=1
print t

在线尝试!

反向遍历字符串,并使用正确的数字构建新的字符串。


3

Japt,18个字节

£¯Y w bX s r"..+"X

在线尝试!

说明

£   ¯  Y w bX s r"..+"X
mXY{s0,Y w bX s r"..+"X}
                          // Implicit: U = input string
mXY{                   }  // Replace each char X and index Y in U by this function:
    s0,Y                  //   Take U.slice(0,Y), the part of U before this char.
         w bX             //   Reverse, and find the first index of X in the result.
                          //   This gives how far back this char last appeared, -1 if never.
              s           //   Convert the result to a string.
                r"..+"X   //   Replace all matches of /..+/ in the result with X.
                          //   If the index is -1 or greater than 9, this will revert to X.
                          // Implicit: output result of last expression


2

05AB1E,20个字节

õIv¹N£RT£©yåi®ykëy}J

在线尝试!

说明

õ                     # push an empty string
 Iv                   # for each [index,char] [N,y] in input
   ¹N£                # push the first N characters of input
      R               # reverse
       T£             # take the first 10 characters of this string
         ©            # save a copy in register
          yåi         # if y is in this string
             ®yk      #   push the index of y in the string in register
                ë     # else 
                 y    #   push y
                  }   # end if
                   J  # join stack as one string

2

Python 3中,125个 118字节

def p(x):print(x,end='')
l={}
for i,c in enumerate(input()):
 if l.get(c,i+9)<i+9:
  p(i-l[c]-1)
 else:
  p(c)
 l[c]=i

在线尝试!


2

C(tcc),113字节

由于该函数创建了输入字符串的副本,因此输入的最大大小为98个字符(足以容纳最长的测试输入)。当然,可以将其更改为任何其他值。

i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j;j=-1;}

在线尝试!

编辑

-15个字节。感谢Johan du Toit


啊!将输入限制为98个字符,并节省一个字节!
管道

不错的解决方案,但您可以再保存15个字节: i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j,j=-1;}
Johan du Toit

@JohanduToit谢谢!我有一个问题。s [i]作为for循环的条件如何工作?我在这个网站上的其他人的答案中已经看到很多次了。
Maxim Mikhaylov

@Max Lawnboy。您最初具有以下内容:'s [i] ^'\ 0'',它是's [i]!='\ 0''的简写。字符\\ 0等于零,因此您可以这样写:'s [i]!= 0'。C语言中的if语句仅测试该值的取值为零或非零,因此不需要'!= 0'。
Johan du Toit


2

Java 7,102 101字节

void a(char[]a){for(int b=a.length,c;--b>0;)for(c=b;c-->0&c+11>b;)if(a[c]==a[b])a[b]=(char)(b-c+47);}

在线尝试!

-1个字节感谢Kevin Cruijssen。我总是很乐意使用go-to运算符。


为什么--c>=0呢?您可以将其替换c-->0为保存一个字节。
凯文·克鲁伊森

@KevinCruijssen我有点想知道我需要先递减,否则实际的计算将是错误的...不错!

1

MATL,31个 30字节

&=R"X@@f-t10<)l_)t?qV}xGX@)]&h

MATL在线上尝试一下

说明

        % Implicitly grab input as a string
&=      % Perform element-wise comparison with automatic broadcasting.
R       % Take the upper-triangular part of the matrix and set everything else to zero
"       % For each column in this matrix
X@      % Push the index of the row to the stack
@f      % Find the indices of the 1's in the row. The indices are always sorted in
        % increasing order
-       % Subtract the index of the row. This result in an array that is [..., 0] where
        % there is always a 0 because each letter is equal to itself and then the ...
        % indicates the index distances to the same letters
t10<)   % Discard the index differences that are > 9
l_)     % Grab the next to last index which is going to be the smallest value. If the index
        % array only contains [0], then modular indexing will grab that zero
t?      % See if this is non-zero...
  qV    % Subtract 1 and convert to a string
}       % If there were no previous matching values
  x     % Delete the item from the stack
  GX@)  % Push the current character
]       % End of if statement
&h      % Horizontally concatenate the entire stack
        % Implicit end of for loop and implicit display

您可能有点不满意,但是我超级无法告诉您哪里。输入this is a test产生this 222a1te52而不是this 222a19e52。第二个t不转换为9
Engineer Toast

@EngineerToast哈哈,谢谢。我会看看。
Suever

1

PHP,104字节

正解

for($i=0;$i<strlen($a=&$argn);$f[$l]=$i++)$a[$i]=is_int($f[$l=$a[$i]])&($c=$i-$f[$l]-1)<10?$c:$l;echo$a;

向后解决方案

在线版本

PHP,111字节

for(;++$i<$l=strlen($a=&$argn);)!is_int($t=strrpos($argn,$a[-$i],-$i-1))?:($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

PHP,112字节

for(;++$i<$l=strlen($a=&$argn);)if(false!==$t=strrpos($argn,$a[-$i],-$i-1))($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

在线版本


1

REXX,124125字节

a=arg(1)
b=a
do n=1 to length(a)
  m=n-1
  c=substr(a,n,1)
  s=lastpos(c,left(a,m))
  if s>0&m-s<=9 then b=overlay(m-s,b,n)
  end
say b

您可能有点不满意。我不知道REXX,但我想错误是在第7行s<9而不是s<10or s<=9。输入this is a test产生this 222a1te52而不是this 222a19e52。第二个t不转换为9在线尝试
Engineer Toast '04

谢谢,这是一个愚蠢的尝试,以减少一个字节。该代码已修复。
idrougge

1

C(gcc)117103字节

i,j;f(char*s){for(i=strlen(s)-1;s[i];i--)for(j=i-1;s[j]&&i-j<11;j--)if(s[i]==s[j]){s[i]=47+i-j;break;}}

在线尝试!

103个字节(不带string.h导入),带有警告。如果违反规定,我会拉

漂亮代码:

i,j;
f(char *s) {
    // Chomp backwards down the string
    for(i=strlen(s)-1; s[i]; i--)
        // for every char, try to match the previous 10
        for(j=i-1; s[j] && i-j < 11; j--)
            // If there's a match, encode it ('0' + (i-j))
            if (s[i] == s[j]) {
                s[i] = 47+i-j;
                break;
            }
}

编辑:

  • 从LLVM更改为gcc以允许隐式i,j声明,并删除了lib导入。
  • 添加了功能包装器以实现合规性

建议(i=strlen(s);s[--i];)而不是(i=strlen(s)-1;s[i];i--)
ceilingcat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.