36
\$\begingroup\$

My friend made a lisp translator the other day, that is to say it took a string and converted s=>th and S=>Th. It was quite long and I thought that it could be golfed.

So the task is to make a program/function that takes an input string, translates it in to lisp and outputs the string

Test case

Sam and Sally like Sheep        Tham and Thally like Thheep
Sally likes sausages            Thally liketh thauthageth
Sally sells seashells           Thally thellth theathhellth

Note that it doesn't matter that h gets repeated all the time

This is code golf so shortest answer wins

\$\endgroup\$
10
  • 18
    \$\begingroup\$ I wished everyone would change the bytes in their headers to byteth. \$\endgroup\$
    – Leaky Nun
    Jun 17, 2016 at 17:14
  • 7
    \$\begingroup\$ There should be bonus points if the program doesn't use s nor S anywhere in it. \$\endgroup\$ Jun 17, 2016 at 18:41
  • 5
    \$\begingroup\$ A thing that would have made this challenge more interesting would be overall case preservation, e.g. LOOK OUT A SNAKE!!! -> LOOK OUT A THNAKE!!! \$\endgroup\$
    – fluffy
    Jun 18, 2016 at 3:06
  • 4
    \$\begingroup\$ @fluffy after writing the question I did realise a case like that would fail, but it is too late to change now \$\endgroup\$
    – george
    Jun 18, 2016 at 7:37
  • 3
    \$\begingroup\$ Welcome to Programming Puzzleth & Code Golf! That Ith a Good quethtion and thothe help the community a lot! \$\endgroup\$
    – user54200
    Jul 5, 2016 at 10:15

58 Answers 58

40
\$\begingroup\$

Common Lithp, 62

(map()(lambda(u)(princ(case u(#\s"th")(#\S"Th")(t u))))(read))

First, (read) the input (it should be a string). Strings in CL are sequences so we use map to iterate on each character. The first argument to map represents the type of the result (e.g. I could build a list from a vector). When it is nil, a.k.a. (), results are discarded. The function that is mapped to the input simply princ (print non-readably) each character, except the ones that should be replaced.

\$\endgroup\$
8
  • 16
    \$\begingroup\$ That language name though. \$\endgroup\$
    – Joe Z.
    Jun 17, 2016 at 15:02
  • 2
    \$\begingroup\$ @JoeZ. I just replaced the s by th, like everybody else did: look at those Pyson answers. \$\endgroup\$
    – coredump
    Jun 17, 2016 at 16:04
  • \$\begingroup\$ @coredump They're all wrong: it's one-way: s->th, S->Th, th->th, Th->Th. \$\endgroup\$ Jun 17, 2016 at 16:05
  • 1
    \$\begingroup\$ @DrGreenEggsandIronMan Sure, (defmacro cathe (&rest args) `(case ,@args)) \$\endgroup\$
    – coredump
    Jun 17, 2016 at 18:07
  • 1
    \$\begingroup\$ Ok lol that makes more sense \$\endgroup\$
    – user54200
    Jul 5, 2016 at 15:20
17
\$\begingroup\$

Retina, 9 bytes

S
Th
s
th

Try it online!

The obvious answer.

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

JavaThcript ETh6, 38 bytes

At first I went with the obvious solution

a=>a.replace(/s/g,'th').replace(/S/g,'Th')

But I golfed it down 4 bytes

a=>a.replace(/s/gi,b=>b>'r'?'th':'Th')

This makes use of the regex i flag, which searches for case-insensitive patterns. The good thing about Javascript is that you can specify an anonymous function to handle (regex) replacing.

Try it here

f=
a=>a.replace(/s/gi,b=>b>'r'?'th':'Th')

s.innerHTML = [
    'abScdsefSghsij',
    'Sam and Sally like Sheep',
    'Sally likes sausages',
    'Sally sells seashells'
].map(c=>c + ' => ' + f(c)).join`<br>`
<pre id=s>

\$\endgroup\$
6
  • 11
    \$\begingroup\$ "E eth thickth"? \$\endgroup\$
    – Joe Z.
    Jun 17, 2016 at 15:02
  • \$\begingroup\$ I was thinking in 'Tt'[b>'r']+'h', but it is the same length \$\endgroup\$ Jun 17, 2016 at 18:48
  • 2
    \$\begingroup\$ You mean 38 byteth \$\endgroup\$
    – Downgoat
    Jun 17, 2016 at 19:41
  • \$\begingroup\$ +1 for TIL that string comparison is done via Code Point Value \$\endgroup\$
    – bren
    Jun 17, 2016 at 21:08
  • \$\begingroup\$ @Upgoat That was my fault sorry. \$\endgroup\$
    – Neil
    Jun 19, 2016 at 22:57
11
\$\begingroup\$

GNU Sed - 17

s/S/Th/g;s/s/th/g

The obvious answer.

$ sed -e "s/S/Th/g;s/s/th/g"

Sam and Sally like Sheep
Tham and Thally like Thheep

Sally likes sausages
Thally liketh thauthageth

Sally sells seashells
Thally thellth theathhellth
\$\endgroup\$
1
  • 18
    \$\begingroup\$ Did you mean GNU Thed? ;) \$\endgroup\$
    – m654
    Jun 17, 2016 at 15:57
10
\$\begingroup\$

Jelly, 13 bytes

“Ss”,“Th“th”y

Thhowing off Jelly'th thhiny new tranthlate atom. Try it online!

\$\endgroup\$
8
\$\begingroup\$

Python 3 - 40 byteth

First golfing!

lambda s:s.translate({115:'th',83:'Th'})

It uses the str module's translate method which accepts a translation table. The translation table is a simple dict with keycode as keys and the str in place of it as value.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to the PP&CG community! \$\endgroup\$ Jun 17, 2016 at 15:23
  • 5
    \$\begingroup\$ Can I ask you, why you have 2 separate accounts? \$\endgroup\$
    – Bálint
    Jun 17, 2016 at 20:50
  • \$\begingroup\$ @Bálint Apparently, he forgot to log into his current account with only 3 rep, but an experience on Stack Overflow. And posted with a new account. \$\endgroup\$
    – user48538
    Jun 18, 2016 at 7:54
6
\$\begingroup\$

JavaThcript ETh6, 43 byteth

s=>s.replace(/s/gi,m=>({s:'th',S:'Th'})[m])

Tetht Thuite:

th=s=>s.replace(/s/gi,m=>({s:'th',S:'Th'})[m])
  
console.log(th('Sam and Sally like Sheep'));
console.log(th('Sally likes sausages'));
console.log(th('Sally sells seashells'));

\$\endgroup\$
1
  • 7
    \$\begingroup\$ Confethth: thou only wroteth that tetht thuite for the thake of itth title! \$\endgroup\$ Jun 18, 2016 at 0:21
6
\$\begingroup\$

V, 11 byteth

Ís/th
ÍS/Th

Try it online!

V ith a language I made. It'th not finithed, but it'th really good at regekth.

\$\endgroup\$
6
\$\begingroup\$

05AB1E, 14 12 bytes

's„th:'S„Th:

The straight forward answer.

Try it online

Saved 2 bytes thanks to @Adnan

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Isn't this the thtraight forward anthwer rather than the straight forward answer? \$\endgroup\$
    – SE is dead
    Jul 17, 2016 at 2:59
5
\$\begingroup\$

C, 50 bytes

s(c){c=getchar();c+=c-83&95?0:'h\1';s(printf(&c));}

Replace \1 with an actual \x01 byte.

jimmy23013 saved a byte, and then I saved two more using his approach! Thanks.

\$\endgroup\$
4
  • \$\begingroup\$ I was about to comment that the &c parameter is broken. But it's not, because on a little-endian architecture the second byte of that int will be 0x00 and actually terminate the "string"... This is horribly clever, I love it ! \$\endgroup\$
    – Quentin
    Jun 17, 2016 at 13:51
  • \$\begingroup\$ s(c){c=getchar();c+=c-83&~32?0:26625;s(printf(&c));} \$\endgroup\$
    – jimmy23013
    Jun 17, 2016 at 13:58
  • \$\begingroup\$ You can't push 2 bytes into a char. 'h\1' \$\endgroup\$ Jun 18, 2016 at 7:53
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Multi-character constants are implementation defined, bu perfectly valid C. \$\endgroup\$
    – Dennis
    Jul 5, 2016 at 2:23
4
\$\begingroup\$

Java, 71 65 bytes

String t(String s){return s.replace("S","Th").replace("s","th");}

First attempt at golfing, so why not with Java.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ You can use replace instead of replaceAll \$\endgroup\$ Jun 17, 2016 at 12:23
  • \$\begingroup\$ Oh, yeah you're right. Thanks! @aditsu \$\endgroup\$
    – Insane
    Jun 17, 2016 at 12:25
  • 3
    \$\begingroup\$ You can save some bytes by using a lambda expression instead of a function. s->s.replace("S","Th").replace("s","th") \$\endgroup\$
    – Denker
    Jun 17, 2016 at 12:45
4
\$\begingroup\$

GNU AWK, 31 bytes

Just using gsub function to translate lower or upper S via regex and print it afterwards. Can work with files, or with stdin as in this case

$ awk '{gsub(/s/,"th");gsub(/S/,"Th")}1' <<< "This is Sparta"                   
Thith ith Thparta
\$\endgroup\$
1
  • \$\begingroup\$ gsub(/s/,"th")gsub(/S/,"Th") does the trick. \$\endgroup\$ May 15, 2022 at 15:41
4
\$\begingroup\$

TI-Basic, 126 bytes

Input Str1
inString(Str1,"s
While Ans
sub(Str1,1,Ans-1)+"th"+sub(Str1,Ans+1,length(Str1)-Ans->Str1
inString(Str1,"s
End
inString(Str1,"S
While Ans
sub(Str1,1,Ans-1)+"Th"+sub(Str1,Ans+1,length(Str1)-Ans->Str1
inString(Str1,"S
End
Str1
\$\endgroup\$
3
  • \$\begingroup\$ This is wrong. Str1 never changes, and Ans will hold a number at the end. \$\endgroup\$
    – lirtosiast
    Jul 14, 2016 at 22:45
  • \$\begingroup\$ Thanks for the note, fixed now. I don't know how I forgot to save Str1 back again... \$\endgroup\$
    – Timtech
    Jul 15, 2016 at 23:08
  • \$\begingroup\$ This is still wrong; it errors when the first or last character is S. As I've said before, please test your code before you post it. \$\endgroup\$
    – lirtosiast
    Jul 18, 2016 at 4:24
4
\$\begingroup\$

Java, 101 byteth

interface a{static void main(String[]A){System.out.print(A[0].replace("S","Th").replace("s","th"));}}

Note that this is a complete program unlike the previous Java answer.

Bonus (has to be fed to the C preprocessor THEE preprothethor first):

#define interfaith interface
#define thtatic static
#define Thtring String
#define Thythtem System
#define replaith(x,y) replace(x,y)

interfaith a{thtatic void main(Thtring[]A){Thythtem.out.print(A[0].replaith("S","Th").replaith("s","th"));}}
\$\endgroup\$
4
\$\begingroup\$

35 Byteth of Julia:

s->replace(s,r"s"i,s->"$(s[1]+1)h")

Try it online! (includes all test cases)

\$\endgroup\$
1
  • \$\begingroup\$ Hey, don't I know you from somewhere? ;) \$\endgroup\$
    – Alex A.
    Jul 29, 2016 at 18:02
4
\$\begingroup\$

C (GCC), 62 byteth

-10 bytes thanks to @ceilingcat; forgot to use the function argument as the iterator.

-1 more byte thanks to @l4m2 and his very smart recursion trick.

l(char*s){*s&&l(s+!!putchar(*s&31^19?*s:104+!putchar(*s+1)));}

Try It Online!

Explanation:

l(char*s)
{
    // If at end of string, do nothing.
    *s&&
        // Else, apply this function to the next character in s ...
        l(s+
            // ... but first, print the current character. If the first
            // five bits of *s equal 19 (which they do for 's' and
            // 'S'), print *s+1 (that is, 't' for 's' and 'T' for 'S')
            // before printing character code 104, which is 'h'.
            // If the first five bits aren't 19, just print *s.
            !!putchar(*s&31^19?*s:104+!putchar(*s+1)));}

Alternative 62-byte version, made by l4m2:

l(char*s){*s&&l(s+!!printf(*s&31^19?"%c":*s%5?"Th":"th",*s));}

Try it online!

I'm too lazy to explain that one fully, but it's quite similar to the last one except it uses two nested conditional statements to figure out if it should print the current character, Th or th. The new *s%5 check is used to figure out if *s is 'S' or 's' (knowing that it's one of those), since the ASCII code of s is divisible by 5 but 'S' is not.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 62 \$\endgroup\$
    – l4m2
    Jul 4, 2023 at 18:57
  • \$\begingroup\$ @l4m2 That's very clever, thanks a lot :) \$\endgroup\$
    – Peter
    Jul 4, 2023 at 20:44
  • 1
    \$\begingroup\$ Alternative 62 \$\endgroup\$
    – l4m2
    Jul 5, 2023 at 6:41
3
\$\begingroup\$

CJam, 15 bytes

q"sS""thTh"2/er

Test it here.

Explanation

q      e# Read input.
"sS"   e# Push string.
"thTh" e# Push string.
2/     e# Split into pairs, i.e. ["th" "Th"].
er     e# Transliteration, replaces 's' with 'th' and 'S' with 'Th'.
\$\endgroup\$
0
3
\$\begingroup\$

Python3 - 46 bytes

lambda s:s.replace("s","th").replace("S","Th")

Dropped 4 bytes with the help of @DenkerAffe!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Python 3 was the language it was originally written in. My version of his code was 59 bytes, so we'll done! \$\endgroup\$
    – george
    Jun 17, 2016 at 10:39
  • 1
    \$\begingroup\$ lambda s:s.replace("s","th").replace("S","Th") is a bit shorter. \$\endgroup\$
    – Denker
    Jun 17, 2016 at 10:51
  • \$\begingroup\$ @DenkerAffe Yes it is shorter but to use lambda in this case, you would still need an input and an output to answer the original question. \$\endgroup\$
    – george
    Jun 17, 2016 at 10:55
  • 1
    \$\begingroup\$ @george Community consensus is that functions can use arguments and returns values instead of using stdin/stdout. Have a look at our defaults for I/O. While you can of course override them if you want, it wouldn't make much sense in this particular challenge. \$\endgroup\$
    – Denker
    Jun 17, 2016 at 11:02
  • \$\begingroup\$ @DenkerAffe okay that's fine. When I asked the question I mean the output would be an echo or print. But I shall leave it to the defaults. So yes using lambda would be shorter \$\endgroup\$
    – george
    Jun 17, 2016 at 11:12
3
\$\begingroup\$

Haskell, 36 bytes

f 's'="th";f 'S'="Th";f x=[x]
(>>=f)
\$\endgroup\$
4
  • \$\begingroup\$ You don't need the space: f's'=... \$\endgroup\$
    – ThreeFx
    Jun 17, 2016 at 14:22
  • 1
    \$\begingroup\$ Sadly, I do. Haskell names may contain apostrophes. :( \$\endgroup\$
    – Lynn
    Jun 17, 2016 at 14:36
  • \$\begingroup\$ Oh damn I completely forgot that. I almost never need Chars... \$\endgroup\$
    – ThreeFx
    Jun 17, 2016 at 14:51
  • 8
    \$\begingroup\$ I thought it wath "Hathkell" \$\endgroup\$ Jun 17, 2016 at 15:42
3
\$\begingroup\$

Rust, 46 bytes

|s:&str|s.replace("s","th").replace("S","Th");

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ @mbomb007. I'm not sure you should edit that. \$\endgroup\$ Jun 17, 2016 at 21:02
  • \$\begingroup\$ I'm making it follow the answering guidelines. I should be able to view a post and know what language it is. Some languages contain "th" already, so it's ambiguous. And who's to say that someone won't create a different language actually called "Rutht" in the future? \$\endgroup\$
    – mbomb007
    Jun 17, 2016 at 21:04
  • 2
    \$\begingroup\$ @mbomb007, who's to say someone won't create a different language called "Rust" in the future? \$\endgroup\$
    – msh210
    Jun 17, 2016 at 21:24
  • \$\begingroup\$ @msh210 Moot point, because if used the poster will need to clarify. \$\endgroup\$
    – mbomb007
    Jun 17, 2016 at 21:32
3
\$\begingroup\$

PHP, 42 Bytes

if run from a file:

<?=strtr($argv[1],["s"=>"th","S"=>"Th"]);

Run as:

~$ php [file] "This is Silly"
\$\endgroup\$
2
  • \$\begingroup\$ -1 byte: remove the newline at the end \$\endgroup\$ Jun 17, 2016 at 16:03
  • \$\begingroup\$ -8 bytes: remove quotes. -> use php -d error_reporting=0 to suppress notices. \$\endgroup\$
    – Titus
    Jul 6, 2016 at 10:03
3
\$\begingroup\$

Emacth Lithp, 61 byteth

(lambda(s)(replace-regexp-in-string"[Ss]\\(\\w*\\)""th\\1"s))

Emacs Lisp tries to be smart when replacing text, but that smartness breaks when the replaced string only takes up one space, i.e. the capital letter S. To prevent this from converting "Sam and Sally" to "THam and THally", the whole word is matched instead. However, this also handles "SAM and Sally" in the way that one would want, i.e. producing "THAM and Thally".

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

x86 machine code, 19 bytes

In hex:

86ac3c5374043c73750440aab068aa84c075eec3

Input: ESI: input string, EDI: output buffer.

Disassembly:

_loop:
0:  ac          lodsb       
1:  3c 53       cmp al,'S'  
3:  74 04       je _th      
5:  3c 73       cmp al,'s'  
7:  75 04       jne _nth    
_th:
9:  40          inc eax     ;[Ss]->[Tt]
a:  aa          stosb       
b:  b0 68       mov al,'h'  
_nth:
d:  aa          stosb       
e:  84 c0       test al,al  
10: 75 ee       jnz _loop   
12: c3          ret         
\$\endgroup\$
1
  • \$\begingroup\$ You can use test al, 'S' to check both at once \$\endgroup\$
    – anatolyg
    Aug 7, 2016 at 22:40
3
\$\begingroup\$

Befunge 98, 37 49 bytes

Original version :

~:"s"- #v_$"ht",>,
_;#-"S":<;$"hT",^ 

Terminating edition, as per consensus :

~:a-!#@_:"s"-#v_$"ht",>,
_;#-"S":      <;$"hT",^ 

This leaves a big honking hole in the code grid that I'm not very happy about. I'll look into that when I have the time.
The 49th byte is a space at the end of the second line, included to have a rectangular grid, required to prevent ccbi (and probably other interpreters) from bugging out and printing an infinite line of "Th"s.

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

Vyxal s, 11 bytes

ƛ⇩\s=[‛th$•

Try it Online!

I wath hoping I could find thomething lethth trivial than jutht replacing the letter with the combo but I couldn't. Lookth like I did.

Explained

ƛ⇩\s=[‛th$•
ƛ             # To each character:
 ⇩\s=[        #   if char.lower == "s":
      ‛th$•   #     "th" with the capitalisation of the character
\$\endgroup\$
2
\$\begingroup\$

C# 6.0 - 58 bytes

string f(string s)=>s.Replace("s","th").Replace("S","Th");

Takes the input string as an argument to the function.

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

Pyth, 14 bytes

::z\s"th"\S"Th

Test suite

Thanks to @LeakyNun for spotting a typo!

\$\endgroup\$
1
  • 7
    \$\begingroup\$ So the language is "Pys"? :P \$\endgroup\$
    – mbomb007
    Jun 17, 2016 at 21:00
2
\$\begingroup\$

MATL, 17 bytes

115'th'YX83'Th'YX

Try it online!

Explanation

115    % 's' (ASCII)
'th'   % String 'th'
YX     % Regex replacement
83     % 'S' (ASCII)
'Th'   % String 'Th'
YX     % Regex replacement
\$\endgroup\$
2
\$\begingroup\$

Python 3, 53 bytes

def l(s):return s.replace("s","th").replace("S","Th")

Usage:

>> l('Sam and Sally like Sheep')

Tham and Thally like Thheep
\$\endgroup\$
5
  • \$\begingroup\$ -7 bytes: lambda s:s.replace("s","th").replace("S","Th") Usage: (lambda s:s.replace("s","th").replace("S","Th"))(s) \$\endgroup\$ Jun 17, 2016 at 16:02
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Well, that's identical to TuukkaX's answer (which was posted before mine), so... \$\endgroup\$
    – m654
    Jun 17, 2016 at 16:04
  • \$\begingroup\$ There's no reason to post another answer then. \$\endgroup\$ Jun 17, 2016 at 16:08
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ I didn't notice his when I posted mine. \$\endgroup\$
    – m654
    Jun 17, 2016 at 16:09
  • \$\begingroup\$ You can delete your answer once you notice there is a shorter one posted before yours. \$\endgroup\$ Jun 17, 2016 at 16:11
2
\$\begingroup\$

GameMaker Language, 74 bytes

return string_replace_all(string_replace_all(argument0,'s','th'),'S','Th')
\$\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.