12
\$\begingroup\$

Based on a list of numbers and their equivalent letters, take a string input, replace the characters of that string with the equivalent number/letter and output the result.

List

  • 1 = a
  • 2 = b
  • 3 = c
  • 4 = d
  • 5 = e
  • 6 = f
  • 7 = g
  • 8 = h
  • 9 = i
  • 0 = j

Input

thisisastring1124

Output

t89s9s1str9n7aabd

Rules

  • Numbers are equivalent to lowercase letters only.
  • Any character outside the list will be left as is.
  • Input string must not contain spaces.
  • Either full program or function is permitted.
  • Since it's code-golf, fewest bytes wins.
\$\endgroup\$
5
  • 2
    \$\begingroup\$ Welcome to PPCG. Nice challenge! \$\endgroup\$
    – Adám
    Jul 4, 2018 at 6:03
  • 2
    \$\begingroup\$ May we swap uppercase letters instead? \$\endgroup\$
    – Adám
    Jul 4, 2018 at 6:03
  • \$\begingroup\$ Only lowercase letters, uppercase letters would be outside the scope of the list. \$\endgroup\$ Jul 4, 2018 at 6:10
  • \$\begingroup\$ Will the input contain only letters and numbers, or might other non-space characters (eg. punctuation) be in it? \$\endgroup\$
    – Sundar R
    Jul 4, 2018 at 22:18
  • \$\begingroup\$ Input string can contain any other character except spaces, but anything outside the list will be left untouched in the output string. \$\endgroup\$ Jul 6, 2018 at 4:05

23 Answers 23

14
\$\begingroup\$

bash, 18 bytes

tr 1-90a-j a-j1-90

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ How does this take input/give output? stdin and stdout? \$\endgroup\$
    – anon
    Jul 5, 2018 at 18:34
  • \$\begingroup\$ @NicHartley Yes. \$\endgroup\$
    – Doorknob
    Jul 5, 2018 at 20:44
10
\$\begingroup\$

Python 3, 76 68 bytes

lambda w:w.translate(dict(zip(s,s[::-1])))
s=b'1234567890jihgfedcba'

Try it online!

\$\endgroup\$
7
\$\begingroup\$

Perl 5, 17 bytes

y;a-j1-90;1-90a-j

Try it online!

\$\endgroup\$
7
\$\begingroup\$

Perl 6, 45 23 bytes

tr/1..90a..j/a..j1..90/

Try it online!

Just a plain transliteration regex.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Using TR would be shorter here, also you don't have to separate all those parts of the sequence: TR/1..90a..j/a..j1..90/ tio.run/##K0gtyjH7n1upoJamYKvwvzokSN9QT8/SIFFPL0sfRIB5@rX/… \$\endgroup\$
    – Phil H
    Jul 4, 2018 at 10:01
  • \$\begingroup\$ @PhilH Ha, I was literally just searching that operator up! Thanks! \$\endgroup\$
    – Jo King
    Jul 4, 2018 at 10:07
6
\$\begingroup\$

05AB1E, 13 9 bytes

žmÁAT£J‡

Try it online!

Explanation

žmÁ         # push 0987654321
   AT£      # push abcdefghij
      J     # join strings
       Â    # bifurcate
        ‡   # transliterate
\$\endgroup\$
5
\$\begingroup\$

Retina 0.8.2, 12 bytes

T`a-j09-1`Ro

Try it online! Explanation:

T``

Perform a transliteration.

a-j09-1

The source list is the letters a-j, then 0, then the digits 9-1.

Ro

The destination list is the source list reversed, i.e. the digits 1-9, then 0, then the letters j-a.

\$\endgroup\$
5
\$\begingroup\$

J, 38 bytes

rplc[:(;~"0|.)'9876543210jabcdefghi'"1

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Python 2, 82 78 bytes

lambda i,l='1234567890jihgfedcba':''.join((x,l[~l.find(x)])[x in l]for x in i)

Try it online!

-4 with thanks to @ovs

\$\endgroup\$
0
3
\$\begingroup\$

JavaScript (ES6), 66 bytes

s=>s.replace(e=/[1a2b3c4d5e6f7g8h9i0j]/g,c=>e[e.search(c)^1],e+=e)

Try it online!

\$\endgroup\$
3
\$\begingroup\$

R, 40 bytes

function(s)chartr("0-9ja-i","ja-i0-9",s)

Try it online!

Surprisingly, R is decent at this kind of challenge, because it has a tr-like function as in the Bash answer. No idea why it exists, but I'm grateful for it!

\$\endgroup\$
2
  • \$\begingroup\$ Amazing! Didn't know chartr() understood regex. \$\endgroup\$
    – snoram
    Aug 3, 2018 at 14:13
  • \$\begingroup\$ @snoram not quite regex; it specifies in the documentation that "Ranges are supported in the specifications, but character classes and repeated characters are not." \$\endgroup\$
    – Giuseppe
    Aug 3, 2018 at 15:02
3
\$\begingroup\$

MS-SQL, 71 bytes

SELECT TRANSLATE(v,'1234567890abcdefghij','abcdefghij1234567890')FROM t

The new SQL 2017 function TRANSLATE performs individual character replacement, so is ideally suited for this purpose. See my similar answer in a prior challenge.

Input is via a pre-existing table t with varchar column v, per our IO rules. To replace only lowercase letters, the table must be created using a case-sensitive collation:

CREATE TABLE t(v varchar(max) COLLATE Latin1_General_CS_AS)
\$\endgroup\$
2
\$\begingroup\$

Jelly, 16 bytes

⁵Øaḣ,ØDṙ1¤ċÞ⁸Ṛy)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Pyth, 13 bytes

Xz+jk+0_S9<GT

Try it here!

Explanation

Xz+jk+0_S9<GT – Full program.
       _S9    – Yield [9, 8, 7, ..., 1]
     +0       – Prepend a 0.
   jk         – Join to a single string.
  +       <GT – And append the first 10 letters of the alphabet to it.
                Yields 0987654321abcdefghij.
Xz            – Transliterates the input from the above to the above reversed.
\$\endgroup\$
2
\$\begingroup\$

Haskell, 80 66 bytes

map(!"1a2b3c4d5e6f7g8h9i0j")
e!(a:b:y)|e==a=b|e==b=a|1<2=e!y
e!_=e

Try it online!

\$\endgroup\$
1
\$\begingroup\$

REXX, 57 bytes

#=1234567890
a='abcdefghij'
say translate(arg(1),a #,# a)
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 81 72 bytes

Thanks to Giacomo Garabello for the suggestions.

f(char*s){for(;*s++=*s-97U<11?(*s-6)%10+48:*s-48U<11?(*s-9)%10+97:*s;);}

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ You can remove 6 chars by altering the input string instead of print it out putchar(...)-->*s=... and other 4 by replacing *s-48U<11 with *s<59 Try it online! \$\endgroup\$ Jul 5, 2018 at 15:37
  • \$\begingroup\$ @GiacomoGarabello *s<59 breaks if characters like $ are in the input, which is why I did *s-48U ([0..47] becomes [-48..-1], which becomes a large unsigned value.) As the question didn't specify whether non-alnums were valid, I went with the more conservative interpretation. \$\endgroup\$
    – ErikF
    Jul 5, 2018 at 16:01
  • \$\begingroup\$ Fair enough. The OP commented recently that every other character is valid but not the space. But you can still use my first suggestion \$\endgroup\$ Jul 6, 2018 at 8:23
  • \$\begingroup\$ 68 bytes \$\endgroup\$
    – ceilingcat
    Oct 17, 2021 at 19:47
1
\$\begingroup\$

Powershell, 94 bytes

-join($args|% t*y|%{if(1+($p=($s='1a2b3c4d5e6f7g8h9i0j').IndexOf($_))){$s[$p-bxor1]}else{$_}})

Test script:

$f = {
-join($args|% t*y|%{if(1+($p=($s='1a2b3c4d5e6f7g8h9i0j').IndexOf($_))){$s[$p-bxor1]}else{$_}})
}

&$f "thisisastring1124"

Explanation

  • $args - argument strings
  • $args|% t*y - expands to |ForEach-Object -Method ToCharArray equivalent of "$args".ToCharArray()
  • ($s='1a2b3c4d5e6f7g8h9i0j').IndexOf($_) - find a char in the string, returns a position or -1 if not found. Let $s stores the string which contains a paired char on neighbor positions that differ by the last bit: 0+1, 2+3, 4+5....
  • if(1+($p=...)) - if position was found
  • $p-bxor1 - position bit xor 1
\$\endgroup\$
1
  • \$\begingroup\$ Nice trick with the -bxor1. \$\endgroup\$ Jul 10, 2018 at 16:55
0
\$\begingroup\$

R, 107 bytes

function(s){a=utf8ToInt(s);l=a>96&a<107;n=a>47&a<58;a[n]=(a[n]-9)%%10+97;a[l]=(a[l]+4)%%10+48;intToUtf8(a)}

Try it online!

First attempt, definitely improvable...

\$\endgroup\$
3
  • \$\begingroup\$ chartr is your friend here, I think. \$\endgroup\$
    – Giuseppe
    Jul 4, 2018 at 21:40
  • 2
    \$\begingroup\$ tio.run/##FYgxCsAgDAD3PiOLBhS0dOnQx0jBGgcLSXx/… like that \$\endgroup\$
    – Giuseppe
    Jul 4, 2018 at 21:44
  • 1
    \$\begingroup\$ @Giuseppe : awesome! I didn't know of chartr function. Please post it as your answer, the approach is totally different ;) \$\endgroup\$
    – digEmAll
    Jul 5, 2018 at 7:28
0
\$\begingroup\$

Rust, 96 bytes

|x|x.bytes().map(|x|match
x{49..=57=>x+48,97..=105=>x-48,48=>106,106=>48,x=>x}as
char).collect()

Try it online!

Not Unicode-safe, if it was it would be even longer.

\$\endgroup\$
0
\$\begingroup\$

K4, 38 bytes

Solution:

{(,/|x,a)(,/a:0 1_'10 11#'.Q`a`n)?x}@'

Explanation:

Lookup each character in the list "abcdefghij1234567890" and then index into the list "1234567890abcdefghijX" where X is the original character.

Need to find a shorter way to build the strings...

{(,/|x,a)(,/a:0 1_'10 11#'.Q`a`n)?x}@'
{                                  }@' / apply (@) lambda {} to each (')
                                 ?x    / lookup x in
         (                      )      / do this together
                          .Q`a`n       / index into .Q with a (gives a-z) and n (gives 0-9)
                   10 11#'             / take 10 from first list and 11 from second list
              0 1_'                    / drop 0 from first list and 1 from second list
            a:                         / save as a
          ,/                           / flatten
 (      )                              / do this together
     x,a                               / prepend x to a
    |                                  / reverse it
  ,/                                   / flatten

Bonus:

Another solution for 38 bytes:

{(a,b,x)?[(b:1_11#.Q.n),a:10#.Q.a]x}@'
\$\endgroup\$
0
\$\begingroup\$

Yabasic, 135 bytes

Takes input from the console and outputs to the console.

Input""s$
For i=1To Len(s$)
c$=Mid$(s$,i,1)
n=asc(c$)-96
If-38>n Then?chr$(143+n+11^(n=-48));ElsIf n<11Then?n*(10>n),"";Else?c$;Fi
Next

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Japt, 44 42 bytes

V=1oA q +0+"jihgfedcba"Um@W=VaX)¦É?Vw gW:X

Try it online!

\$\endgroup\$
0
\$\begingroup\$

sed, 44 bytes

y/1234567890abcdefghij/abcdefghij1234567890/

A bit boring, I admit.

Testing:

$ echo 'thisisastring1124' | sed 'y/1234567890abcdefghij/abcdefghij1234567890/'
t89s9s1str9n7aabd
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.