[Question]
  [
Stolen from @Downgoat with permission
The point of this challenge is to (not) settle the debate on the pronunciation of "gif".
[![Gif vs. Jif](https://i.stack.imgur.com/j8SIr.gif)](https://i.stack.imgur.com/j8SIr.gif)"
---
The pronunciation of *gif* is debated and while it's supposed to be (and should be) pronounced *jif*, it's still commonly disputed.
In this challenge you will be given a set of words that have a *g* or *j*, representing the sound that the word is pronounced with. You'll also get some text in which you have to fix the incorrect spellings of *gif*.
Because this is the internet and everyone always wrong. It's (not) common courtesy to correct them.
An example of a wrong pronunciation would be:
```
There was a **gif** of a mouse eating a burrito
```
The wrong spelling of *gif*? Unacceptable! This must be corrected immediately:
```
There was a **jif (as in jar)** of a mouse eating a burrito
```
---
Are we done? Nope, you're *still* wrong.
You're *always* wrong
This must work the other way:
```
In the **jif** the cat wore a hat of a cat
```
This obvious misspelling must be fixed, we shall correct this to:
```
In the **gif (as in graphic)** the cat wore a hat of a cat
```
---
### Rules
* Input is a string (the sentence) and an array of strings (or any reasonable alternative, such as a comma separated string) in any order
* You may take the `g` and `j` words in any order. They may be taken separately.
* Every instance of `gif` (any case) in the sentence must be replaced with `jif (as in ___)` where `___` is a uniformly random selected word beginning with `j` from the array of strings, and vice versa for `jif` with words beginning with `g`.
* ONLY the words `gif` and `jif` should be replaced (i.e "jiffy" should not be changed). Those words have done no wrong.
* You are guaranteed that at least one word in the array begins with `g` and at least one begins with `j`.
* Case must be preserved (e.g. `GiF` -> `JiF`).
* You may write a program or a function
* Standard loopholes apply
* We need to (not) settle the debate quickly; shortest code in bytes wins
---
### Examples
Input and output separated by a single line:
```
graphic, jar, jam, gram
I saw a jif of how to pronounce gif that showed gif is pronounced jif
I saw a gif (as in graphic) of how to pronounce jif (as in jar) that showed jif (as in jam) is pronounced gif (as in gram)
gravy, jeff
G is for gIf, h is for JiF, i is for gIF, j is for JIf
G is for jIf (as in jeff), h is for GiF (as in gravy), i is for jIF (as in jeff), j is for JIf (as in gravy)
joke, june, gorilla, great
Jiffy should not be treated as a GIF or JIF, like gifted.
Jiffy should not be treated as a JIF (as in june) or GIF (as in great), like gifted.
```
  
[Answer]
## Mathematica, 164 165 bytes
This is an abomination, but I want someone to share my pain.
```
StringReplace[f[f@"g"="j"]="g";f[f@"G"="J"]="G";z=IgnoreCase->1>0;#,x:"g"|"j"~~y:"if ":>{f@x,y,"(as in ",RandomChoice@StringCases[#2,f@x~~Except[","]..,z]}<>") ",z]&
```
`Function` which expects the first argument `#` to be the sentence to be (in)corrected and the second argument `#2` to a be comma separated string of words.
`f[f@"g"="j"]="g";f[f@"G"="J"]="G"` defines a function `f` which takes the letters `g`, `G`, `j`, and `J` to their appropriate replacements. This is ever so slightly shorter than `f@"g"="j";f@"j"="g";f@"G"="J";f@"J"="G"`.
I also set `z` equal to `IgnoreCase->True` since I'll be using it twice.
`x:"g"|"j"~~y:"if "` is a `StringExpression` which matches `"gif "` or `"jif "`, naming the first letter `x` and the last three characters `y`. Since the option `z` (also known as `IgnoreCase->True`) is passed to `StringReplace`, these letters can be in any combination of upper and lower case.
I then replace every such match with
```
{f@x,y,"(as in ",RandomChoice@StringCases[#2,f@x~~Except[","]..,z]}<>") " 
```
`RandomChoice@StringCases[#2,f@x~~Except[","]..,z]` randomly selects a word out of the second argument `#2` which begins with `f[x]`, again ignoring case because the option `z` is given.
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~88~~ ~~87~~ 91 bytes
-1 byte from ETHproductions. +4 bytes because words containing "gif" or "jif" shouldn't be replaced. -2 bytes because replacement word lists can be taken separately now.
```
->s,g,j{s.gsub(/\b(g|j)if\b/i){$&.tr("GgJj","JjGg")+" (as in #{($1[/g/i]?j:g).sample})"}}
```
[Try it online!](https://tio.run/##TY7LasMwEEX3@YrBDcWmiky3hbbQRU38C3EWsiuNR5EfWBLBuPnsrt0xpbSbM/feeTBTrOfVPFfr4cULFHbxEn2s07yqU/y0GZmqzilb9vcyTGlSYGkTkZS2wCR7SCBVHqiHuyXdP55yzOn8ap8wk151o9O3LLnd1jEGD@aEOngBG6UfHYX/@rwWQDw0TIBHI6D9dSW9C6C/HjsLZH56RyPhTcOVQgvzELdHFFgyZpY7nNTYUgNcO4ZWAXDoNaDqNnhAMhxFcmFmTz0nurkMO6smsLxjVXPhY86xqsHyrmduastjz1AfGqy@avfVD4dGNa3@Bg "Ruby – Try It Online")
[Answer]
# [CJam](https://sourceforge.net/p/cjam/wiki/), 78 bytes
```
l',%:A;lS%{_ela"gifjif"3/&{_V=_el:B'g=1W?Z*+V\t" (as in "A{V=elB=!},mR')}O?S}%
```
[Try it online!](http://cjam.aditsu.net/#code=l'%2C%25%3AA%3BlS%25%7B_ela%22gifjif%223%2F%26%7B_V%3D_el%3AB'g%3D1W%3FZ*%2BV%5Ct%22%20%28as%20in%20%22A%7BV%3DelB%3D!%7D%2CmR'%29%7DO%3FS%7D%25&input=graphic%2Cjar%2CJaM%2Cgram%0AI%20saw%20a%20JiF%20of%20how%20to%20pronounce%20gif%20that%20showed%20giF%20is%20pronounced%20jIf)
Requires the list of replacement characters to be separated by nothing but commas.
---
Explanation:
```
l',%                        e# read line of input and split at commas
    :A;                     e# store in var A and pop off the stack
       lS%{...}%            e# for each word in the next line of input so:
_ela"gifjif"3/&             e#   intersection of ["gif" "jif"] and [lowercase(word)]
               {...}O?      e#   if set it non-empty, run block below, otherwise do nothing (push empty string)
                      S     e#   push space
_V=                         e#     extract first char
   _el:B                    e#     duplicate to lowercase and store in var B
        'g=1W?Z*+           e#     convert g/G <=> j/J
                 V\t        e#     store back to word
" (as in "                  e#     push string
           A{V=elB=!},      e#     filter replacements by words starting with the same char (case insensitive)
                      mR    e#     select random element
                        ')  e#     push ')' char
```
[Answer]
# [Python 3](https://docs.python.org/3/), 237 bytes
```
lambda s,g,j:' '.join([(w if False in(w[0]in q,w[1:2]in['i','I'],w[2:3]in['f','F'],w[3:]in",;!?.")else q[w[0]]+w[1:3]+" (as in "+choice(g if w[0]in 'jJ'else j)+')'+w[3:])for w in s.split()])
from random import*
q=dict(zip("gGjJ","jJgG"))
```
[Try it online!](https://tio.run/##LY3LboMwEEX3@YrJbGwXC7VhRxR1Bwq/4LKgEJuxEsyrQvTn6YC6mpkzuuf269yGLtns7Wt7Vq/vpoJJO@1TASL2gTpp5AJkIaue0wP4Xsx7SR0MejEf6YVXI0hocRclk0uaHMQyyQ6SpAxQX8@fMarH7hjMriijPZ@UEYKsJhYDRnUbqH5It/f91whfiCPlVSSUiA6hsmGEZc9M8dQ/aZaqVCc7hheMVdfwoFcfxvntNNwaqmf5S71El/sCNfrC5ajU1o/UzdIypwwKbszJZuDvNlvBgQZHVoMne0YNBt1Y9S3VnHdtmGYstUF@2pW/6H92ws4/ "Python 3 – Try It Online")
This is the best I can do -- might be some way to do it quicker (probably with regexes) but my brain hurts now.
Explanation:
`q` is a simple dictionary mapping, I hope that's clear.
`s,g,j` are the input string, the list of g-words, and the list of j-words.
`' '.join` joins together the list comprehension done across `for w in s.split()` is therefore for the list of words in s.
The middle bit is black magic, which I'll break down piecewise. First, the condition: `False in(w[0]in q,w[1:2]in['i','I'],w[2:3]in['f','F'],w[3:]in",;!.")`.
`w[0]in q` checks the first character is in the keys of `q` which are `'g','G','j','J'`. The reason for separating out `q` as a variable is we also use it as a dict/map later.
`w[1:2]in ['i','I']` checks that the second character is either i or I. The :2 is necessary because just putting `w[1]` would result in a crash on 1-letter words, but slices don't do that for some reason (I thought they did, whatever!)
`w[2:3]in ['f','F']` is analogous. I briefly had this as just 2: before I realized I needed to account for gif, or jif, followed by punctuation!
`w[3:]in",;!?."` checks that the subsequent character(s) are punctuation. I admit my code doesn't work if someone puts 'gif?!' but I can't be perfect. Someone else can take up the challenge of opening quotes before gif or jif, too.
`False in(,,,)` is basically a big NAND. It's actually the same bytecount as separating four items with `and` and swapping the arguments, but this looks cooler and works better if you have to extend it to a fifth `and`ed thing.
`w if` means that if False is in the conditional-list, we just return the word unchanged -- it doesn't meet our criteria. `else`, we change it to:
`q[w[0]]+w[1:3]+" (as in "+choice(g if w[0]in 'jJ'else j)+')'+w[3:]`
OK. `q[w[0]]` substitutes the first letter correctly. `w[1:3]` tacks on the i or I and f or F, `w[3:]` tacks on any trailing punctuation. That leaves the as in clause.
`" (as in "+choice(g if w[0]in 'jJ'else j)+')'` puts in the obvious string literal at the start and the trailing parenthesis, the interesting bit here is `choice(g if w[0]in 'jJ'else j)` which randomly chooses from `g` or `j`, depending on if `w[0]` is in `'jJ'`. and I just realized I had this bit backwards so fixing that throughout, done.
It's been a long day. `choice` is in the `random` module hence the import. I think that's everything.
[Answer]
## JavaScript (ES6), 142 bytes
```
(s,g,j,r=l=>l[Math.random()*l.length|0])=>s.replace(/\b[gj]if\b/gi,w=>`GJgj`[l=`JGjg`.search(w[0])]+w.slice(1)+` (as in ${r([g,j,g,j][l])})`)
```
Takes separate `g` and `j` word lists.
[Answer]
# Javascript(ES6), 151 bytes
```
f=(s,g,j)=>s.replace(/\b(g|j)(if)\b/ig,(m,p,c)=>`${a=g,p=="j"?"g":p=="J"?"G":(a=j,p=="g"?"j":"J")}${c}(as in ${a[Math.floor(Math.random()*a.length)]})`)
```
I probably can golf down the ternary part more, but I can't think of how right now. Also, it takes the g and j words separately.
]