字母数字


15

有一个非常简单的密码,可以用字母在字母表中的位置代替字母。例如,abc将成1 2 3为此密码。

此挑战是对此密码的另一种选择。


挑战

创建一个程序,该程序需要输入ASCII字符,并输出以空格分隔的字符串:

  • -26通过整数26

  • a通过字母j

输出应通过STDOUT或您的语言最接近的替代品输出。


技术指标

  • 大写字母应否定。大写D的例子是-4,当一个小写d4

  • 数字应更改为对应的alpha。1a等等。输入中的任何零将为j

  • 所有非字母数字字符(空格除外)均应忽略。

  • 空格是0

  • 输出中的相邻空格应减少为单个空格。

    Input: You + Me
    Correct Output: -25 15 21 0 -13 5
    Incorrect Output: -25 15 21 0 0 0 -13 5
    
  • 允许使用单个尾随空格或换行符。


例子

Input: programming puzzles
Output: 16 18 15 7 18 1 13 13 9 14 7 0 16 21 26 26 12 5 19

Input: Code Golf
Output: -3 15 4 5 0 -7 15 12 6

Input: Programming Puzzles & Code Golf
Output: -16 18 15 7 18 1 13 13 9 14 7 0 -16 21 26 26 12 5 19 0 -3 15 4 5 0 -7 15 12 6

Input: C0d3 G0lf
Output: -3 j 4 c 0 -7 j 12 6

Input: abc_ABC
Output: 1 2 3 -1 -2 -3

记分板

为了使您的分数出现在黑板上,应采用以下格式:

# Language, Bytes

删除线不会引起问题。



输出的末尾可以有空格吗?
丹尼斯

是。允许使用单个尾随空格或换行符。@丹尼斯
扎克·盖茨

返回/打印字符串的函数是否是有效答案?您还可以添加一个测试用例,例如“ abc_ABC”来排除所有[^ \ w]和[\ W]正则表达式吗?
最多

我不确定您要问的是什么,但是我已经添加了该测试用例。我希望这就是您想要的;如果没有,请告诉我。@Max
Zach Gates

Answers:


10

CJam,58 57 54 51 50 49字节

在我写下解释时,我注意到可以选择将一个50字节版本缩短一个字节...

q_el_eu&S-A,s--S%S*{i_32md\2*5-*48md@)A%'a+\?}%S*

在这里测试。

50字节解决方案:

q_el_eu&S-A,s--S%S*{_A,s&\i_)A%'a+\32md\2*5-*?}%S*
q_el_eu&S-A,s--S%'`*{i32md:D;(_(2*(D*D3+A%'a+?}%S*
q_el_eu&S-A,s--S%'`*{i32md\(_@_@(2*(*\3+A%'a+?}%S*
q_el_eu&S-A,s--S%'`*{i32md\(_(2*(g@*_z3+A%'a+?}%S*

说明

q         e# Read input.
_el_eu&   e# Intersect a lower-case version with an upper-case version to remove
          e# all letters.
S-        e# Remove spaces from that string.
A,s-      e# Remove digit characters from that string. It now contains all the
          e# the characters from the input we should ignore.
-         e# Remove these characters from the input.
S%S*      e# Split on runs of spaces and join by spaces, collapsing multiple into one.
{         e# Map this block onto each character...
  i_      e#   Convert to character code and make a copy.
  32md    e#   Get divmod 32. Note that digits have character codes 32 + something,
          e#   the upper case letters have character codes 64 + n (where n is the 
          e#   absolute value we want), while lower case letters have codes 96 + n. 
          e#   So the div gives 2 or 3 to distinguish capitalisation (and 1 for digits) 
          e#   and the mod gives the correct absolute value for letters.
          e#   As it happens, the mod also gives 0 for spaces.
  \2*5-   e#   Pull up the div, duplicate, subtract 5. Turns 2 into -1 and 3 into 1. 
          e#   It also turns 1 (digits) into -3.
  *       e#   Multiply the mod by this sign.
          e#   We now have the correct result for everything but digits. Note that
          e#   the absolute value for digits is more than 26, and for everything
          e#   else it's less than 27.
  48md    e#   Get divmod 48. This gives div 0 and mod n for all correct results n.
          e#   For digits it gives div -1 and we don't care about the mod. We'll
          e#   use the div as a truthy/falsy value to select the right result.
  @)A%    e#   Pull up the other copy of the character code, increment 
          e#   (range 49..58), take modulo 10.
          e#   This gives 9 for 0 and n-1 for any other digit n.
  'a+     e#   Add to the character a.
  \?      e#   Select the correct result based on the div 48.
}%
S*        e# Join the resulting values by spaces.

这必须是第一次,CJam的负值模数行为对我很有用。


6

的JavaScript(ES6),110个 107 133 120字节

收下,老我!

a=>[...a.replace(/[\W_]*?( ?)[\W_]*/g,'$1')].map(x=>(c=x.charCodeAt())<40?0:c<60?'jabcdefghi'[x]:c<91?64-c:c-96).join` `

打高尔夫球的空间可能更大,尤其是在正则表达式中,这样可以很好地降低高尔夫球的速度。非高尔夫版本:

function f(a) {
  // Replaces each run of bad chars and spaces with
  // a space if it contained one, nothing otherwise:
  a = a.replace(/[\W_]*?( ?)[\W_]*/g, '$1');

  var b = a.split('');
  b = b.map(function(x) {
    var c = x.charCodeAt();
    if (c == 32)     // space
      return 0;
    else if (c < 60) // numbers
      return 'jabcdefghi'.charAt(x);
    else if (c < 91)
      return 64 - c; // uppercase
    else
      return c - 96; // lowercase
  });
  b = b.join(' ');
  return b;
}

建议欢迎!


测试'123___abc'。提示:您需要处理下划线
edc65

另一个问题:All non-alphanumeric characters should be ignored.。测试:“ A $ b”应为-1 2
edc65

@ edc65噢,伙计,我以为我已经完成了...但是谢谢你让我知道!
ETHproductions 2015年

4

Pyth,50 49字节

jdm?>d26C+70ddm-xZd26:-z-z=Zs[_rG1dGjk.<UT1)" +"d

在这里尝试。

编辑:重组字符串卫生以确保正确处理下划线。它甚至还节省了一个字节,是的!

该程序创建一个查找字符串,该字符串用于清理输入。然后将其映射到该字符串中的相应索引。最后,任何大于26的索引都将转换为正确的ASCII字符。

                                                     Implicit: z=input(), d=' ', ,
                                                       k='', G=[a-z]
                              _rG1                   Reversed, capitalised alphabet
                                  d                  Single space
                                   G                 Lower case alphabet
                                    jk.<UT1          '1234567890'
                            s[             )         Concatenate the 4 previous statements
                          =Z                         Store in Z
                        -z                           Setwise difference of input and above
                                                       (to get all illegal characters)
                      -z                             Setwise difference of input and illegal chars
                     :                      " +"d    Regex replace to lose multiple spaces
              m                                      Map the above over d:
                xZd                                    Get index of d in Z
               -   26                                  Subtract 26
  m                                                  Map the above over d:
   ?>d26                                               If d > 26
        C+70d                                            Convert (d+70) to ASCII
             d                                         Otherwise, select d
jd                                                   Join on spaces and print

使用\W正则表达式的上一版本(50字节):

jdm?>d26C+70ddm-xs[_rG1\ Gjk.<UT1)d26::z"\W"d" +"d

3

利亚,145个 136字节

r=replace;print(join([47<x<58?x+58-10(x>48):x==32?0:cmp(x,96)*(lowercase(x)-96)for x=r(r(readline(),r"[^a-z0-9 ]"i,""),r" +"," ")]," "))

取消高尔夫:

# Read a string from STDIN
input = readline()

# Remove non-alphanumeric characters and replace duplicated spaces
r = replace(replace(input, r"[^a-z0-9 ]"i, ""), r" +", " ")

# Construct an array using comprehension over the replaced input string
A = [47 < x < 58 ? x + 58 - 10(x > 48) : x == 32 ? 0 : cmp(x, 96) * (lowercase(x) - 96) for x = r]

# Join the array elements with spaces
j = join(A, " ")

# Print to STDOUT
print(j)

为了使数字成为字母,我们在ASCII值上加58,如果当前字符不为0,则减去10。这确保0映射到j,其他数字映射到a- i

可以使用否定大写字母cmp。大写字母将返回-1,小写字母将返回1。

在线尝试


2

Perl 5中,120 116 113 105字节

首先清理不需要的字符和多余的空格。
然后沿着每个字符的ascii表爬下。

$_=pop;s/[^\w ]|_//g;s/ +/ /g;map{$n=ord;say$".($n>96?$n-96:$n>64?64-$n:$n>48?chr$n+48:$n>47?j:0)}split//

测试

$ perl -M5.01 numbers4letters.pl "zZaA _ 190"
 26 -26 1 -1 0 a i j
$ perl -M5.01 numbers4letters.pl "PrOgr4mm1n9 Puz2l3s & C0d3_G0lf!"
-16 18 -15 7 18 d 13 13 a 14 i 0 -16 21 26 b 12 c 19 0 -3 j 4 c -7 j 12 6

2
您可以在正则表达式中用一个空格代替\ s来打一个字符,而第二个正则表达式可以用来打高尔夫球s/ +/ /g,第一个正则表达式是错误的,因为\ w与下划线字符匹配
Max

2
另外两个字符出与s/[^\w ]|_//g
马克斯

很好,甚至比使用ignore case标志更好。
LukStorms

@Max很好的提示。我的答案中保存了2个字节,谢谢。
edc65

2

C,142 138 135

c,d;main(s){while(c=getchar()+1)d=c|32,c=d-98<26u?s=(d-97)*(c/32*2-5),0:c-48<11u?s='a'+c%10,4:c==33&&s?s=0,0:3,printf("%d \0%c "+c,s);}

放开一点:

int c,d;
int main(int s)                     // s initially non-zero, meaning spaces are allowed
{
    while(c=getchar()+1)            // getchar until EOF (-1) encountered
    {
        d=c|32;                     // d becomes lowercase c (both incremented by 1)
        if (d-98<26u)               // check for letter
        {
            s=(d-97)*(c/32*2-5);    // print this number and allow subsequent spaces
            c=0;                    // format string will be "%d "
        }
        else if (c-48<11u)          // check for digit
        {
            s='a'+c%10;             // print this letter and allow subsequent spaces
            c=4;                    // format string will be "%c "
        }
        else if (c==33&&s)          // else if space and allowed to output spaces
        {
            s=0;                    // print 0 and disallow subsequent spaces
            c=0;                    // format string will be "%c "
        }
        else
        {
            c=3;                    // format string will be "", prints nothing
        }
        printf("%d \0%c "+c,s);     // final c is treated as index into string literal
    }
}

通过GCC 4.9.3和Clang 3.5.2中的给定测试。


2

> <>(鱼),219209字节

>i:84*=?v:86*1-)?!^:f4*2-(?v:88*)?!v:a9*1+(?v:c8*)?!^:ca*3+  (?v~
>4*(?vov>~86*$:@=?v86*00.  >:86*=?v77*1-+00.>88*-::-$-00.01-*8c<
 >.! ! ! 00~v?( 0:\00. >.!00+6*aa~<>~    92*2!.<2*29<
^7:;?=0:<r0~<
*o73.>n>84

在这里尝试

这是我第一个打高尔夫的代码!最终,我能够使用我想在高尔夫挑战赛中使用的语言,而且考虑到字符会自动转换为小数,因此这似乎是完美的选择。

我希望结果会短一些,但显然不会。不过,我还没有打太多。在某些地方,代码可能更干净/更有意义,但由于它们始终需要空格,因此不会保存任何字节。可能有一种方法可以在第二行的最后一位上保存一些字节,使其朝相反的方向并与已经存在的00混搭,我将不得不在以后再使用它

基本上,这通过检查当前字符是否在该组的最高/最低值范围内来检查其是否为空格,数字,大写字母或小写字母。如果这些都不是,它将被丢弃。如果在其中之一中,则将其转换为数字(如果是字母),并且将其转换为数字(或者更确切地说,是97-106之间的数字,它们是字母aj的值)。然后,它检查最上面的值是否小于28,在这种情况下,它是一个数字并输出一个数字,否则它是一个字母并输出该数字代表的字母,输出一个空格,然后循环直到堆栈为空。


2

的JavaScript(ES6),108 122 124

编辑从@马克斯的评论使用正则表达式
EDIT2 14个字节保存感谢ETHProductions

EcmaScript 6仅用于箭头功能,因此它应可在Firefox和最新的Chrome浏览器中使用。

测试下面的代码段

F=
t=>t[R='replace'](/[^\w ]|_/g,'')[R](/ +|./g,c=>((v=parseInt(c,36))>9?c>'Z'?v-9:9-v:'jabcdefghi'[v]||0)+' ')

// Less golfed
U=t=>
  t.replace(/[^\w ]|_/g,'') // remove invalid characters
  .replace(/ +/g,' ') // collapse spaces
  .replace(/./g, c => ( // valid character replacing
    v = parseInt(c,36), // '0'..'9'-> 0..9, 'a'..'z' -> 10..25, ' ' -> NaN
    (
      v > 9 
      ? c > 'Z' ? v-9 : 9-v // manage upper vs lower
      : 'jabcdefghi'[v] || 0 // digits, NaN as an index gives undefined, substituted with 0
    ) + ' ' // separator space
  ))


// TEST
out=x=>O.textContent=x+'\n'+O.textContent;

function go() { out(I.value + ' --> ' + F(I.value) +'\n')}

// test cases, a trailing blank added to the expected output as ...
// "A single trailing space or newline is allowed."

;[
  ['A$b','-1 2 ']
, ['123___abc', 'a b c 1 2 3 ']
, ['You + Me','-25 15 21 0 -13 5 ']
, ['programming puzzles', '16 18 15 7 18 1 13 13 9 14 7 0 16 21 26 26 12 5 19 ']
, ['Code Golf', '-3 15 4 5 0 -7 15 12 6 ']
, ['Programming Puzzles & Code Golf', '-16 18 15 7 18 1 13 13 9 14 7 0 -16 21 26 26 12 5 19 0 -3 15 4 5 0 -7 15 12 6 ']
, ['C0d3 G0lf', '-3 j 4 c 0 -7 j 12 6 ']
].forEach(t=>{ 
  k=t[1],r=F(t[0]), 
  out('Test '+(k==r?'OK':'Fail')+'\nInput:  '+t[0]+'\nResult: '+r+'\nCheck:  '+k+'\n')
})
Custom test: <input id=I><button onclick='go()'>-></button>
<pre id=O></pre>


我可能会误会,但是我认为您可以通过更改[R](/ +/g,' ')[R](/./g,为来节省一大笔钱[R](/ +|./g,。(对不起,提出一个旧帖子,顺便说一句)
ETHproductions'Apr 25'17

@ETHproductions看起来不错。谢谢
edc65


1

CJam,52个字节

'{,97>:L_eu+A,s(++S+l{1$&},S%S*\26,:)_Wf*+LA<+0+erS*

在线尝试

解决方案的关键部分是它使用CJam er(音译)运算符。作为运算符的参数,它需要所有字符的列表以及相应值的列表。

作为输入的预处理步骤,它将删除不属于转换表的字符(特殊字符),并将重复的空格减少为单个空格。

说明:

'{,97>  Build list of all lower case letters.
:L      Save it in variable L for later reuse.
_eu+    Add list of upper case letters.
A,s     Build digits "0123456789".
(+      Pop off first digit and append it at the end, to get "1234567890".
+       Add digits to list of characters.
S+      Add a space. List of characters that have values is now complete.
l       Get input.
{1$&},  Filter out all input characters that are not in list.
S%      Split input at spaces.
S*      And re-assemble it with spaces. This reduces multiple spaces to one space.
\       Swap input and character list.
26,     Start building list of values. Start with [0 ... 25].
:)      Use "smilie operator" to increment all values, to get [1 ... 26].
        These are the values for the lower case letters.
_Wf*    Copy the list and negate the values to get [-1 ... -26] for upper case.
+       Concatenate the two lists.
L       Retrieve the list of lower case letters we saved away earlier.
A<      Keep the first 10, which are the values for the digits.
+       Concatenate to list of values.
0+      Add 0 to list, as value for space.
er      Transliterate input string to corresponding values.
S*      Join with spaces for output.

1

Python 2中,191个 179 177 173 172 168 160字节

import re
print" ".join([[[chr(x+48),"j"][x<49],[`[x-96,-x+64][x<96]`,"0"][x<65]][x>57or x<33]for x in map(ord,re.sub(" +"," ",re.sub("[^\w ]|_","",input())))])

测试

"programming puzzles"
16 18 15 7 18 1 13 13 9 14 7 0 16 21 26 26 12 5 19

"Code Golf"
-3 15 4 5 0 -7 15 12 6

"Programming Puzzles & Code Golf"
-16 18 15 7 18 1 13 13 9 14 7 0 -16 21 26 26 12 5 19 0 -3 15 4 5 0 -7 15 12 6

"C0d3 G0lf"
-3 j 4 c 0 -7 j 12 6

"You + Me"
-25 15 21 0 -13 5

1

PHP,116字节

while($c=ord(preg_replace(["#[^\w ]|_#","# +#"],["","@"],$argn))[$i++])echo$c<96?jabcdefghi[$c-48]?:64-$c:$c-96," ";

接受STDIN的输入;与运行-nR

分解

while($c=ord(preg_replace(["#[^\w ]|_#","# +#"],["","@"],$argn) # sanitize input
    [$i++]))echo            # loop through string and print ...
    $c<96                       # if not lowercase:
        ?jabcdefghi[$c-48]          # digit -> letter
        ?:                          # if that turned out falsy (=empty):
        64-$c                       # uppercase (or former spaces) -> negative (or 0)
    :$c-96                      # else -> positive
," ";                           # append space

您可以@使用反引号代替来处理小写部分中的空格。
对于jabcdefghi0数字,您还可以使用:


我相信您必须更改订单"#_|[^\w ]#"而不是"#[^\w ]|_#"
—JörgHülsermann17年

0

Hassium,1156字节

func main() {s = input();c="";for(x=0;x<s.length;x++){c=s[Convert.toNumber(Convert.toString(x))].toString();if (c.toLower()!=c)print(r(c.toLower())*-1);else if(r(c)=="")continue;else print(r(c));print(" ");}}func r(c) {if(c=="a")return 1;else if(c=="b")return 2;else if(c=="c")return 3;else if(c=="d")return 4;else if(c=="e")return 5;else if(c=="f")return 6;else if(c=="g")return 7;else if(c=="h")return 8;else if(c=="i")return 9;else if(c=="j")return 10;else if(c=="k")return 11;else if(c=="l")return 12;else if(c=="m")return 13;else if(c=="n")return 14;else if(c=="o")return 15;else if(c=="p")return 16;else if(c=="q")return 17;else if(c=="r")return 18;else if(c=="s")return 19;else if(c=="t")return 20;else if(c=="u")return 21;else if(c=="v")return 22;else if(c=="w")return 23;else if(c=="x")return 24;else if(c=="y")return 25;else if(c=="z")return 26;else if(c==" ")return 0;else if(c=="1")return "a";else if(c=="2")return "b";else if(c=="3")return "c";else if(c=="4")return "d";else if(c=="5")return "e";else if(c=="6")return "f";else if(c=="7")return "g";else if(c=="8")return "h";else if(c=="9")return "i";else if(c=="0")return "j";else return"";}

很长的答案


1
折叠的空间似乎不太起作用。You + Me产生输出-25 15 21 0 0 -13 5
丹尼斯

1
有趣的语言,有点像C / Java / [另一种语言,我不记得它的名称]。有没有一种简单的方法可以将每个字符转换成数字,即检索字符代码的函数?(向下滚动至表格并查看该Dec列。)
ETHproductions 2015年

0

果冻,32字节,语言发布日期挑战

⁶ØB;µ³fi@€
Øaḣ⁵ṙ9
26RµN;;0¢;ị@ÑK

在线尝试!

说明

辅助函数1Ŀ(将输入中的每个字母数字/空格转换为数字)

⁶ØB;µ³fi@€
⁶           space
 ØB;        append all digits, uppercase and lowercase letters (in that order)
    µ       set as the new default for missing arguments
     ³      first command-line argument
      f     delete all characters not in {space + alphanumerics}
       i@€  take index of each element within {space + alphanumerics}

辅助函数(返回常量字符串“jabcdefghi”

Øaḣ⁵ṙ9
Øa      lowercase alphabet
  ḣ⁵    take first 10 elements
    ṙ9  rotate 9 elements to the left

主程序

26RµN;;0¢;ị@ÑK
26R             Range from 1 to 26
   µ            set as default for missing arguments
    N           Minus {each element of the range from 1 to 26}
     ;          with {the range from 1 to 26} appended
      ;0        with a 0 appended
        ¢;      with the result of 2£ prepended
          ị@    index into this using
            Ñ   the result of 1Ŀ
             K  separate by spaces

0

视网膜,74 70字节(非竞争)

请注意第3行的前导空格,第6行的尾随空格和第二行为空。

[^ \ w] | _

 +
〜
。
$ + 
[AZ]
-$ +
`
[js]
a $ +
[tz]
b $ +
T`〜ld`dd0-6jl

在线尝试!

尽管语言是在挑战之前提出的,但我认为我在挑战之后使用了某些语言功能,因此我将其标记为非竞争。


0

Java 7中,257个 254字节

class M{public static void main(String[]a){String r="",x;for(int c:a[0].getBytes()){x=(c>96&c<123?c-96:c>64&c<91?"-"+(c-64):c>48&c<58?(char)(c+48):c==48?"j":c<33?0:"")+"";r+=!x.isEmpty()&&!(r.endsWith("0 ")&x.equals("0"))?x+" ":"";}System.out.print(r);}}

在这里尝试。

说明:

class M{                               // Class
  public static void main(String[]a){  //  Required main-method
    String r="",                       //   Result-String
      x;                               //   Temp String
    for(int c:a[0].getBytes()){        //   Loop over the characters of the input-String
      x=(                              //    Set the temp String to:
        c>96&c<123?                    //     If it's a lowercase letter:
          c-96                         //      Set `x` to the 1-indexed alphabetic index
        :c>64&c<91?                    //     Else-if it's a uppercase letter:
          "-"+(c-64)                   //      Set `x` to the 1-indexed alphabetic index as negative
        :c>48&c<58?                    //     Else-if it's a digit 1-9:
          (char)(c+48)                 //      Set `x` to the 1-indexed alphabetic character
        :c==48?                        //     Else if it's a zero:
          "j"                          //      Set `x` to "j"
        :c<33?                         //     Else if it's a space:
          0                            //      Set `x` to "0"
        :                              //     Else:
          ""                           //      Set `x` to an empty String
       )+"";                           //     Required `+""` because `(char)` and `0` aren't Strings
      r+=                              //    Append the result-String with:
        !x.isEmpty()                   //     If `x` has a value
        &&!(r.endsWith("0 ")&x.equals("0"))?
                                       //     and it's not "0" with the previous value also being a zero
          x+" "                        //      Append the value of `x`, plus a space
        :                              //     Else:
          "";                          //      Append nothing
    }                                  //   End of loop
    System.out.print(r);               //   Print the result to STDOUT
  }                                    //  End of main-method
}                                      // End of class

输入和输出示例:

Input:
Programming Puzzles & C0d3 G0lf

Output:
-16 18 15 7 18 1 13 13 9 14 7 0 -16 21 26 26 12 5 19 0 -3 j 4 c 0 -7 j 12 6 
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.