13
\$\begingroup\$

*What is a transmogrifier?

In the C programming language, there are formations called digraphs and trigraphs that are two and three characters sequences that evaluate to less common characters. For example, you can use ??- if your keyboard doesn't have ~.

Given text, replace all instances of the following digraphs and trigraphs (left side) with the correct, shorter, golfed character (right side).

??=  #
??/  \
??'  ^
??(  [
??)  ]
??!  |
??<  {
??>  }
??-  ~
<:   [
:>   ]
<%   {
%>   }
%:   #

Source

Input

Input is ASCII text. Trailing newline allowed. Does not need to be valid C code.

Output

Output is the same text, with all instances of the above digraphs and trigraphs replaced with the shortened version, evaluated left to right. Trailing newline allowed. Does not need to be valid C code.

Test Cases

=> separates input and output.

if (true ??!??! false) { => if (true || false) {

??-arr.indexOf(n) => ~arr.indexOf(n)

function f(??) { console.log('test??'); } => function f(] { console.log('test^); }

/* comment :> :) *??/ => /* comment ] :) *\

%:What am I doing??!!??` => `#What am I doing|!??

??(??)??(??) <:-- not a palindrome => [][] [-- not a palindrome

?????????? => ??????????

int f(int??(??) a) ??< return a??(0??)??'a??(1??) + "??/n"; ??> => int f(int[] a) { return a[0]^a[1] + "\n"; }

??<:>??<% => {]{%

<:> => [>

<::> => []

:>> => ]>

#\^[]|{}~ => #\^[]|{}~

: > => : >

??=%: => ##
\$\endgroup\$
6
  • 3
    \$\begingroup\$ Please remove the `s from the examples. It makes them so hard to read. \$\endgroup\$ Commented May 20, 2017 at 8:18
  • 4
    \$\begingroup\$ "??=%:" is another relevant test case: in C, this means "#%:" where %: isn't special, but I think your expected output is "##". \$\endgroup\$
    – hvd
    Commented May 20, 2017 at 8:38
  • \$\begingroup\$ @Satan'sSon will do, I originally had it not in a code block to make input/output more readable but Riker changed it over. Feel free to edit something like formatting yourself next time :) \$\endgroup\$
    – Stephen
    Commented May 20, 2017 at 11:33
  • 1
    \$\begingroup\$ So, you're asking for golfed code to golf code. Bonus golf :-) \$\endgroup\$
    – Mast
    Commented May 20, 2017 at 15:05
  • \$\begingroup\$ @Mast that's the idea \$\endgroup\$
    – Stephen
    Commented May 20, 2017 at 15:38

7 Answers 7

7
\$\begingroup\$

C, 206 205 bytes

(-1 thanks to ceilingcat)

The newlines are just here for readability.

c,d,q;f(char*s){for(char*S,*T,*t=s;c-63?q=0:q++,d=c<<8|*s,*s?
q>1&&(T=index(S="=/'()!<>-",*s))?t-=2,*s="#\\^[]|{}~"[T-S]:
d>*s&&(T=strstr(S=">:<>%<:%",&d))&&(c="][ }{ # "[T-S])&1?--t,*s=c:0:
0,*t++=c=*s++;);}

Modifies s in place. Tested with GCC and clang on Fedora Workstation, x86, in 32-bit and 64-bit mode.

C is not exactly the best language for golfing here.

\$\endgroup\$
2
  • \$\begingroup\$ C is not exactly the best language for golfing here. no kidding. Looks good :) Thinking back, I should have forced all questions to add +1 or +2 bytes if they used one of the characters that a digraph or trigraph makes xD \$\endgroup\$
    – Stephen
    Commented May 20, 2017 at 11:39
  • 1
    \$\begingroup\$ You could make it even worse: +1 or +2 for each character that can be part of a di-/trigraph would really hurt :) \$\endgroup\$
    – hvd
    Commented May 20, 2017 at 11:41
5
\$\begingroup\$

Retina, 65 bytes

T`-=/'()!<>?`~#\\^[]|{}_`\?\?[-=/'()!<>]
<:
[
:>
]
<%
{
>%
}
%:
#

Try it online! T is a little awkward to use but still saves me 14 bytes.

\$\endgroup\$
8
  • \$\begingroup\$ Can you do \?\?[^:%]? \$\endgroup\$ Commented May 20, 2017 at 0:35
  • \$\begingroup\$ (\?\?[^:%?] rather) \$\endgroup\$ Commented May 20, 2017 at 1:12
  • \$\begingroup\$ @ETHproductions That would have a side effect of also turning ??a into a. \$\endgroup\$
    – eush77
    Commented May 20, 2017 at 8:24
  • \$\begingroup\$ @eush77 Oh hmm, you're right... \$\endgroup\$ Commented May 20, 2017 at 10:55
  • \$\begingroup\$ Line 8 should be %> instead of >%. \$\endgroup\$
    – Dennis
    Commented Sep 15, 2018 at 13:17
5
\$\begingroup\$

JavaScript (ES6), 106 bytes

s=>[...'#\\^[]|{}~[]{}#'].map((c,i)=>s=s.split('<:<%%'[i-9]+':>%>:'[i-9]||'??'+"=/'()!<>-"[i]).join(c))&&s

How?

This is pretty straightforward.

We should note however that:

  • When i is less than 9, the expression '<:<%%'[i-9] + ':>%>:'[i-9] evaluates to undefined + undefined which equals NaN (falsy as expected).

  • When i is greater than or equal to 9, the expression '??' + "=/'()!<>-"[i] evaluates to "??" + undefined which is coerced to the string "??undefined" (truthy when we expect a falsy result).

That's why we must process the test in this order.

Test cases

let f =

s=>[...'#\\^[]|{}~[]{}#'].map((c,i)=>s=s.split('<:<%%'[i-9]+':>%>:'[i-9]||'??'+"=/'()!<>-"[i]).join(c))&&s

console.log(f(`if (true ??!??! false) {`))                                        // `if (true || false) {`
console.log(f(`??-arr.indexOf(n)`))                                               // `~arr.indexOf(n)`
console.log(f(`function f(??) { console.log('test??'); }`))                       // `function f(] { console.log('test^); }`
console.log(f(`/* comment :> :) *??/`))                                           // `/* comment ] :) *\`
console.log(f(`%:What am I doing??!!??`))                                         // `#What am I doing|!??`
console.log(f(`??(??)??(??) <:-- not a palindrome`))                              // `[][] [-- not a palindrome`
console.log(f(`??????????`))                                                      // `??????????`
console.log(f(`int f(int??(??) a) ??< return a??(0??)??'a??(1??) + "??/n"; ??>`)) // `int f(int[] a) { return a[0]^a[1] + "\n"; }`
console.log(f(`??<:>??<%`))                                                       // `{]{%`
console.log(f(`<:>`))                                                             // `[>`
console.log(f(`<::>`))                                                            // `[]`
console.log(f(`:>>`))                                                             // `]>`
console.log(f(`#\^[]|{}~`))                                                       // `#\^[]|{}~`
console.log(f(`: >`))                                                             // `: >`

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

Ruby, 104+1 = 105 bytes

Uses the -p flag for +1 byte.

"=#/\\'^([)]!|<{>}-~".scan(/(.)(.)/){|k,v|gsub'??'+k,v}
"<:[:>]<%{%>}%:#".scan(/(..)(.)/){|k,v|gsub k,v}

Try it online!

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

Javascript (ES6), 131 123 bytes

f=
s=>"#??= \\??/ ^??' [??( ]??) |??! {??< {??> ~??- [<: ]:> {<% }%> #%:".split` `.map(x=>s=s.split(x.slice(1)).join(x[0]))&&s
<input oninput=console.log(f(this.value))>

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

PHP , 112 Bytes

<?=str_replace(explode(_,strtr("<:_:>_<%_%>_%:0=0/0'0(0)0!0<0>0-",["_??"])),str_split("[]{}##\\^[]|{}~"),$argn);

Try it online!

PHP , 115 Bytes

<?=str_replace(explode(_,"??=_??/_??'_??(_??)_??!_??<_??>_??-_<:_:>_<%_%>_%:"),str_split("#\\^[]|{}~[]{}#"),$argn);

Try it online!

PHP , 124 Bytes

Regex solution

foreach(explode(_,"=|%:_/_'_\(|<:_\)|:>_!_<|<%_>|%>_-")as$v)$a=preg_replace("#\?\?$v#","#\\^[]|{}~"[$k++],$a=&$argn);echo$a;

Try it online!

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

JavaScript (ES6), 113 bytes

s=>s.replace(/\?\?[^:%?]|[<:%]./g,c=>"#\\^[]|{}~"["=/'()!<>-".indexOf(c[2])]||"[] {} #"["<:><%>%:".indexOf(c)]||c)

Not the shortest, but I wanted to try a different approach.

\$\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.