29
\$\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\$
9
  • \$\begingroup\$ Is a trailing space allowed in the output? \$\endgroup\$ May 24, 2017 at 15:01
  • \$\begingroup\$ Can we assume there will be at most one space between words? \$\endgroup\$ May 24, 2017 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\$
    – user69654
    May 24, 2017 at 15:27
  • \$\begingroup\$ @BusinessCat Yes. \$\endgroup\$
    – sporklpony
    May 24, 2017 at 15:37
  • \$\begingroup\$ @mathjunkie Yes. \$\endgroup\$
    – sporklpony
    May 24, 2017 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\$
1
  • \$\begingroup\$ You can take input and output as a list, you know. \$\endgroup\$
    – sporklpony
    May 24, 2017 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\$
4
  • \$\begingroup\$ I think you can take input as a list as well, saving a further byte on the ¸ \$\endgroup\$ May 24, 2017 at 15:40
  • \$\begingroup\$ That might be a stretch, @ETHproductions, but I'll ask. EDIT: Confirmed here \$\endgroup\$
    – Shaggy
    May 24, 2017 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\$ May 24, 2017 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, 2017 at 16:54
6
\$\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\$
2
  • \$\begingroup\$ You could replace both .collect and .each with .map. \$\endgroup\$
    – manatwork
    May 24, 2017 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, 2017 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\$
0
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\$
3
  • \$\begingroup\$ You can take input and output as a list, you know. \$\endgroup\$
    – sporklpony
    May 24, 2017 at 15:39
  • \$\begingroup\$ @ComradeSparklePony You confirmed that after I answered :P Golfing it now \$\endgroup\$ May 24, 2017 at 15:44
  • \$\begingroup\$ )o for 1m>. \$\endgroup\$
    – jimmy23013
    May 25, 2017 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\$
2
  • \$\begingroup\$ Could you remove join? Question states that you can output a list. It would save 8 bytes \$\endgroup\$
    – Craig Ayre
    May 25, 2017 at 15:28
  • 1
    \$\begingroup\$ @CraigAyre, sweet, thanks! \$\endgroup\$ May 25, 2017 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\$
6
  • \$\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, 2017 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, 2017 at 16:39
  • \$\begingroup\$ I didn't know dd and gg both had shorter versions! Awesome :) \$\endgroup\$
    – Wossname
    May 26, 2017 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, 2017 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, 2017 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\$
0
3
\$\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\$
1
  • \$\begingroup\$ clever input idea \$\endgroup\$
    – Jonah
    Oct 30, 2017 at 0:21
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\$
2
  • \$\begingroup\$ @Rod Good suggestion, thank you! \$\endgroup\$ May 24, 2017 at 15:39
  • 4
    \$\begingroup\$ S[:-1] can be shortened to S; zipping lists of different lengths automatically truncates whichever is longer \$\endgroup\$ May 24, 2017 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\$
2
  • 1
    \$\begingroup\$ Functions can be unnamed, so you can omit the f=. \$\endgroup\$
    – nimi
    May 24, 2017 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
    May 24, 2017 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
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\$
4
  • 1
    \$\begingroup\$ You need to include the import statement in the byte count. Cool answer! \$\endgroup\$
    – sporklpony
    May 25, 2017 at 0:12
  • \$\begingroup\$ also, you need to have your input and output code in the byte count \$\endgroup\$ May 25, 2017 at 11:24
  • 1
    \$\begingroup\$ I think you can drop the final newline for 1 byte. \$\endgroup\$ Jun 4, 2017 at 1:02
  • \$\begingroup\$ @ØrjanJohansen yes, also "b" instead of "u1" works, so -2 bytes. \$\endgroup\$
    – Mikhail V
    Jun 4, 2017 at 1:13
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\$

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\$
1
\$\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\$
1
\$\begingroup\$

Retina, 46 37 31 bytes

Several bytes saved thanks to @Neil and @PunPun1000

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

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Can you not drop the (.*) and $3? \$\endgroup\$
    – Neil
    May 24, 2017 at 19:07
  • \$\begingroup\$ @Neil yeah, thanks \$\endgroup\$ May 28, 2017 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, 2017 at 16:29
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\$
1
  • \$\begingroup\$ It is fine to use linefeed separation. \$\endgroup\$
    – sporklpony
    May 24, 2017 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\$
1
  • \$\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\$ Jul 3, 2017 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\$
2
  • \$\begingroup\$ Golfier version proposal (exact same code): -29 bytes \$\endgroup\$
    – scottinet
    Sep 5, 2017 at 9:50
  • \$\begingroup\$ 74 bytes \$\endgroup\$
    – ceilingcat
    Nov 2, 2019 at 8:49
0
\$\begingroup\$

J, 34 bytes

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

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.