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\$
  • 3
    \$\begingroup\$ Please remove the `s from the examples. It makes them so hard to read. \$\endgroup\$ – caird coinheringaahing May 20 '17 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 May 20 '17 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 May 20 '17 at 11:33
  • 1
    \$\begingroup\$ So, you're asking for golfed code to golf code. Bonus golf :-) \$\endgroup\$ – Mast May 20 '17 at 15:05
  • \$\begingroup\$ @Mast that's the idea \$\endgroup\$ – Stephen May 20 '17 at 15:38
5
\$\begingroup\$

Retina, 65 bytes

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

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

\$\endgroup\$
  • \$\begingroup\$ Can you do \?\?[^:%]? \$\endgroup\$ – ETHproductions May 20 '17 at 0:35
  • \$\begingroup\$ (\?\?[^:%?] rather) \$\endgroup\$ – ETHproductions May 20 '17 at 1:12
  • \$\begingroup\$ @ETHproductions That would have a side effect of also turning ??a into a. \$\endgroup\$ – eush77 May 20 '17 at 8:24
  • \$\begingroup\$ @eush77 Oh hmm, you're right... \$\endgroup\$ – ETHproductions May 20 '17 at 10:55
  • \$\begingroup\$ Line 8 should be %> instead of >%. \$\endgroup\$ – Dennis Sep 15 '18 at 13:17
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\$
  • \$\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 May 20 '17 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 May 20 '17 at 11:41
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, privacy policy and cookie policy

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