your Uncle help Drunk needs

10

0

Drunk Uncle (sorry M.E. and AUS for region lock) is a fictional character from Saturday Night Live. He often confuses words for others that sound like them. For this challenge you need to convert normal speech into drunkspeak.

Algorithm

Translating to drunkspeak requires swapping the order of words in the text. Swapping is based on the drunkenness similarity of two words. Drunkenness similarity is defined as the number of letters that two words have occuring at the same indices. However, two identical words have a drunkenness similarity of -1. For example, tree and friend have a drunkenness similarity of 2, because they both have an 'r' at index 1, and an 'e' at index 3.

All you have to do is find the two words in the text with the highest drunkenness similarity, then swap them. Once you swap two terms, they do not move any more. Then you look at the remaining swappable terms and swap the two that have the highest drunkenness similarity. You keep doing this until you can't swap any more. Then you output (or return, for a function) the updated text.

Specifics

  • For simplicity, input is a list of words consisting of characters in [A-Za-z]
  • Every input contains at least one word
  • Letter matching is case-insensitive: A matches with a (Note: Due to this rule Dog and dog are identical, and thus have a D.S. of -1)
  • If multiple pairs have the highest drunkenness similarity:
    1. Of the words, that can maximize drunkenness similarity, pick the one with the lowest index in the list
    2. Pair that word with the lowest-index word that maximizes drunkenness similarity

Examples

  1. Drunk Uncle needs your help (title)

    • S1: Drunk<=>your (DS: 1) your Uncle needs Drunk help
    • S2: needs<=>help (DS: 1) your Uncle help Drunk needs
    • Output: your Uncle help Drunk needs
  2. I love fidget spinners (boring example)

    • S1: I<=>love (DS: 0) love I fidget spinners
    • S2: fidget<=>spinners (DS: 0) love I spinners fidget
  3. dog eat dog ear

    • S1: eat<=>ear (DS: 2) dog ear dog eat
    • S2: dog<=>dog (DS: -1) dog ear dog eat (this step just formality)
  4. Let me tell you a story

    • S1: Let<=>me (DS: 1) me Let tell you a story
    • S2: tell<=>you (DS: 0) me Let you tell a story
    • S3: a<=>story (DS: 0) me Let you tell story a
  5. Too many money and purple people

    • S1: purple<=>people (DS: 4) Too many money and people purple
    • S2: many<=>money (DS: 2) Too money many and people purple
    • S3: Too<=>and (DS: 0) and money many Too people purple

Let me know if there are more examples you want me to cover.

geokavel

Posted 2017-07-18T17:22:19.197

Reputation: 6 352

8please change 'i love fid-get spinners' to 'i hate fid-get spinners' – Okx – 2017-07-18T17:45:35.910

1"natural language" – HyperNeutrino – 2017-07-18T20:08:53.543

Answers

3

JavaScript - 286 279 bytes

f=(a,n=(a=a.split` `).length)=>{for(d=n>>1;w=-2,d--;){for(i=n;i--;)for(j=n;j--;)s=((a,f,v=0)=>{for(u=s=a!=f;(r=a[v])&&(t=f[v++]);s+=(p=a=>a.toLowerCase())(r)==p(t));return u*s-1})(a[i],a[j]),!(f[i]|f[j])&&s>=w&&(w=s,x=i,y=j);f[x]=f[y]=1,[a[x],a[y]]=[a[y],a[x]];}return a.join` `}

You can try it on JSFiddle.

user72349

Posted 2017-07-18T17:22:19.197

Reputation:

Welcome (again) to PPCG :) Nice first submission! – HyperNeutrino – 2017-07-18T20:12:20.477

2

Python 3, 285 277 270 267 Bytes, not working

i=input().split();r=range;l=len;t=y=z=-1;n=str.lower
for p in r(l(i)):
 for q in r(p):
  b=min(l(i[p]),l(i[q]));x=0
  for s in r(b):
   if n(i[p][s])==n(i[q][s]):
    x=x+1
  if n(i[p])==n(i[q]):
   x=-1
  if x>t:
   t=x;y=p;z=q
i[y],i[z]=i[z],i[y]
print(" ".join(i))

I tried to make the output match the challenge, not the test cases, as a couple of the test cases contradict the challenge.

Edit: golfed the 'lower' thingy.

Edit: changed split(" ") to split()

Edit: I realised this doesn't actually complete all the thingys, and while I might come up with a full working answer, in the meantime I might as well add that this only completes one iteration.

Harmless

Posted 2017-07-18T17:22:19.197

Reputation: 61

1

You need to define either g = str.lower or g = lambda s: s.lower() which you then can use like this.

– ბიმო – 2017-08-09T12:49:53.727

@Bruce Forte Thanks! This got rid of 8 bytes. (It only went down to 270 though because I also had to fix a thing to make it so that it would swap words even if the highest similarity was 0; this added a byte). – Harmless – 2017-08-09T13:07:31.763

1

No problem and welcome to PPCG! If you haven't seen already, these kind of posts are very helpful. Btw .split(' ') can be replaced by .split().

– ბიმო – 2017-08-09T13:17:54.670

Wait, which test cases did you change, and what was wrong with them? – geokavel – 2017-08-09T15:15:13.823

I don't have enough rep to change a post, but the apparent contradiction was for the first example - the given answer for 'drunk uncle needs your help' was 'your uncle help drunk needs' over 'your uncle needs drunk help'. Both of these answers swapped words with the same similarity score, and they both follow your given tie-breaker by using the first of the pair to decide which to swap, in the sense that they both start with the first word. (I realise now as I write this that the contradiction is not really that, but more an ambiguity). The given way to decide- running out of chars see next- – Harmless – 2017-08-09T16:53:28.223

The given way to decide between these is to choose the matching word, or as you more subtly/literally put it 'the one that maximises drunk ness similarity with that word'. This would make sense in a situation with two pairs of words, but in this example it is still ambiguous. Can I assume, that in a situation like this, you would choose the one with the lowest index (furthest from the left)? – Harmless – 2017-08-09T17:09:26.620

Yes, I meant to say in the case of a tie, first pick the left-most word that can get a max DS. Then match it with the left-most word that achieves max DS. – geokavel – 2017-08-09T17:23:05.350

@geokavel That's kind of handy as that's what both a) I interpreted it as before I re-read it and b) that's what I wrote the code to do. Also, I just realised that all the examples are correct, for some reason I didn't get that the S1 and S2 (and S3) were you feeding each answer back in. – Harmless – 2017-08-09T18:56:47.437

Wait a minute, If you feed in an answer into the formula, it reverses the drunkness – Harmless – 2017-08-09T18:58:12.373

@geokavel I also just realised that following the formula, if you put a drunkspeak answer into the formula, it won't drunkify it further - the most similar words in the sentence are the pair you just swapped, so it will swap them... reversing the drunkness. – Harmless – 2017-08-09T19:00:51.887

Yeah, I dont exactly feed it back in. I just follow these rules: 1) Words that have moved can't move again. 2) Keep swapping until there's no pairs left to swap. – geokavel – 2017-08-09T19:24:53.513

@geokavel I... didn'tsee that. I don't think I'm good at reading. Back to the drawing board it is – Harmless – 2017-08-09T20:23:16.280