Golff y Côd - Treiglad

16

1

Read this yng Nghymraeg

Challenge

Given a word in Welsh, output all of the possible mutated forms of the word.

Mutations

A mutation is a change of the first letter of a word when following certain words or in certain grammatical contexts.

In Welsh, the following are considered "consonants":

b c ch d dd f ff g ng h l ll m n p ph r rh s t th

Note that multiple character consonants such as ch, ng and rh are counted as one letter in Welsh, and therefore one consonant.

The other letters in the Welsh alphabet are vowels, listed below:

a e i o u w y

See below, all of the mutations with the original letter on the left and the resulting mutated letters on the right:

Original | Mutations
---------+---------------
p        | b mh ph
t        | d nh th
c        | g ngh ch
b        | f m
d        | dd n
g        | [no letter] ng
m        | f
ll       | l
rh       | r

Here, [no letter] means that the g is removed from the start of the word.

Note that there are some consonants which do not mutate:

ch
dd
f
ff
j
l
n
ng
ph
r
s
th

Vowels may also be found at the start of words but do not mutate:

a
e
i
o
u
w
y

Examples

Input: dydd

Output:

dydd
ddydd
nydd

Input: pobl

Output:

pobl
bobl
mhobl
phobl

Input: gwernymynydd

Output:

gwernymynydd
wernymynydd
ngwernymynydd

Input: ffrindiau

Output:

ffrindiau

Input: enw

Output:

enw

Input: theatr

Output:

theatr

On the request of ArtOfCode ;)

Input: llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch

Output:

llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
lanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch

Rules

The input will only ever be one word.

There will always be more letters after the leading consonant in your input.

Winning

The shortest code in bytes wins.

Beta Decay

Posted 2016-09-09T19:53:05.740

Reputation: 21 478

5New test case: llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch – ArtOfCode – 2016-09-10T08:01:29.067

Another test case theatr; t mutates but th doesn't. – Antti Haapala – 2016-09-10T09:32:01.533

Should be 'Golff y Côd' - 'yr' only comes before a vowel, you use 'y' before a consonant. – Gareth – 2016-09-10T12:25:43.437

If anyone's interested in the complicated rules regarding mutation in Welsh, there's an app called 'Ap Treiglo' which gives the rules and lists many of the words which cause mutations in the following word. – Gareth – 2016-09-10T12:38:08.327

@Beta Decay Yeah, for the last 5 years. Rhyl before that, for my sins. – Gareth – 2016-09-10T20:02:50.437

Irish does the same thing phonetically, but writes it quite differently (we prepend the urú, so b becomes mb (pronounced m). We even keep the case on the original initial letter, so in English is i mBéarla. Some writers keep the urú in lower case even when writing in block capitals. – TRiG – 2016-10-26T12:19:24.437

Answers

5

JavaScript (ES6), 180 bytes

x=>x.replace(/^([cpt](?!h)|d(?!d)|[bgm]|ll|rh)(.+)/,(_,y,z)=>({p:"b mh ph",t:"d nh th",c:"g ngh ch",b:"f m",d:"dd n",g:" ng",m:"f"}[y]||y[0]).split` `.map(b=>a.push(b+z)),a=[x])&&a

Outputs as an array of strings. This is my first try, so it's almost certainly not optimal.

Try it out

f=x=>x.replace(/^([cpt](?!h)|d(?!d)|[bgm]|ll|rh)(.+)/,(_,y,z)=>({p:"b mh ph",t:"d nh th",c:"g ngh ch",b:"f m",d:"dd n",g:" ng",m:"f"}[y]||y[0]).split` `.map(b=>a.push(b+z)),a=[x])&&a
<input id=A value="pobl"><button onclick="B.innerHTML=f(A.value).join('<br>')">Run</button><br>
<pre id=B>

ETHproductions

Posted 2016-09-09T19:53:05.740

Reputation: 47 880

It's not optimal, but my PC decided to switch itself off, and I no longer remember what optimisation I was able to make. – Neil – 2016-09-11T00:29:58.743

4

C#, 356 338 360 bytes

I know that C# is a poor choice for code golf, but it's worth the shot:

Third attempt, all cases now pass, including th- ph- etc. This adjustment cost roughly 18 bytes.

Thanks pinkfloydx33 for the tips saving 24 bytes!

namespace System{using Linq;using S=String;class P{static void Main(S[]a){Action<S>w=Console.WriteLine;w(a[0]);foreach(S r in"th-dd-ch-ph-p.b.mh.ph-t.d.nh.th-c.g.ngh.ch-b.f.m-d.dd.n-g..ng-m.f-ll.l-rh.r".Split('-')){var b=r.Split('.');if(a[0].StartsWith(b[0])){foreach(S f in b.Skip(1))w(Text.RegularExpressions.Regex.Replace(a[0],$"^{b[0]}",f));break;}}}}}

Output

$> ./p gwernymynydd
gwernymynydd
wernymynydd
ngwernymynydd

Formatted Version

    namespace System {
    using Linq;
    using S = String;

    class P {
        static void Main(S[] a) {
            Action<S> w = Console.WriteLine;
            w(a[0]);
            foreach (S r in "th-dd-ch-ph-p.b.mh.ph-t.d.nh.th-c.g.ngh.ch-b.f.m-d.dd.n-g..ng-m.f-ll.l-rh.r"
                .Split('-')) {
                var b = r.Split('.');
                if (a[0].StartsWith(b[0])) {
                    foreach (S f in b.Skip(1))
                        w(Text.RegularExpressions.Regex.Replace(a[0], $"^{b[0]}", f));
                    break;
                }
            }
        }
    }
}

grizzly

Posted 2016-09-09T19:53:05.740

Reputation: 221

1$"{f}" should just be f, you can also save the first call to write line, as well as the action, by not skipping the first element in b (saving the skip as well) and just replacing the first item with itself (I think). You also only make one call to regex so Caching/renaming the import costs more than just Text.RegularExpressions.Regex.Replace(...) in the body. The break is also superfluous since it's only gonna match once doesnt matter if it loops through to the end – pinkfloydx33 – 2016-09-10T03:08:02.377

1

There are no poor choices of language for golf - you are competing against anyone else who wants to try and beat you in the same language. Plus C# was once the golfing language of choice for Jon Skeet...

– trichoplax – 2016-09-10T08:32:52.433

@pinkfloydx33 Thanks for the tips! However I can't remove the first Console.WriteLine call because this will skip outputting the word in case there are no replacements for it. I am sure there is a way how to optimize it by changing the condition. – grizzly – 2016-09-10T17:06:46.797

I just spotted theatr case and it seems it isn't mutating correctly. – grizzly – 2016-09-10T17:07:51.693

Yeah there are several test cases that don't pass at the moment because PH, TH, CH and DD do not get transformed – pinkfloydx33 – 2016-09-10T17:59:32.167

Fixed now, all cases pass. Thanks for noticing! – grizzly – 2016-09-11T00:17:24.913

3

PowerShell v3+, 254 231 bytes

param($a)$a;$z=-join$a[1..$a.length]
if(($x=@{112='b mh ph';116='d nh th';99='g ngh ch';98='f m';100='dd n';109='f'})[+$a[0]]-and$a-notmatch'^[cpt]h|^dd'){-split$x[+$a[0]]|%{"$_$z"}}
($z,"ng$z")*($a[0]-eq103)
$z*($a-match'^ll|^rh')

working to golf further...

Examples

(Output is space-separated because that's the default Output Field Separator for stringified arrays. I don't know if the words I used for testing are actual words, but they fit the exceptions.)

PS C:\Tools\Scripts\golfing> 'dydd','pobl','gwernymynydd','ffrindiau','enw','rhee','llewyn','chern','ddydd','phobl'|%{"$_ --> "+(.\golff-yr-cod.ps1 $_)}
dydd --> dydd ddydd nydd
pobl --> pobl bobl mhobl phobl
gwernymynydd --> gwernymynydd wernymynydd ngwernymynydd
ffrindiau --> ffrindiau
enw --> enw
rhee --> rhee hee
llewyn --> llewyn lewyn
chern --> chern
ddydd --> ddydd
phobl --> phobl

AdmBorkBork

Posted 2016-09-09T19:53:05.740

Reputation: 41 581

3

Python 3, 196,189 185 bytes

Original attempt

w=input();print(w);[w.startswith(a)and[print(w.replace(a,i,1))for i in
r]+exit()for(a,*r)in(j.split(',')for j
in'th rh ph p,b,mh,ph t,d,nh,th c,g,ngh,ch b,f,m d,dd,n g,,ng m,f ll,l rh,r'.split())]

Vaultah noted that not w.find(a) would be a replacement for w.startswith(a) that would save 2 characters. But instead of not x and y we can use x or y which saves some characters more:

w=input();print(w);[w.find(a)or[print(w.replace(a,i,1))for i in
r]+exit()for(a,*r)in(j.split(',')for j
in'th rh ph p,b,mh,ph t,d,nh,th c,g,ngh,ch b,f,m d,dd,n g,,ng m,f ll,l rh,r'.split())]

Yet further savings by replacing w.replace(a,i,1) with i+w[len(a):]:

w=input();print(w);[w.find(a)or[print(i+w[len(a):])for i in
r]+exit()for(a,*r)in(j.split(',')for j
in'th rh ph p,b,mh,ph t,d,nh,th c,g,ngh,ch b,f,m d,dd,n g,,ng m,f ll,l rh,r'.split())]

Then I noticed that there was a bug, rh was listed twice; once in my short-circuit list that would take care of those double-letter consonants. Unfortunately dd was missing from there, so no savings, and we have

w=input();print(w);[w.find(a)or[print(i+w[len(a):])for i in
r]+exit()for(a,*r)in(j.split(',')for j
in'th ph dd p,b,mh,ph t,d,nh,th c,g,ngh,ch b,f,m d,dd,n g,,ng m,f ll,l rh,r'.split())]

Given any of the sample inputs, it gives the desired output; given

gorsaf

it outputs

gorsaf
orsaf
ngorsaf

and given input

theatr

it prints

theatr

Antti Haapala

Posted 2016-09-09T19:53:05.740

Reputation: 341

1

C#, 349 bytes

Based on @grizzly's submission, but corrected to work with the consonants that don't get transformed (ph/ch/th/dd) that it wasn't working with, plus trimmed some excess out. Hope that's alright?

I had it down to 290 until I realized that I was missing the th/ch/ph/dd cases :-(. Adding in the Regex call killed it

namespace System{class P{static void Main(string[]a){var x=a[0];if(!Text.RegularExpressions.Regex.IsMatch(x,"^[pct]h|^dd"))foreach(var r in"p.b.mh.ph-t.d.nh.th-c.g.ngh.ch-b.f.m-d.dd.n-g..ng-m.f-ll.l-rh.r".Split('-')){var b=r.Split('.');if(a[0].StartsWith(b[0]))for(int i=1;i<b.Length;)x+='\n'+b[i++]+a[0].Substring(b[0].Length);}Console.Write(x);}}}

Interesting note, never knew that you could omit the space between var r in"string"

Formatted:

namespace System
{
    class P
    {
        static void Main(string[] a)
        {
            var x = a[0];
            if (!Text.RegularExpressions.Regex.IsMatch(x, "^[pct]h|^dd"))
                foreach (var r in"p.b.mh.ph-t.d.nh.th-c.g.ngh.ch-b.f.m-d.dd.n-g..ng-m.f-ll.l-rh.r".Split('-'))
                {
                    var b = r.Split('.');
                    if (a[0].StartsWith(b[0]))
                        for (int i = 1; i < b.Length;) x += '\n' + b[i++] + a[0].Substring(b[0].Length);
                }
            Console.Write(x);
        }
    }
}

pinkfloydx33

Posted 2016-09-09T19:53:05.740

Reputation: 308

0

Perl 6, 162 bytes

{/^(.|<[cprt]>h|dd|ff|ng|ll)(.*)/;(%('p',<b mh ph>,'t',<d nh th>,'c',<g ngh ch>,'b',<f m>,'d',<dd n>,'g',«'' ng»,'m',<f>,'ll',<l>,'rh',<r>){$0}//~$0).map(*~$1)}

Try it online!

bb94

Posted 2016-09-09T19:53:05.740

Reputation: 1 831