27
\$\begingroup\$

Given a list or delimited string, output a list or delimited string with the first character of each word one word later.

For this challenge, a "word" consists of only all printable ASCII characters, except the space, newline, and tab character.

For example, take the string "Good afternoon, World!" (space-delimited):

1. String
"Good afternoon, World!"

2. Get the first characters:
"[G]ood [a]fternoon, [W]orld!"

3. Move the characters over. The character at the end gets moved to the beginning.
"[W]ood [G]fternoon, [a]orld!"

4. Final string
"Wood Gfternoon, aorld!"

This is , so shortest code wins!

Test cases:

Input -> output (space-delimited)

"Good afternoon, World!" -> "Wood Gfternoon, aorld!"
"This is a long sentence." -> "shis Ts i aong lentence."
"Programming Puzzles and Code Golf" -> Grogramming Puzzles Pnd aode Colf"
"Input -> output" -> "onput I> -utput"
"The quick brown fox jumped over the lazy dog." -> "dhe Tuick qrown box fumped jver ohe tazy log."
"good green grass grows." -> "good green grass grows."
\$\endgroup\$
  • \$\begingroup\$ Is a trailing space allowed in the output? \$\endgroup\$ – Business Cat May 24 '17 at 15:01
  • \$\begingroup\$ Can we assume there will be at most one space between words? \$\endgroup\$ – math junkie May 24 '17 at 15:03
  • \$\begingroup\$ with some rules on which letters can follow each other, you'd have a spoonerism generator en.wikipedia.org/wiki/Spoonerism \$\endgroup\$ – Display name May 24 '17 at 15:27
  • \$\begingroup\$ @BusinessCat Yes. \$\endgroup\$ – Comrade SparklePony May 24 '17 at 15:37
  • \$\begingroup\$ @mathjunkie Yes. \$\endgroup\$ – Comrade SparklePony May 24 '17 at 15:37

30 Answers 30

10
\$\begingroup\$

05AB1E, 7 6 bytes

€ćÁ2ôJ

Explanation:

€ć      Extract head of each
  Á     Rotate to the right
    2ô  Split into pieces of length two
      J Join

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You can take input and output as a list, you know. \$\endgroup\$ – Comrade SparklePony May 24 '17 at 15:37
8
\$\begingroup\$

Japt, 11 10 9 8 bytes

Takes advantage of Japt's index wrapping and negative indexing.

ËhUgEÉ g

Try it online


Explanation

        :Implicit input of array U (each element is an individual word).
Ë       :Map over the array.
h       :Replace the first character of the current element (word) ...
Ug      :  with the word in the array at index ...
EÉ      :    current index (E) -1's ...
g       :  first character.
        :Implicit output of array of modified words
\$\endgroup\$
  • \$\begingroup\$ I think you can take input as a list as well, saving a further byte on the ¸ \$\endgroup\$ – ETHproductions May 24 '17 at 15:40
  • \$\begingroup\$ That might be a stretch, @ETHproductions, but I'll ask. EDIT: Confirmed here \$\endgroup\$ – Shaggy May 24 '17 at 15:41
  • 1
    \$\begingroup\$ Yes, at the very beginning of the post it says "Given a list or delimited string," Not sure how long that's been there though (I guess since the challenge was first posted). \$\endgroup\$ – ETHproductions May 24 '17 at 15:43
  • \$\begingroup\$ Nice one! Using h was a good idea. I came up with £g´Y ¯1 +XÅ which can become £XhUg´Y ¯1 using your technique. \$\endgroup\$ – Oliver May 24 '17 at 16:54
5
\$\begingroup\$

Haskell, 43 bytes

p%((a:b):r)=(p:b):a%r
_%e=e
(%)=<<head.last

Try it online! Uses a list of strings for input and output.

Remembers the first letter of the previous word p, and recursively makes it the first letter of the current word while sending the new first letter down the chain. The previous first letter is initialized as the first letter of the last word.

\$\endgroup\$
4
\$\begingroup\$

Ruby, 85 77 63 bytes

Pretty sure this could be much shorter.

Edit: Thanks for @manatwork for collect -> map

a=gets.split;$><<a.zip(a.rotate -1).map{|x,y|y[0]+x[1..-1]}*' '
\$\endgroup\$
  • \$\begingroup\$ You could replace both .collect and .each with .map. \$\endgroup\$ – manatwork May 24 '17 at 16:08
  • 1
    \$\begingroup\$ -p flag (+1 byte) and i=-2;gsub(r=/\b\w/){$_.scan(r)[i+=1]} for ultimate golfage \$\endgroup\$ – Value Ink Jun 2 '17 at 21:48
4
\$\begingroup\$

Jelly, 6 bytes

Ḣ€ṙ-;"

Try it online!

Thanks to Dennis for reading the rules better than me, this returns a list of the words. It doesn't work as a full program.

\$\endgroup\$
4
\$\begingroup\$

CJam, 12 10 9 bytes

Saved 1 byte thanks to jimmy23013

q~Sf+:()o

Takes input as a list of words.

Try it online!

Explanation

     e# Example input: ["Good" "afternoon," "World!"]
q~   e# Read and eval the input.
     e# STACK: [["Good" "afternoon," "World!"]]
Sf+  e# Append a space to each word.
     e# STACK: [["Good " "afternoon, " "World! "]]
:(   e# Remove the first character from each substring.
     e# STACK: [["ood " 'G "fternoon, " 'a "orld! " 'W]]
)o   e# Remove and print the last element of the array.
     e# STACK: [["ood " 'G "fternoon, " 'a "orld! "]]
     e# Implicitly join the remaining array with no separator and output.
\$\endgroup\$
  • \$\begingroup\$ You can take input and output as a list, you know. \$\endgroup\$ – Comrade SparklePony May 24 '17 at 15:39
  • \$\begingroup\$ @ComradeSparklePony You confirmed that after I answered :P Golfing it now \$\endgroup\$ – Business Cat May 24 '17 at 15:44
  • \$\begingroup\$ )o for 1m>. \$\endgroup\$ – jimmy23013 May 25 '17 at 12:44
3
\$\begingroup\$

V, 7 bytes

Îxjp
{P

Try it online!

Explanation:

Î       " On every line:
 x      "   Delete the first character
  j     "   Move down a line
   p    "   And paste a character (into column 2)
{       " Move to the beginning of the input
 P      " And paste the last thing we deleted (into column 1)
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 46 bytes

s=>s.map((k,i)=>s.slice(i-1)[0][0]+k.slice(1))

Takes advantage of the fact that slice(-1) returns the last element of an array.

Snippet

f =

s=>s.map((k,i)=>s.slice(i-1)[0][0]+k.slice(1))

console.log(f(['Good', 'afternoon,', 'World!']));
console.log(f(['This', 'is', 'a', 'long', 'sentence.']));
console.log(f(['Programming', 'Puzzles', 'and', 'Code', 'Golf']));
console.log(f(['Input', '->', 'output']));
console.log(f(['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog.']));
console.log(f(['good', 'green', 'grass', 'grows.']));

\$\endgroup\$
  • \$\begingroup\$ Could you remove join? Question states that you can output a list. It would save 8 bytes \$\endgroup\$ – Craig Ayre May 25 '17 at 15:28
  • 1
    \$\begingroup\$ @CraigAyre, sweet, thanks! \$\endgroup\$ – Rick Hitchcock May 25 '17 at 15:37
3
\$\begingroup\$

Vim, 16, 9 bytes

<C-v>GdjPGD{P

7 bytes saved thanks to @Wossname!

Takes input one word per line, e.g.

Hello
world
and
good
day
to
you

I believe this should be fine since taking the input as a list is allowed.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ It can be done in 12 keystrokes if you do it 'by hand' as it were. Not sure how to articulate that syntax here or if it's even valid to do that in this puzzle. ^vGdjPGd$ggP (where ^v is the [control+v] key combo, just be sure to start with the cursor at the top left and be in command mode) \$\endgroup\$ – Wossname May 25 '17 at 13:20
  • \$\begingroup\$ @Wossname Ah, that's a great idea! Theres a couple small things I added to save even more bytes (for example, dd -> D, gg -> }) Thanks for the tip! \$\endgroup\$ – DJMcMayhem May 25 '17 at 16:39
  • \$\begingroup\$ I didn't know dd and gg both had shorter versions! Awesome :) \$\endgroup\$ – Wossname May 26 '17 at 7:17
  • \$\begingroup\$ How about using the "superscript HTML tags" around the letter v in the code instead of "<C-v>"? That would make the code look the right length when seen in the Answer. So your code would look like... <sup>V</sup>GdjPGD{P ... which looks pretty neat when the stackexchange web page formats it properly. \$\endgroup\$ – Wossname May 26 '17 at 7:25
  • 1
    \$\begingroup\$ I see, the curly braces jump around between paragraphs, it works here because we're only dealing with one paragraph. Cool. Oh wow that makes scrolling quickly through large code files really easy! Thanks for that tip. :) \$\endgroup\$ – Wossname May 26 '17 at 13:11
3
\$\begingroup\$

><>, 44 45 bytes

90.f3+0.>&i&01.>~r&l0=?;o20.
 i:" "=?^:1+ ?!^

Assumes space-separated words.

Correction by Aaron added 1 byte

\$\endgroup\$
2
\$\begingroup\$

Python 2, 74 bytes

Try it online

S=input().split()
print' '.join(b[0]+a[1:]for a,b in zip(S,S[-1:]+S[:-1]))

-5 bytes, thanks to @Rod

\$\endgroup\$
  • \$\begingroup\$ @Rod Good suggestion, thank you! \$\endgroup\$ – Dead Possum May 24 '17 at 15:39
  • 4
    \$\begingroup\$ S[:-1] can be shortened to S; zipping lists of different lengths automatically truncates whichever is longer \$\endgroup\$ – Julian Wolf May 24 '17 at 16:34
2
\$\begingroup\$

Haskell, 50 bytes

f=zipWith(:).((:).last<*>init).map head<*>map tail

Input and output are as lists of words.

\$\endgroup\$
  • 1
    \$\begingroup\$ Functions can be unnamed, so you can omit the f=. \$\endgroup\$ – nimi May 24 '17 at 16:37
  • 1
    \$\begingroup\$ Oh, cool, I didn't realize there was an online compiler for Haskell. I'll delete my comments, since I'm wrong ^^ \$\endgroup\$ – Nic Hartley May 24 '17 at 18:54
2
\$\begingroup\$

PHP, 62 bytes

$c=end($_GET);foreach($_GET as$g)echo$g|$g[0]=$c^$g^$c=$g,' ';
\$\endgroup\$
2
\$\begingroup\$

C#, 78 77 bytes

using System.Linq;a=>a.Select((s,i)=>a[i-->0?i:a.Count-1][0]+s.Substring(1));

Compiles to a Func<List<string>, IEnumerable<string>>, Full/Formatted version:

using System;
using System.Collections.Generic;
using System.Linq;

class P
{
    static void Main()
    {
        Func<List<string>, IEnumerable<string>> f = a =>
                a.Select((s, i) => a[i-- > 0 ? i : a.Count - 1][0] + s.Substring(1));

        Console.WriteLine(string.Join(" ", f(new List<string>() { "Good", "afternoon,", "World!" })));
        Console.WriteLine(string.Join(" ", f(new List<string>() { "This", "is", "a", "long", "sentence." })));

        Console.ReadLine();
    }
}
\$\endgroup\$
2
\$\begingroup\$

Brachylog, 12 bytes

{hᵐ↻|bᵐ}ᶠzcᵐ

Try it online!

Explanation

Example input: ["Good","afternoon,","World!"]

{      }ᶠ       Find: [["W","G","a"],["ood","fternoon,","orld!"]]
 hᵐ↻              Take the head of each string, cyclically permute them
    |             (and)
     bᵐ           Get the strings without their heads
         z      Zip: [["W","ood"],["G","fternoon,"],["a","orld!"]]
          cᵐ    Map concatenate on each list: ["Wood","Gfternoon,","aorld!"]
\$\endgroup\$
2
\$\begingroup\$

R, 72 70 bytes

function(x)paste0(substr(x,1,1)[c(y<-length(x),2:y-1)],substring(x,2))

Try it online

2 bytes saved thanks to Giuseppe.

Input and output are lists. Takes a substring consisting of the first letters, cycles the last one to the front, and pastes it together with a substring of the rest of each word. The cycling step is a killer, but I can't figure out a way to cut it down any further.

\$\endgroup\$
2
\$\begingroup\$

Python 2 + Numpy, 104 bytes

from numpy import *
s=fromstring(input(),"b")
m=roll(s==32,1)
m[0]=1
s[m]=roll(s[m],1)
print s.tobytes()
\$\endgroup\$
  • 1
    \$\begingroup\$ You need to include the import statement in the byte count. Cool answer! \$\endgroup\$ – Comrade SparklePony May 25 '17 at 0:12
  • \$\begingroup\$ also, you need to have your input and output code in the byte count \$\endgroup\$ – Felipe Nardi Batista May 25 '17 at 11:24
  • 1
    \$\begingroup\$ I think you can drop the final newline for 1 byte. \$\endgroup\$ – Ørjan Johansen Jun 4 '17 at 1:02
  • \$\begingroup\$ @ØrjanJohansen yes, also "b" instead of "u1" works, so -2 bytes. \$\endgroup\$ – Mikhail V Jun 4 '17 at 1:13
2
\$\begingroup\$

APL (Dyalog), 6 bytes

Takes matrix with one word per column.

¯1∘⌽@1

Try it online!

¯1∘⌽ rotate one step right

@ at

1 row 1

\$\endgroup\$
  • \$\begingroup\$ clever input idea \$\endgroup\$ – Jonah Oct 30 '17 at 0:21
1
\$\begingroup\$

Mathematica, 59 bytes

""<>#&/@Thread@{RotateRight@#~StringTake~1,#~StringDrop~1}&

Try it online!

Takes and returns a list of words.

If you prefer to take and return strings, this works for 87 bytes:

StringRiffle[Thread@{RotateRight@#~StringTake~1,#~StringDrop~1}&@StringSplit@#," ",""]&
\$\endgroup\$
1
\$\begingroup\$

Retina, 46 37 31 bytes

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

Try it Online

Still being golfed..

\$\endgroup\$
  • 1
    \$\begingroup\$ Can you not drop the (.*) and $3? \$\endgroup\$ – Neil May 24 '17 at 19:07
  • \$\begingroup\$ @Neil yeah, thanks \$\endgroup\$ – math junkie May 28 '17 at 0:41
  • \$\begingroup\$ If you turn the + in the first line to a * you turn (.* .) in the third line to (.*) for -2 bytes. Try it Online! \$\endgroup\$ – PunPun1000 Jul 3 '17 at 16:29
1
\$\begingroup\$

kdb+, 25 22 bytes

Solution:

rotate[-1;1#'a],'1_'a:

Example:

q)rotate[-1;1#'a],'1_'a:("The";"quick";"brown";"fox";"jumped";"over";"the";"lazy";"dog.")
"dhe"
"Tuick"
"qrown"
"box"
"fumped"
"jver"
"ohe"
"tazy"
"log."

Explanation:

1_'a:             // (y) drop first character of each element of a
,'                // join each left with each right
rotate[-1;1#'a]   // (x) take first character of each element of a, rotate backwards 1 char

Extra:

A version that takes a regular string (37 bytes):

q){" "sv rotate[-1;1#'a],'1_'a:" "vs x}"The quick brown fox jumped over the lazy dog."
"dhe Tuick qrown box fumped jver ohe tazy log."
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 40 bytes

39 bytes of code + 1 for -a

$F[-1]=~/./;$a=$&,s/./$a/ for@F;say"@F"

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Retina, 25 20 bytes

Byte count assumes ISO 8859-1 encoding.

Om$`^.((?=.*¶))?
$#1

Try it online!

Input and output are linefeed-separated. The test suite performs the necessary I/O conversion from space-separation.

\$\endgroup\$
  • \$\begingroup\$ It is fine to use linefeed separation. \$\endgroup\$ – Comrade SparklePony May 24 '17 at 15:40
0
\$\begingroup\$

Mathematica, 134 bytes

(w=Characters@StringSplit@#;d=Drop[w,0,1];StringRiffle[StringJoin/@Table[PrependTo[d[[i]],RotateRight[First/@w][[i]]],{i,Length@w}]])&
\$\endgroup\$
0
\$\begingroup\$

Pyth, 12 bytes

.b+hNtY.>Q1Q

Takes a list of words and returns a list of words.

Try it!

\$\endgroup\$
0
\$\begingroup\$

Java (OpenJDK 8), 97 bytes

for(int n=s.length,i=0,j=n-1;i<n;j%=n)System.out.print(s[j++].charAt(0)+s[i++].substring(1)+" ");

Try it online!

\$\endgroup\$
  • \$\begingroup\$ This is a snippet, not a function. Also, you should take the entire String as one argument, and also keep commas and question/examination marks in the output as is. \$\endgroup\$ – Kevin Cruijssen Jul 3 '17 at 11:57
0
\$\begingroup\$

C, 106 77 bytes

i,a,b;f(char*o){a=*o;for(i=0;o[i++];)if(o[i]==32){b=o[++i];o[i]=a;a=b;}*o=a;}

-29 bytes from scottinet

Modifies the string in-place.

Ungolfed:

char *f(char *o){
    char a=*o,b; // start with a as the first character of the first word
    for(int i=0;++i<strlen(o);){
        // iterate through the string with i as the index
        if(o[i]==32){ // if the current character is a space, 
                      // i.e. if a word begins after this character
            b=o[++i]; // store the beginning of the next word in b
            o[i]=a; // set the beginning of the next word to a
            a=b; // set a to what the beginning of the next work used to be
        }
    }
    *o=a; 
    // set the beginning of the first word to the old beginning of the last word
}
\$\endgroup\$
  • \$\begingroup\$ Golfier version proposal (exact same code): -29 bytes \$\endgroup\$ – scottinet Sep 5 '17 at 9:50
  • \$\begingroup\$ 74 bytes \$\endgroup\$ – ceilingcat Nov 2 at 8:49
0
\$\begingroup\$

J, 34 bytes

;@(,.~_1|.])~/@|:@(split;.2)@,&' '

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Husk, 11 bytes

Foz:ṙ_1TmΓ,

Input and output as a list of strings, try it online!

(The header just transforms the input to a list of words and joins the output list with spaces.)

Explanation

F(z:ṙ_1)TmΓ,  -- example input: ["Good" "afternoon,","World!"]
         m    -- map the following (example on "Good")
          Γ   -- | pattern match head & tail: 'G' "ood"
           ,  -- | construct tuple: ('G',"ood")
              -- : [('G',"ood"),('a',"fternoon,"),('W',"orld!")]
        T     -- unzip: ("GaW",["ood","fternoon,","orld!"])
F(     )      -- apply the function to the pair
    ṙ_1       -- | rotate first argument by 1 (to right): "WGa"
  z:          -- | zip the two by (example with 'W' and "ood")
              -- | | cons/(re)construct string: "Wood"
              -- :-: ["Wood","Gfternoon,","aorld!"]

Alternative, 11 bytes

§oz:ṙ_1m←mt

Try it online!

\$\endgroup\$
0
\$\begingroup\$

AWK, 63 bytes

{for(R=substr($NF,1,1);++j<=NF;R=r)sub(r=substr($j,1,1),R,$j)}1

Try it online!

It seems like there should be a way to reduce the redundancy, but I'm not seeing it.

Note: the TIO link has 4 extra bytes to allow for multiline input.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.