53
\$\begingroup\$

Make a program that takes the word you input, and adds that word to the back of itself minus its first letter, then repeats until all letters are gone. For example, cat would become catatt, and hello would become helloellolloloo.

Input
Any of the 26 letters of the English alphabet. There may be multiple words separated by spaces, and the change should be applied to every word.

Output
The word(s) inputted, with each word put after itself with its first letter missing, and then with its second letter missing, and so on until there are no more letters to add.

More examples:

ill eel outputs illlll eelell

laser bat outputs laserasersererr batatt

darth vader outputs dartharthrththh vaderaderdererr

This is code golf, so the shortest code wins.

Clarification:
You can treat the input or output as a list. You can separate words using newline instead of space. You can add a trailing space to the input.

\$\endgroup\$
17
  • 25
    \$\begingroup\$ honestly, the multiple words thing is kinda annoying. All it does is require a split, apply the function on each word, and then join again. It's also quite debilitating for lots of esolangs which have to check for a space manually \$\endgroup\$
    – Jo King
    Commented Sep 18, 2018 at 22:44
  • 6
    \$\begingroup\$ Can we take in input as a list of words and output as such? \$\endgroup\$
    – Quintec
    Commented Sep 18, 2018 at 23:53
  • 5
    \$\begingroup\$ What length words do you need to handle? \$\endgroup\$
    – MickyT
    Commented Sep 19, 2018 at 1:14
  • 6
    \$\begingroup\$ Is it OK for words to be separated by a newline in the output(instead of a space)? \$\endgroup\$
    – JayCe
    Commented Sep 19, 2018 at 1:37
  • 11
    \$\begingroup\$ 1. Please update the spec with the new allowances (array I/O, trailing space, etc.) 2. Please inform the existing solutions in case any can save bytes by taking advantage of them. \$\endgroup\$
    – Shaggy
    Commented Sep 19, 2018 at 8:36

75 Answers 75

38
\$\begingroup\$

brainfuck, 60 56 bytes

,[>++++++++[-<----<++++>>]<[>>]<[[<]>.[[-]>[.>]<[<]>]],]

Try it online!

Requires a trailing space and prints a leading space. Both of these could be circumvented, but that ends up at 112 bytes.

Explanation

,[  Loop over each byte of input
  Tape: 32 w o r-32 d'
  >++++++++[-<----<++++>>]   Subtract 32 from the character and add 32 to the previous char
  Tape: 32 w o r d-32 0'
  <[>>]<   If the last character was a space
  Tape: 32 w o r d-32 0'
  or
  Tape: 32 w o r d' space-32
  [
    [<]>.   Move to the end of the word and print out the space
    [   Loop over each letter
      [-]    Remove the first letter (initially space)
      >[.>]  Print the rest of the word
      <[<]>  Move back to the first letter
    ]
    Tape: clear
  ]
,]  Get the next byte of input
\$\endgroup\$
32
\$\begingroup\$

Japt -m, 6 3 bytes

Input and output are arrays of words.

£sY

Try it


Explanation

        :For each word in the input array
£       :Map each letter at index Y
 sY     :  Slice the current word from index Y
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Thats really compact. Nice! \$\endgroup\$
    – qazwsx
    Commented Sep 18, 2018 at 23:37
  • 9
    \$\begingroup\$ @qazwsx: Now 50% more compact! \$\endgroup\$
    – Shaggy
    Commented Sep 19, 2018 at 10:38
  • 1
    \$\begingroup\$ Isn't £ two bytes in UTF-8? \$\endgroup\$
    – Vi.
    Commented Sep 20, 2018 at 16:12
  • 9
    \$\begingroup\$ @Vi, I'm not using UTF-8 here. \$\endgroup\$
    – Shaggy
    Commented Sep 20, 2018 at 16:16
20
\$\begingroup\$

Haskell, 36 21 bytes

map$concat.scanr(:)""

Try it online!

Edit: -15 bytes, because of new IO format (list of words instead of space separated words)

\$\endgroup\$
2
  • \$\begingroup\$ You could shave off 5 characters by replacing scanr (:) "" with tails. \$\endgroup\$ Commented Sep 20, 2018 at 11:56
  • 1
    \$\begingroup\$ @FrerichRaabe: yes, but that would require an import Data.List which adds 17 bytes to the score. \$\endgroup\$
    – nimi
    Commented Sep 20, 2018 at 16:37
19
\$\begingroup\$

Python 3, 49 bytes

d=lambda s:' '.join(n+d(n[1:])for n in s.split())

Try It Online!

This takes advantage of the fact that "".split() returns an empty array so that acts as the check for the base case in the recursion.

\$\endgroup\$
19
\$\begingroup\$

Perl -p, 36 25 23 bytes

s!\b|\S!$'=~s/ .*//r!eg

Try it online!

This is a single regsub. First, it matches all word boundaries or non-space characters:

[][H][e][l][l][o] [][W][o][r][l][d]

Note that each of these matches should be replaced with the rest of the word:

[→Hello][H→ello][e→llo][l→lo][l→o][o→] (...)

We can accomplish this with the special variable $', which stores the part of the string after the match. However, we need to apply the nested regsub s/ .*// to it, which removes everything past the first space in $', in order to get rid of the remaining words in the input.

Thanks to @nwellnhof for 2 bytes.

\$\endgroup\$
1
  • \$\begingroup\$ You can replace [^ ] with \S. \$\endgroup\$
    – nwellnhof
    Commented Sep 19, 2018 at 10:21
17
\$\begingroup\$

Jelly, 3 bytes

ḊƬ€

Try it online!

Don’t need the Ks anymore since array input/output is now allowed.

ḊƬ€
  €   For each word:
Ḋ       Remove the first letter
 Ƭ      until there are none left.
\$\endgroup\$
3
  • \$\begingroup\$ I think you need ḊƬẎ) (or ḊƬF), if you prefer). \$\endgroup\$ Commented Sep 19, 2018 at 15:10
  • \$\begingroup\$ @EriktheOutgolfer I don't think so. Each word is represented by a separate array in the output \$\endgroup\$
    – dylnan
    Commented Sep 19, 2018 at 16:46
  • 2
    \$\begingroup\$ I'm not sure if you can claim that, since the arrays are nested, and nothing is specified in the question to allow it. \$\endgroup\$ Commented Sep 19, 2018 at 17:44
14
\$\begingroup\$

APL(Dyalog), 19 9 bytes

{⌽∊,\⌽⍵}¨

thanks to @H.PWiz for jogging my brain

This works because all strings in APL are character arrays.

{⌽∊,\⌽⍵}¨ 
        ¨ - for each string
      ⍵} - string argument - ex. "hello"
     ⌽ - reverse - "olleh"
   ,\ - scan magic - "o" "ol" "oll" "olle" "olleh"
  ∊ - enlist(join together) "oolollolleolleh"
{⌽ - reverse - "helloellolloloo"

TIO

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

JavaScript (ES6), 33 bytes

Saved 1 byte thanks to @ShieruAsakoto

I/O format: array of words.

a=>a.map(g=w=>w&&w+g(w.slice(1)))

Try it online!


JavaScript (ES6), 35 bytes

I/O format: array of words.

a=>a.map(w=>w.replace(/./g,"$&$'"))

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ 44: s=>s.replace(/\S+/g,g=s=>s&&s+g(s.slice(1))) \$\endgroup\$ Commented Sep 19, 2018 at 0:43
  • 1
    \$\begingroup\$ Thanks for my "something new" for today; never knew about $' (or $<backtick>). \$\endgroup\$
    – Shaggy
    Commented Sep 19, 2018 at 22:07
13
\$\begingroup\$

R, 82 75 67 bytes

write(sapply(x<-scan(,""),substring,1:(y=max(nchar(x))),y),1,y,,"")

Try it online!

Several bytes saved thanks to JayCe

Separates output with newlines.

The sapply(...) expression generates a matrix/column vector of the appropriate substrings, padding with "" as needed. write then prints the elements of the matrix, y per line, separating them with "".

\$\endgroup\$
4
  • 5
    \$\begingroup\$ Golfed a different approach while holding a sleepy baby; will add an explanation later. \$\endgroup\$
    – Giuseppe
    Commented Sep 19, 2018 at 0:30
  • 2
    \$\begingroup\$ If the length of the words are restricted, eg 99 chars or ~1e6 then you can knock of a bunch of bytes with ...substring,1:1e6,1e6)... or similar \$\endgroup\$
    – MickyT
    Commented Sep 19, 2018 at 1:30
  • 2
    \$\begingroup\$ If you can separate words by a newline: tio. I have asked this in a comment. Can work with@MickyT ‘s comment \$\endgroup\$
    – JayCe
    Commented Sep 19, 2018 at 1:39
  • \$\begingroup\$ @JayCe looks like that could be 67 bytes before incorporating MickyT's suggestion \$\endgroup\$
    – Giuseppe
    Commented Sep 19, 2018 at 13:18
8
\$\begingroup\$

brainfuck, 94 93 bytes

-[-[-<]>>+<]>-<<+[[[-]<,[->+>+<<]>[-<+>]>>[-<->>+<]<]<<[>>+<<[-]]<[<]>[[.>]<[<]>[-]>]>>>>.<<]

Try it online!

  • Saved one byte thanks to Nitrodon -- golfing .[-]>[.>]<[<]> to [.>]<[<]>[-]>.

Explanation

[[[ (dynamic) tape layout: ... NUL STR ... STR CHR FLG BUF SPC NUL ... ]]]

load a 32 into SPC
-[-[-<]>>+<]>-

while FLG
<<+[

 read a word
 [
  clear FLG; read CHR
  [-]<,
  copy CHR to BUF (using FLG as a temporary)
  [->+>+<<]>[-<+>]
  subtract SPC from BUF and save SPC
  >>[-<->>+<]
  move tape layout one to the right
  <
 ]

 strip trailing space; set FLG to true
 << [>>+<<[-]]
 to STR's first character
 <[<]>
 print word in all reduced forms
 [
  [.>]<[<]>[-]>
 ]

 print SPC; move to FLG
 >>>>.<<
]

Try it online!

Attribution

Esolang's brainfuck constant collection was used for the initial space load.

\$\endgroup\$
2
  • \$\begingroup\$ This doesn't seem to terminate. Is that intended? \$\endgroup\$
    – Jo King
    Commented Sep 18, 2018 at 23:34
  • 1
    \$\begingroup\$ @JoKing Yes. In certain implementations it would exceed the tape limit, exiting by error. \$\endgroup\$ Commented Sep 18, 2018 at 23:35
6
\$\begingroup\$

05AB1E, 5 bytes

€.síJ

Try it online!

Explanation

€.s        # push suffixes of each
   í       # reverse each
    J      # join suffixes
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Boring 5-bytes alternative: í€ηJí (since prefixes is a 1-byte builtin instead of 2-bytes like suffixes; still requires an additional reverse-each however at the start however, so the byte-count remains 5). \$\endgroup\$ Commented Sep 19, 2018 at 13:19
6
\$\begingroup\$

Husk, 6 4 bytes

-2 bytes thanks to Jonathan Allan (taking input as a list)!

moΣṫ

Try it online!

Explanation

Takes input as a list of strings and maps the following function:

Σṫ  -- example argument: "abc"
 ṫ  -- tails: ["abc","bc","c"]
Σ   -- concat: "abcbcc"
\$\endgroup\$
1
  • \$\begingroup\$ The split & join are possibly no longer required, currently such specification is in a comment. \$\endgroup\$ Commented Sep 19, 2018 at 17:23
5
\$\begingroup\$

Retina 0.8.2, 15 bytes

 
¶
.
$&$%'
¶
 

Try it online! Note: trailing spaces. Explanation:

Split on spaces.

.
$&$%'

Append its suffix to each letter. The % means that we only get the word's suffix.

Join with spaces.

\$\endgroup\$
5
\$\begingroup\$

Vim, 47 bytes (38 key strokes)

Start with your input as the sole line in a Vim buffer.

:s/<Space>/\r/g<CR>ggqaywPlxqqb99@aj0q99@bgg99J

Explanation

This puts each word on its own line, iterates over each line, then rejoins them all. Breaks if words are longer than 99 characters or if your input has more than 99 words.

  1. :s/<Space>/\r/g<CR> replaces spaces with new lines (\r)
  2. gg positions the cursor at the beginning of the first line
  3. qa begins recording macro a:
    • yw yanks the rest of the word
    • P puts it behind the cursor
    • lx removes the first letter of the latter word
    • q stops recording macro a
  4. qb begins recording macro b:
    • 99@a executes macro a ninety-nine times (introduces the character limit)
    • j0 positions the cursor at the start of the next line
    • q stops recording macro b
  5. 99@b executes macro b ninety-nine times (introduces the word limit)
  6. gg positions the cursor at the first line
  7. 99J joins the following ninety-nine lines with spaces (word limit again)

For another 2 bytes (2 key strokes) you could extend the word limit to 999. Another 4 bytes, 9999, etc.

\$\endgroup\$
5
\$\begingroup\$

Pepe, 167 153 bytes

REEerEeeEeeeeeRrEEEEerEEEEEeerEErEEeerreErEEeErreEREEEEEEEreereErEerEEEErEEeerrEEreRRErEEEEreREEreeereReeRerEEEEEErEEEeerreEerEEeerEEEEerEEeEreereErEeree

Try it online!

\$\endgroup\$
5
\$\begingroup\$

16-bit x86 assembly code, 24 bytes

     47             inc    di
     B020           mov    al,20h
l1:  3806           cmp    [si],al
     7212           jb     l5 ;less means end of string
     7401           je     l2  ;equal means space was seen
     4F             dec    di ;overwrite extra space
l2:  E80300         call   l3
     46             inc    si ;move to next character in word
     75F1           jne    l1
l3:  56             push   si
l4:  3806           cmp    [si],al
     A4             movsb      ;copy character
     77FB           ja     l4  ;until either zero or space is seen
     5E             pop    si
l5:  C3             ret

Call with si = pointer to source string, di = pointer to output buffer.
The source string requires a zero byte to end it.
The code is the same in 16- or 32- or 64-bit (si/di become either esi/edi or rsi/rdi).
32-bit code is two bytes larger because of the expanded call.
64-bit code is three bytes larger still because the inc/dec of rsi/rdi attracts a prefix (but if it is known that they are within 32-bit memory space, then they can be esi/edi again to avoid that penalty).

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

MATL, 18 16 bytes

"@gXH"HX@Jh)]0&h

Input is a cell array of words. Try it online!

Explanation

"         % Implicit input: cell array of strings. For each cell
  @g      %   Push content of current cell, that is, a word
  XH      %   Copy into clipboard H
  "       %   For each letter
    H     %     Push word
    X@    %     Push iteration index
    Jh)   %     Index from that until the end into current word
  ]       %   End
  0       %   Push 0. Will be cast to char. Char(0) is displayed as space
  &h      %   Concatenate horizontally all elements so far. Implicit display
\$\endgroup\$
4
\$\begingroup\$

K4 / K (oK), 9 bytes

Solution:

,/'(1_)\'

Try it online!

Explanation:

,/'(1_)\' / the solution
        ' / apply to each
       \  / scan
   (  )   / do this together
    1_    / drop first
,/'       / flatten (,/) each (')
\$\endgroup\$
4
\$\begingroup\$

C++ (clang), 174 bytes

#include<map>
#include<string.h>
std::string r(std::string w){while(auto x=strchr(w.c_str(),32))return r(w.substr(0,x-w.c_str()))+" "+r(x+1);return w!=""?w+r(w.substr(1)):w;}

Try it online!

It's my first submission, and i didn't know if returning string instead of printing it is okay :)

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to PPCG! Yes, returning a string is okay. Hope you stick around! \$\endgroup\$
    – Jo King
    Commented Sep 20, 2018 at 10:27
  • \$\begingroup\$ You could use the inequality operator's symmetry to remove a space and thus save a byte -- return w!=""? can be return""!=w?. \$\endgroup\$ Commented Sep 21, 2018 at 19:27
4
\$\begingroup\$

Stax, 3 bytes

m|]

Run and debug it

Explanation:

m   Map over the lines
 |] Get all suffixes (suffices?)
    Implicit flatten and output
\$\endgroup\$
1
4
\$\begingroup\$

Vyxal, 5 bytes

ƛ[Ḣx+

Try it Online!

(IMO) this is a really neat recursive solution. Port of my JS answer that came out really nicely.

ƛ     # Foreach value as n
 [    # If truthy (Not empty string)
   x  # Call this function (The function we're mapping with)
  Ḣ   # With n[1:] - remove first character
    + # Appended to the result

The "concatenation of suffixes" approach doesn't do any better:

Vyxal, 5 bytes

ƛṘ¦∑Ṙ

Try it Online!

ƛ     # Map...
 Ṙ    # Reverse
  ¦   # Cumulative sums (prefixes)
   ∑  # Concatenated
    Ṙ # Reversed
\$\endgroup\$
3
\$\begingroup\$

Charcoal, 14 bytes

⪫E⪪S ⭆ι✂ιμLι¹ 

Try it online! Note: Trailing space. Link is to verbose version of code. Explanation:

   S            Input string
  ⪪             Split on spaces
 E              Map over each word
      ι         Current word
     ⭆          Map over each character and join
        ι       Current word
         μ      Current index
           ι    Current word
          L     Length
            ¹   Literal 1
       ✂        Slice
⪫               Join with spaces
                Implicitly print
\$\endgroup\$
3
\$\begingroup\$

Pip -s, 11 bytes

J_@>,#_Mq^s

Takes the space-separated list of words from stdin. Try it online!

Explanation

             s is space (implicit)
        q    Read a line of stdin
         ^s  Split it on spaces
       M     Map this lambda function to each word:
 _            The word...
  @>          sliced starting at index...
    ,#_       range(len(word))
              This creates len(word) slices ["word" "ord" "rd" "d"]
J             Join those into a single string
             The resulting list of modified words is printed; the -s flag uses space
             as the separator
\$\endgroup\$
3
\$\begingroup\$

Python 2, 63 bytes

lambda s:' '.join(map(g,s.split()))
g=lambda s:s and s+g(s[1:])

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ It is 64 bytes on my computer, mac OS. \$\endgroup\$
    – aydinugur
    Commented Sep 21, 2018 at 23:30
3
\$\begingroup\$

Canvas, 6 bytes

±[±]⇵]

Try it here!

5 bytes with a crazy output format

\$\endgroup\$
3
\$\begingroup\$

C#, 111 90 bytes

b=>string.Join(" ",(b.Split(' ').Select(x=>string.Concat(x.Select((y, i)=>x.Substring(i))))))

Try it Online!

By Changing input and output to arrays, I saved a few bytes:

b=>b.Select(x=>string.Concat(x.Select((y,i)=>x.Substring(i)))).ToArray()

Try it Online!

\$\endgroup\$
3
\$\begingroup\$

K (oK), 17 13 bytes

{,/|:'|,\|x}'

Try it online!

Prefix anonymous function; Input is taken as a list of strings, which in turn are lists of characters.

Thanks @streetster for 4 bytes.

How:

{,/|:'|,\|x}' //Main function, argument x → ("ill";"eel")
            ' // For each element of the argument
         |x}  // Flip it. x → ("lli";"lee")
       ,\     // Concatenate each element, keeping intermediates. x → (("l";"ll";"lli");("l";"le";"lee")
      |       // Flip it again. x → (("lli";"ll";"l");("lee";"le";"l"))
   |:'        // Now flip each element. x → (("ill";"ll";"l");("eel";"el";"l"))
{,/           // Concatenation scan. x → ("illlll";"eelell")
\$\endgroup\$
3
  • \$\begingroup\$ You can return a list, also take a look at my oK solution \$\endgroup\$
    – mkst
    Commented Sep 20, 2018 at 16:33
  • \$\begingroup\$ @streetster oh, nice. I'm still in the process of learning K, so my solutions won't be as short or as elegant as I'd like. Thanks for the heads up! \$\endgroup\$
    – J. Sallé
    Commented Sep 20, 2018 at 16:35
  • \$\begingroup\$ Flatten before reverse allows you to omit the "reverse-each", bringing it down to 10 bytes: {|,/,\|x}' \$\endgroup\$ Commented Oct 19, 2018 at 2:39
3
\$\begingroup\$

Common Lisp, 179 bytes

(defun r(s)(cond((endp s)nil)((eql(first s)#\Space)(princ " ")(r(rest s)))(t(q s)(r(rest s)))))(defun q (l)(cond((eql(first l)#\Space)t)((endp l)t)(t(princ(first l))(q(rest l)))))

Try it online!

This is my first try at golfing any edits are welcome

\$\endgroup\$
9
  • \$\begingroup\$ Hello and welcome to PPCG. Removing whitespace can save you 29 bytes. \$\endgroup\$ Commented Sep 21, 2018 at 1:20
  • \$\begingroup\$ @Johnathan Frech thanks i just updated with no spaces \$\endgroup\$
    – JRowan
    Commented Sep 21, 2018 at 1:27
  • \$\begingroup\$ I think you missed four superfluous spaces. \$\endgroup\$ Commented Sep 21, 2018 at 1:28
  • \$\begingroup\$ You can most likely also use car instead of first and cdr instead of rest to further golf your submission. \$\endgroup\$ Commented Sep 21, 2018 at 1:30
  • \$\begingroup\$ Na, im good with it now haha, maybe ill come back and mess with it later. Im just learning lisp now my teacher said to never use car and cdr so they were out of my head while i was doing it \$\endgroup\$
    – JRowan
    Commented Sep 21, 2018 at 1:32
3
\$\begingroup\$

Lua, 70 bytes

for i=1,#arg do x=arg[i]for i=1,#x do io.write(x:sub(i))end print()end

Try it online!

Explanation

The arguments in Lua are stored in the table arg starting at index 1. The unary operator # returns the size of the table and function s:sub(a,b) returns a substring based on string s delimited by integers a and b, if b is not passed it will return the rest of the string.

I had to use io.write() instead of print() to avoid line breaking, and added print() at the end for the opposite reason.

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

Python 3, 79 74 bytes

-5 bytes thanks to mypetlion

print(*map(lambda x:''.join(x[n:]for n in range(len(x))),input().split()))

Try it online!

A full program that takes input from stdin and outputs to stdout.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ print(*map(lambda x:''.join(x[n:]for n in range(len(x))),input().split())) Full program to save 5 bytes. \$\endgroup\$
    – mypetlion
    Commented Sep 18, 2018 at 23:13

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.