44
\$\begingroup\$

The challenge

Well, I think it is quite clear, isn't it? You have to make a function or a program that takes a string as an argument and outputs the corrispondent Yoda-speaking.

This is , so least number of bytes wins.

The input

The input could be any string without linefeed. You can translate a string if it is composed like this:

Subject + Verb + Something else.

Where Subject is a personal pronoun (I, you, he, she, it, we, they). You don't have to recognize that the second word is a verb.

If the first word isn't a pronoun, the input is valid but the output will be Too difficult, this sentence is.

You have to win this code challenge -> Translatable
Luke has to win this code challenge -> Untranslatable

Input can end with a letter, a . or a !, not with a ?.

Furthermore, strings can contain Non-Ascii, Parenthesis, commas, colons ...

The output

In case of a translatable sentence, the output is the same sentence, with the subject and the verb at the end of the sentence.

You have to win this code challenge -> To win this code challenge, you have.

Comma, period and lower-case on the pronoun are mandatory. (Except, of course, if the pronoun is I).

As stated before, if it is untranslatable you have to output the string Too difficult, this sentence is.

Examples

You have to win this code challenge -> To win this code challenge, you have.
He won this code challenge -> This code challenge, he won.  (I know this is not yoda-speaking, but I don’t want to overcomplicate this challenge)
I ate an ice cream earlier! -> An ice cream earlier, I ate.
I liked the Star Wars original trilogy more than the prequel’s one. -> The Star Wars original trilogy more than the prequel’s one, I liked.
I find your lack of faith disturbing -> Your lack of faith disturbing, I find.
I think we are done with the examples -> We are done with examples, I think.
He is your son, Vader -> Your son, Vader, he is.
I think they’ll add new features -> They’ll add new features, I think.
I made a fantastic code challenge (I hope) -> A fantastic code challenge (I hope), I made.
I love constants like π -> Constants like π, I love.

I’ll be the next President, I swear! -> Too difficult, this sentence is.
This challenge is great! -> Too difficult, this sentence is.
Is this challenge great? -> Too difficult, this sentence is.
Luke is not ready for this task -> Too difficult, this sentence is.
Somebody loves constants like π -> Too difficult, this sentence is.
[Empty string] -> Too difficult, this sentence is.
\$\endgroup\$
16
  • 9
    \$\begingroup\$ From a non-question point of view, shouldn't infinitives be moved as well? For example, the You have to win this code challenge should be This code challenge, you have to win. \$\endgroup\$ Jan 4, 2016 at 12:07
  • 9
    \$\begingroup\$ "To win this code challenge, you have." sounds really strange. \$\endgroup\$
    – nicael
    Jan 4, 2016 at 12:35
  • 3
    \$\begingroup\$ Can the input contain commas? What if the input doesn't end in a letter, period or !? Is that guaranteed not to happen or should we handle that and print the same thing as when there is no leading pronoun. Can the input contain linefeeds? Apostrophes? Colons/parentheses/backticks? Non-ASCII characters? You say the "the input could be any string", but your test cases only cover very specific types of strings. \$\endgroup\$ Jan 4, 2016 at 13:08
  • 4
    \$\begingroup\$ 'have to' is an odd helper-verb construction peculiar to English; it's unlikely Yoda would use it. "This code challenge, win, you must." On the other hand, Yoda has his own helper-verb constructions he tends to use: "This code challenge, won, he did." I can't picture Yoda saying "This code challenge, he won" or "to win this code challenge, you have". \$\endgroup\$ Jan 4, 2016 at 15:16
  • 4
    \$\begingroup\$ Don't the answers need more 'Mmmmm's? \$\endgroup\$
    – Steve Ives
    Jan 5, 2016 at 14:56

6 Answers 6

17
\$\begingroup\$

Retina, 162 137 145 134 131 129

Multiple punctuation is now handled correctly. Test case: You will not win this challenge...! -> Not win this challenge..., you will.

Try it Online!

[.!]$

T`A-Z`a-z`^\w\w
G`^(I|we|you|s?he|it|they) \S+ \S
(\S+ \S+) (.*)
$2, $1.
T`a-z`A-Z`^.
^$
Too difficult, this sentence is.

Description:

If there is punctuation in the end, delete it.

[.!]$

^empty line

Transform the pronoun to lower case, except it is I.

T`A-Z`a-z`^\w\w

Filter out any line that does not match <Pronoun><space><word><space><word>...

G`^(I|we|you|s?he|it|they) \S+ \S

Split into pronoun + verb, remainder. Then rearrange.

(\S+ \S+) (.*)
$2, $1.

Transform the first character to upper case.

T`a-z`A-Z`^.

If the result is empty, it didn't pass the filter above. Print an error message.

^$
Too difficult, this sentence is.
\$\endgroup\$
6
  • \$\begingroup\$ The character classes in transliteration mode don't use square brackets. \$\endgroup\$ Jan 4, 2016 at 13:16
  • 1
    \$\begingroup\$ Also, [^ ] can probably be replaced with \S everywhere, and in the first regex [^ ]+ can be replaced with .+. In the character classes you don't need to escape . so [.!] works fine. Also, since you don't swap the order of $1 and $2 in the third stage, you can capture them into a single group and save 5 bytes. \$\endgroup\$ Jan 4, 2016 at 13:20
  • \$\begingroup\$ ([^I]|It) can be shortened to ^\w\w \$\endgroup\$ Jan 4, 2016 at 13:22
  • \$\begingroup\$ Wow, what a load of improvements. Thanks. \$\endgroup\$
    – Rainer P.
    Jan 4, 2016 at 13:33
  • \$\begingroup\$ I think I|It can become I?, if Retina supports that \$\endgroup\$ Jan 4, 2016 at 15:47
7
\$\begingroup\$

ES6, 212

This can probably a bit further golfed down:

i=>(r=/(you|s?he|it?|we|they)( \S+) ([^\.!?]+)/i.exec(i))?(c=(a,b)=>a[`to${['Low','Upp'][b]}erCase`]())(r[3].slice(0,1),1)+r[3].slice(1)+", "+c(r[1],+(/i/i.test(r[1])))+r[2]+".":"Too difficult, this sentence is."

JSFiddle (requires up-to-date browser like Chrome) or run it via node.js

Ungolfed:

i=>{
    r=/(you|s?he|it?|we|they)( \S+) ([^\.!?]+)/i.exec(i); //Main RegExp
    c=(a,b)=>a[`to${['Low','Upp'][b]}erCase`](); //shortcut for toUpperCase/toLowerCase
    if (r)
        return c(r[3].slice(0,1),1)+r[3].slice(1) + ", " //the "something else", properly formated
             + c(r[1], +(/i/i.test(r[1]))) //The subject lowercased except for "i" or "I"
             + r[2] + "."; //The End
    else //no match, no sentence to translate
        return "Too difficult, this sentence is.";
}
\$\endgroup\$
4
  • \$\begingroup\$ Broken test: I think they’ll add new features -> returns They, I think. on Google Chrome 47.0.2526.106 m. Also, it doesn't like I love constants like π. To add on that, I made a fantastic code challenge (I hope) returns A fantastic code challenge , I made. instead of A fantastic code challenge (I hope), I made. \$\endgroup\$ Jan 4, 2016 at 14:35
  • \$\begingroup\$ @IsmaelMiguel Fixed, but even got 3 characters less due to another bug I also fixed \$\endgroup\$
    – Helco
    Jan 4, 2016 at 14:56
  • \$\begingroup\$ It solved all issues, all tests seem fine. Well done! You got my upvote. \$\endgroup\$ Jan 4, 2016 at 14:59
  • 3
    \$\begingroup\$ You need to add ^ to the start of your regex otherwise a sentence with any text before the pronoun will still be parsed as valid. \$\endgroup\$
    – user81655
    Jan 4, 2016 at 15:27
6
\$\begingroup\$

JavaScript (ES6), 164 bytes

s=>([,p,,i,r]=s.match`^(((I)|You|He|She|It|We|They) \\S+) (.*?)[.!]?$`)?r[0].toUpperCase()+r.slice(1)+`, ${i?p:p.toLowerCase()}.`:"Too difficult, this sentence is."

Explanation

It's almost painful how many bytes capitalising the first letter of a string takes in JavaScript...

s=>

  // Match and get specific parts of the input string
  ([,p,,i,r]=s.match`^(((I)|You|He|She|It|We|They) \\S+) (.*?)[.!]?$`)?

    r[0].toUpperCase()+r.slice(1)     // capitalise first letter
      +`, ${i?p:p.toLowerCase()}.`    // lower-case the pronoun (unless it is I)
  :"Too difficult, this sentence is."

Test

Test does not use destructuring assignment to make it more cross-browser compatible.

var solution = s=>(p=s.match`^(((I)|You|He|She|It|We|They) \\S+) (.*?)[.!]?$`)?p[4][0].toUpperCase()+p[4].slice(1)+`, ${p[3]?p[1]:p[1].toLowerCase()}.`:"Too difficult, this sentence is."
<input type="text" id="input" value="I love constants like π...!" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

\$\endgroup\$
3
  • \$\begingroup\$ 162 chars: var solution = s=>(p=s.match^(((It?)|You|[HW]e|[ST]hey) \\S+) (.*?)[.!]?$)?p[4][0].toUpperCase()+p[4].slice(1)+, ${p[3]?p[1]:p[1].toLowerCase()}.:"Too difficult, this sentence is." \$\endgroup\$
    – wally
    Jan 5, 2016 at 19:36
  • \$\begingroup\$ @wally Thanks, but unfortunately that regex would make It stay capitalised and also match Shey instead of She. \$\endgroup\$
    – user81655
    Jan 5, 2016 at 23:22
  • \$\begingroup\$ Ah, my testing was insufficient! Yes I can see why... Ah well. \$\endgroup\$
    – wally
    Jan 6, 2016 at 9:25
3
\$\begingroup\$

Python, 261 bytes

import re
def a(b):
 if b[-1:]in".!":
  b=b[:-1]
 if re.match('(I|YOU|S?HE|IT|WE|THEY) \w+ \S+',b.upper()):
  b=(b+',').split()
  if b[0]!="I":
   b[0]=b[0].lower()
  b=" ".join(b[2:]+b[:2])
  return b[0].upper()+b[1:]
 return "Too difficult, this sentence is."

Turns out Python doesn't mind things like b[-1]in".!" Next I'll play with the match object more, if no-one beats me to it :)

\$\endgroup\$
3
  • \$\begingroup\$ I think you can remove a space in the b=b[:-1] part. \$\endgroup\$ Jan 5, 2016 at 1:42
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ thanks! \$\endgroup\$
    – Rob Grant
    Jan 5, 2016 at 8:48
  • 3
    \$\begingroup\$ you can put b=b[:-1] at the end of the line with the if. you can remove the space from after the return on the last line. this will break python3 compatibility by replacing 2 spaces with a tab and 3 with a tab and a space \$\endgroup\$ Jan 5, 2016 at 10:25
2
\$\begingroup\$

Python, 218 217 204 bytes

Not sure if this can be further golfed down.

def f(s):t=s.split();u=' '.join(t[2:]).rstrip('!.');return['Too difficult, this sentence is.','%s, %s %s.'%(u[0].upper()+u[1:],['I',t[0].lower()][t[0]!='I'],t[1])][t[0]in'I We You He She It They'.split()]

Ungolfed:

def f(s):
    t = s.split()
    u = ' '.join(t[2:]).rstrip('!.')
    return [
        'Too difficult, this sentence is.',
        '%s, %s %s.' % (u[0].upper() + u[1:],
                        ['I', t[0].lower()][t[0] != 'I'],
                        t[1])
    ][t[0] in 'I We You He She It They'.split()]
\$\endgroup\$
1
  • \$\begingroup\$ you can change s.split(' ') to s.split() and 'I|We|You|He|She|It|They'.split('|') to 'I We You He She It They'.split(), replace the if...else with the same boolean list used elsewhere, change t[0]in to t[0]in, remove the spawce around the return \$\endgroup\$
    – Blue
    Jan 5, 2016 at 17:47
1
\$\begingroup\$

GNU sed, 129 bytes

I'm including +1 byte for the -r flag.

#!/bin/sed -rf

/^I /b
s/^(You|[HW]e|She|It|They) /\L&/
t
s/.*/Too difficult, this sentence is./p
d
:
s/[.!]$//
s/^([^ ]+ [^ ]+) (.*)/\u\2, \1./

Explanation

If we match a leading I we jump to the label:

/^I /b

If we match one of the other pronouns, we downcase it, then jump to the label:

s/^(You|[HW]e|She|It|They) /\L&/
t

Otherwise we print the failure message and move to the next input line:

s/.*/Too difficult, this sentence is./p
d

If we jumped to the label, we remove any final punctuation:

:
s/[.!]$//

and swap the first two words with the rest of the sentence, capitalising the new first word and adding the required punctuation as we do so:

s/^([^ ]+ [^ ]+) (.*)/\u\2, \1./
\$\endgroup\$
2
  • \$\begingroup\$ Your program does not check whether the input consists of at least three words. Sentences like You are pass first and second line but don't match on the last, so the output is you are instead of the error message. Add a check like ...|They) \S+ \S/\L&/ to the first two lines. \$\endgroup\$
    – Rainer P.
    Jan 6, 2016 at 22:44
  • \$\begingroup\$ @Rainer - You're right (I blame the lack of test cases for short inputs). I'll look at how to rework this soon. \$\endgroup\$ Jan 7, 2016 at 16:29

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.