Code Golf: Forwards sdrawkcaB sdrawkcaB Forwards Forwards sdrawkcaB

14

1

Task

  • The user inputs a sentence - words only. Any input other than letters or spaces, including integers and punctuation, should throw an exception: "Sentence must only use letters".
  • The output has a pattern, where some words are reversed and others words are normal.
  • The pattern starts as a normal word, the next two words are reversed, then the next two words are normal and the pattern continues.
  • An example of where the words should be normal and where words reversed is below:

Normal - Reversed - Reversed - Normal - Normal - Reversed - Reversed - Normal ...

Input Example

She sells Sea shells on the Sea shore

Output Example

She slles aeS shells on eht aeS shore

Additional Rules

  • If capital letters are used, they should remain on the letter they were originally posted on.
  • Any multiple spaces initially posted on input should be reduced to one space. For example Programming Puzzles and Code Golf becomes Programming selzzuP dna Code Golf

Shortest Code Wins!!

Happy coding...

Belfield

Posted 2015-10-30T21:58:49.227

Reputation: 579

All contests require an objetive winning criterion. Code golf (shortest code wins) should work well for this. You should also clarify what counts as word bondaries. Are words always composed of letters? Are they always separated by a single space? Also, the for example part is the only pattern that is used here, yes? – Dennis – 2015-10-30T22:05:07.580

Could you also include a test case that illustrates the rule from the fourth bullent point? – Dennis – 2015-10-30T22:10:36.330

"input including an integer should be rejected" What does that mean? Should the function throw an error? Output = Input? – Stewie Griffin – 2015-10-30T22:24:40.147

I have re-edited the description. Thanks for your feedback - anything else please just comment – Belfield – 2015-10-30T22:51:17.217

That may be a good idea... – Belfield – 2015-10-30T23:07:51.520

8Many programming languages do not have exceptions. – Doorknob – 2015-10-30T23:30:34.343

1@Doorknob: True, but sometimes challenges cannot be solved by all languages. Other examples are graphical output, file or web access. No need to worry. – nimi – 2015-10-30T23:46:42.280

15@nimi It seems entirely unnecessary to restrict a challenge to a small subset of languages for such a trivial reason. – Doorknob – 2015-10-30T23:56:34.157

Yep, this problem seems over-specified. – Yakk – 2015-10-31T01:20:09.510

1Should newlines count as a valid character? What about tabs? Should all whitespace be valid? – Downgoat – 2015-10-31T01:32:46.540

In the example about multiple spaces, there are no multiple spaces, just 1 newline. Could you please explaint better? – edc65 – 2015-10-31T01:32:49.500

10This otherwise-good challenge is ruined by the rule Any input other than letters or spaces, including integers and punctuation, should throw an exception: "Sentence must only use letters". It means implementing a secondary task totally unrelated to the challenge of reversing words, cuts out languages that don't have exceptions, and requires hardcoding or compressing a long string that takes up a lot of the byte count. – xnor – 2015-10-31T07:53:17.580

@Vihan yes apologies, I have edited the description above so it is explained better. Just multiple spaces should be dealt with as one space. – Belfield – 2015-10-31T08:14:26.223

@xnor unfortunately posting a question is a bit of a conundrum... initially I posted the request as a very simple question of reversing and not reversing. People wanted more clarity to my question, which is good because it helps answers be more accurate - however the downfall being that it comes with constraints - I must have edited this question 30 odd times now! It is unfortunately a "damned if you do, damned if you don't". I realise now it is not ideal, but unfortunately that is the question and I will not be changing it. Thanks for your input. – Belfield – 2015-10-31T08:19:20.010

2

@Belfield Yes, I see your bind. I guess there's nothing you can do now. In the future, try posting in the Sandbox to get feedback before posting.

– xnor – 2015-10-31T08:29:18.737

3@Belfield a good challenge is much more difficult than a good answer. I enjoyed this one anyway, and the next wil be better. – edc65 – 2015-10-31T10:19:22.750

@edc65 thanks for the appreciation - code golf has helped me with interview tests... so it's nice for me to give back to the community – Belfield – 2015-10-31T10:52:06.350

Answers

15

TeaScript, 55 bytes 58 60 69 76 78 80 87 89

xO`a-z `?xl(#~-i&2?l:lv(),/ +/):Ld`SÀZn­ Û § «e Ò5s`

This is extremely short, I'm very happy with it.

The last ~20 characters may seem like gibberish but that's "Sentence must only use letters" encoded. All the characters have char codes below 256 so each are one byte

Explanation

xO`a-z `?  // If input contains only a-z and space...

   xl(#       // Loop through input 
      ~-i&2?  // If (index - 1 "unary and"ed with 2) isn't 0...
          :l,     // Leave alone
          lv()    // Otherwise, reverse string
       / +/ // Loops on spaces
   )

:Ld`SÀZn­ Û § «e Ò5s` // Otherwise... decompress and print  the error string

Downgoat

Posted 2015-10-30T21:58:49.227

Reputation: 27 116

Thanks for posting the test - very nice. Every one is in the same boat when it comes to the error - no golfing that line – Belfield – 2015-10-31T00:07:45.493

Strange, now it works in Firefox. But I also used Firefox earlier. – Jakube – 2015-10-31T14:46:25.337

Best answer so far! – Belfield – 2015-11-01T18:26:32.303

What? You beat Pyth?! With a JS-based language?!? How is that even possible?!?! – ETHproductions – 2015-11-25T03:12:26.293

2@ETHproductions You can always win as long as Dennis isn't competing :p – Downgoat – 2015-11-25T05:51:23.923

4

Haskell, 141 bytes

r=reverse
f x|all(`elem`(' ':['a'..'z']++['A'..'Z']))x=unwords$zipWith($)(cycle[id,r,r,id])$words x|1<2=error"Sentence must only use letters"

Almost 2/3 of the code is for error checking. Seems to be the first real world challenge.

The work is done by unwords$zipWith($)(cycle[id,reverse,reverse,id])$words x which splits the input into a list of words, zips it with the cycling list of functions [id,reverse,reverse,id,id,reverse...] and joins the result with spaces back to a single string.

Thanks to @Christian Irwan for 2 bytes.

nimi

Posted 2015-10-30T21:58:49.227

Reputation: 34 639

"Sentence must only user letters" can be changed to "Sentence must only use letters" - my bad on the error! – Belfield – 2015-10-30T23:11:35.640

@Belfield: fixed – nimi – 2015-10-30T23:13:54.947

Why don't r=reverse? – Akangka – 2015-10-31T15:53:49.720

@ChristianIrwan: Thanks! (In an early version I had a pointfree function without a name, so using two times reverse and r=reverse had the same length, because of the missing f=. Didn't check again when moving to non pointfree). – nimi – 2015-10-31T16:09:51.683

3

JavaScript (ES6) 122

f=s=>/[^a-z ]/i.test(s)?"Sentence must only use letters":s.split(/ +/).map((w,i)=>~-i&2?w:[...w].reverse().join``).join` `

alert(f(prompt('?','She sells Sea shells on the Sea shore')))

edc65

Posted 2015-10-30T21:58:49.227

Reputation: 31 086

When there is a newline in the input, it outputs an error, from the example I don't think this is supposed to happen – Downgoat – 2015-10-31T01:27:29.780

1@Vɪʜᴀɴ it's tricky, The example is about multiple spaces, but then there are no multiple spaces - just 1 newline. I think it was mangled by SO editor. IF we have to manage newlines and other generic space, the byte count increase by 2 – edc65 – 2015-10-31T01:31:23.490

2

Python, 163 160 157 145

k=raw_input()
k=["Sentence tsum ylno use letters",k][k.replace(' ','').isalpha()]
for i,x in enumerate(k.split()):print x[::-1if(i+1)/2%2else 1],

Removed 15 characters, thanks Mego!!

Moose

Posted 2015-10-30T21:58:49.227

Reputation: 883

Yes, afraid nimi has a point... – Belfield – 2015-10-30T23:28:52.697

Shoot, I missed that. I'll revise it. – Moose – 2015-10-30T23:32:38.730

@Mego, re.search returns None (which can't be used as an index) if the result isn't found, and adding "!=None" is actually one byte longer than my original method. I saved 3 bytes by merging the last two lines though. Thanks! – Moose – 2015-10-31T01:11:50.630

2

Retina, 103 bytes

\s+

(?<=^\S+ (\S+ )?((\S+ ){4})*)
;
+`(;\S*)(\S)
$2$1
;

i`.*[^a-z ].*
Sentence must only use letters

There should be a single space on the second line, which SE seems to be swallowing. Run the code from a single file with the -s flag.

Retina has no concept of exceptions so the output is simply replaced by Sentence must only use letters if there are non-letter non-whitespace characters in the input.

Martin Ender

Posted 2015-10-30T21:58:49.227

Reputation: 184 808

2

Pyth, 61 bytes

?.A}R+G\ rz0jd.e_W%%k4 3bfTczd"Sentence must only use letters

Try it online.

PurkkaKoodari

Posted 2015-10-30T21:58:49.227

Reputation: 16 699

1

Bash + coreutils, 108

[ ${@//[a-zA-Z]/} ]&&echo Sentence must only use letters||for t;{
((++i/2%2))&&rev<<<$t||echo $t
}|tr \\n \ 

The last character of this program is a space.

Input is taken from the command line:

$ ./norrevvevnor.sh Programming Puzzles and Code$'\n' Golf
Programming selzzuP dna Code Golf $ 
$ ./norrevvevnor.sh Programming Puzzles and Code$'\n' Golf1
Sentence must only use letters
$ 

Digital Trauma

Posted 2015-10-30T21:58:49.227

Reputation: 64 644

1

Julia, 150 134 bytes

s->ismatch(r"[^a-z ]"i,s)?error("Sentence must only use letters"):(i=3;join([(i+=1;isodd((i+1)i÷2)?reverse(w):w)for w=split(s)]," "))

Ungolfed:

function f(s::AbstractString)
    if ismatch(r"[^a-z ]"i, s)
        error("Sentence must only use letters")
    else
        i = 3
        a = [(i += 3; isodd((i + 1)i ÷ 2) ? reverse(w) : w) for w = split(s)]
        return join(a, " ")
    end
end

Saved 16 bytes thanks to Glen O!

Alex A.

Posted 2015-10-30T21:58:49.227

Reputation: 23 761

Before anything else, might I suggest reversing the logic of the initial conditional and assigning r to be its result? That is, r=ismatch(...)||error(...) - will shave off a few characters, and reverse the conditional that uses r. Will comment again with, I suspect, some more savings – Glen O – 2015-10-31T09:17:20.033

Minor correction - I had || to deal with the negation, then realised that the negation isn't necessary. Reverse it back to &&. And even better, use ?: instead to do it even better. s->(r=ismatch(r"[^a-z ]"i,s))?error("Sentence must only use letters"):join([(iseven(i)&&(r=!r);r?reverse(w):w)for(i,w)=enumerate(split(s))]," ") for 144 bytes. And I think I can do better inside join... – Glen O – 2015-10-31T09:24:54.123

Here's a streamlined version of your solution, with 134 bytes: s->ismatch(r"[^a-z ]"i,s)?error("Sentence must only use letters"):(i=3;join([(i+=1;isodd((i+1)i÷2)?reverse(w):w)for w=split(s)]," ")) – Glen O – 2015-10-31T09:45:43.527

@GlenO Awesome suggestions, thanks! – Alex A. – 2015-10-31T20:48:38.190

1

Pyth, 72

=zflTc?:z"[^A-Za-z ]"0"Sentence tsum ylno use letters"zdjd.e?%/hk2 2_bbz

Doesn't beat the other Pyth answer, but I already invested time into writing it. It's basically a translation of my Python answer.

Try it online

Moose

Posted 2015-10-30T21:58:49.227

Reputation: 883

1

Julia, 109 bytes

s->(i=0;join([isalpha(w)?(i+=1)%4>1?reverse(w):w:error("Sentence must only use letters")for w=split(s)]," "))

i=0 and (i+=1)%4>1 are used to decide whether each word gets reversed or not. isalpha applies to the words after being split using split(s) to determine whether or not there are characters that aren't letters (spaces have already been removed by this point). join restores the string after the manipulation, unless the error is thrown.

Glen O

Posted 2015-10-30T21:58:49.227

Reputation: 2 548

0

Japt v2.0a0 -S, 41 bytes

¸¬è\L ?`SÀZn­ Û § «e Ò5s`:UeS²S ¸ËzEc2

Try it

¸¬è\L ?`...`:UeS²S ¸ËzEc2     :Implicit input of string U
¸                             :Split on spaces
 ¬                            :Join
  è                           :Count occurrences of
   \L                         :RegEx /[^A-Z]/gi
      ?`...`:                 :If truthy return the compressed string "Sentence must only use letters", else
             Ue               :Recursively replace in U
               S²S            :  Two spaces with one
                   ¸          :Split on spaces
                    Ë         :Map each element at 0-based index E
                     z        :  Rotate clockwise by 90 degrees multiplied by
                      Ec2     :    E rounded up to the nearest multiple of 2
                              :Implicit output, joined with spaces

Shaggy

Posted 2015-10-30T21:58:49.227

Reputation: 24 623

0

Perl 5 -ap, 80 bytes

map$_=++$i%4>1?reverse:$_,@F;$_=/[^a-z ]/i?"Sentence must use only letters":"@F"

Try it online!

Xcali

Posted 2015-10-30T21:58:49.227

Reputation: 7 671

0

Jelly, 39 bytes

³Ḳ¹ƇUJ2&TƲ¦K
“*[,ṛDṾȧƤ°Ġṛ©¦»
ØẠ” ṭ³eƇ⁼£

Try it online!

Thanks to Erik the Outgolfer. He saved me from a few extra bytes and from many hours of frustration.

Here's a 46 byte solution

It actually throws a python syntax error when the input contains invalid characters.

³Ḳ¹ƇUJ2&TƲ¦K
“çỤḷṁŀDṀẠṠGmḟĖƲƑ⁽Ḳḟ»ŒV
ØẠ” ṭ³eƇ⁼£

Try it online!

Zylviij

Posted 2015-10-30T21:58:49.227

Reputation: 390

0

Java, 215 bytes

Regex is fun

s->{if(s.split("[^a-zA-Z ]").length>1)throw new Error("Sentence must only contains letters");else{int i=1;for(String a:s.split(" "))System.out.print((i++%2<1?new StringBuffer(a).reverse():a)+(a.isEmpty()?"":" "));}}

Try it online!

Benjamin Urquhart

Posted 2015-10-30T21:58:49.227

Reputation: 1 262

Your output currently isn't correct. You now output She slles aeS shells no the aeS shore, but it should be She slles aeS shells on eht aeS shore instead (first normal; then alternating in pairs of 2 reversed or not). Two issues cause this. You now increase i even if an item is empty, and i++%2<1 should be i++%4>1 instead. Here a fixed 211 bytes version.

– Kevin Cruijssen – 2019-04-24T12:11:32.153

@KevinCruijssen this is what I get for not reading carefully enough – Benjamin Urquhart – 2019-04-24T12:45:23.887

0

05AB1E, 36 bytes

ðKDáÊi“¸–ƒ—€É€Å™ê“.ªFë#áεN4%>2÷iR]ðý

Try it online.

Throws the following error when the input does not only contain [A-Za-z ]:

(RuntimeError) Could not convert Sentence must only use letters to integer.

Explanation:

ðK                   # Remove all spaces from the (implicit) input-string
  Dá                 # Create a copy, and remove everything except for letters from this copy
    Êi               # If the copy with letters removed and the original are NOT equal:
      “¸–ƒ—€É€Å™ê“   #  Push dictionary string "sentence must only use letters"
                  .ª #  With sentence capitalization
      F              #  And try to loop that many times, causing the error above
     ë               # Else:
      #              #  Split the (implicit) input-string on spaces
       á             #  Only keep letters (which will remove empty items caused by multiple
                     #  adjacent spaces in the input, which is shorter than `õK`)
        ε            #  Map each word to:
         N4%>2÷      #   Calculate ((index modulo-4) + 1) integer-divided by 2
                     #   (results in 0,1,1,2,0,1,1,2,0,1 for indices 0,1,2,3,4,5,6,7,8,9)
               i     #   If this is exactly 1:
                R    #    Reverse the current word
     ]               # Close the if-statement, map, and if-else statement
      ðý             # Join the modified word-list by spaces
                     # (and then output it implicitly as result)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why “¸–ƒ—€É€Å™ê“ is "sentence must only use letters".

Kevin Cruijssen

Posted 2015-10-30T21:58:49.227

Reputation: 67 575

0

PHP, 147 bytes

foreach(explode(' ',$argn)as$a){if(!ctype_alpha($a))throw new Exception('Sentence must only use letters');$o.=(++$i%4>1?strrev($a):$a).' ';}echo$o;

Try it online!

Or if die() is acceptable as an "Exception":

PHP, 131 bytes

foreach(explode(' ',$argn)as$a){if(!ctype_alpha($a))die('Sentence must only use letters');$o.=(++$i%4>1?strrev($a):$a).' ';}echo$o;

Try it online!

640KB

Posted 2015-10-30T21:58:49.227

Reputation: 7 149

0

Pyth, 55 bytes

?--rz0Gd"Sentence must only use letters"jd.e_W%%k4 3bcz

Borrowed the %%k4 3 bit from Pietu1998. Saved one additional byte.

Try it online: Demonstration or Test Suite

Explanation

?--rz0Gd"..."jd.e_W%%k4 3bcz   implicit: z = input string
   rz0                         convert z to lower-case
  -   G                        remove all letters
 -     d                       remove all spaces
?                              if there is some chars left than
        "..."                    print the string "Sentence must only ..."
                               else:
                          cz     split z by spaces or multiple spaces
               .e                map each pair (k index, b string) of ^ to: 
                 _       b          b or reversed of b, depending on
                  W%%k4 3           (k mod 4) mod 3
             jd                  join the result by spaces

Jakube

Posted 2015-10-30T21:58:49.227

Reputation: 21 462