• A string (the wave-snippet) with a length >= 2.
  • A positive integer n >= 1.


We output a single-line wave. We do this by repeating the input string n times.

Challenge rules:

  • If the first and last character of the input string matches, we only output it once in the total output (i.e. ^_^ of length 2 becomes ^_^_^ and not ^_^^_^).
  • The input string won't contain any whitespaces/tabs/new-lines/etc.
  • If your language doesn't support non-ASCII characters, then that's fine. As long as it still complies to the challenge with ASCII-only wave-input.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, please add an explanation if necessary.

Test cases:

_.~"(              length 12

'°º¤o,¸¸,o¤º°'     length 3

-__                length 1

-__                length 8

-__-               length 8

¯`·.¸¸.·´¯         length 24

**                 length 6

String & length of your own choice (be creative!)
  • It would be nice to add snippet with results into the question :) – Qwertiy Oct 8 '16 at 8:41
  • 2
    "A positive integer n >= 1" seems kinda pleonastic to me... :) – paolo Oct 9 '16 at 19:41

29 Answers 29

up vote 8 down vote accepted

Pyke, 15 14 10 bytes


Try it here!

  QhQeq    -    input_1[0] == input_1[-1]
 Q     >   -   input_1[^:]
        *  -  ^ * V
t          -   input_2 - 1
         + - input_1 + ^
  • +1 for an explanation that looks like a wave itself! – wastl Jun 24 at 9:52

Python 3, 32 bytes

lambda s,n:s+s[s[0]==s[-1]:]*~-n

Concatenates n copies of the string, removing the first character from all copies but the first if the first character matches the last one.

  • This doesn't properly handle the question's "¯`·.¸¸.·´¯" string, does it? When I try it, s[0] and s[-1] seem to refer to the first and last byte, rather than the first and last character. Edit: ah, wait, that's Python 2 vs. Python 3. It works correctly in Python 3. – hvd Oct 9 '16 at 12:40

05AB1E, 13 bytes

Uses CP-1252 encoding.


Try it online!


-___- and 3 used as input for example.

D              # duplicate input string
               # STACK: "-___-", "-___-"
 ¬U¤X          # push copies of the first and last element of the string
               # STACK: "-___-", "-___-", "-", "-"
     Q         # compare for equality 
               # STACK: "-___-", "-___-", 1
      i¦}      # if true, remove the first char of the copy of the input string
               # STACK: "-___-", "___-" 
         I<    # push input number and decrease by 1
               # STACK: "-___-", "___-", 2
           ×   # repeat the top string this many times
               # STACK: "-___-", "___-___-"
            J  # join with input string
               # STACK: "-___-___-___-"
               # implicitly output

JavaScript (ES6), 47 bytes

<div oninput=o.textContent=n.value&&f(s.value,n.value)><input id=s><input id=n type=number min=1><div id=o>

  • 1
    Congrats on 20k! – Adnan Oct 7 '16 at 11:44
  • 2
    @Adnan Thanks! 20002 too, which is nice and symmetrical. – Neil Oct 7 '16 at 11:58
  • 1
    Is currying possible in this instance? I mean doing s=>n=>... instead of (s,n)=> – Zwei Oct 7 '16 at 21:39

Perl, 29 bytes

28 bytes code + 1 for -p.

Thanks to @Dada for helping me shave off a few bytes!



perl -pe 's/^((.).*?)(\2?)$/$1x<>.$3/e' <<< "'°º¤o,¸¸,o¤º°'
perl -pe 's/^((.).*?)(\2?)$/$1x<>.$3/e' <<< '**

Online example.

  • 2
    Nice. You could save (indirectly) 3 bytes by using <> instead of $' as it allows you to get rid of -0. And then you can use s///e instead of //;$_= to win one more byte :-) – Dada Oct 7 '16 at 11:18
  • @Dada nice... I completely screwed up my original attempt and oversimplified it and ended up making it much larger... I've taken your comments on board but I seem to need a $ to match the end, still saves me bytes as not using ' means I can drop it having to be save to a file to save adding 3 for -p and drop it back to 1! – Dom Hastings Oct 7 '16 at 12:28
  • 1
    Huhu. Yes indeed it needs the $ instead of the newline you previously had. (Sorry my comment wasn't very detailed, I was in a hurry...) – Dada Oct 7 '16 at 12:37
  • I like the idea of using <> in the replace string. But if n is separated by a space instead of a newline, the character count can be reduced a bit: s/(.+?) (\d+)/$1x$2/e – squeamish ossifrage Oct 7 '16 at 16:09
  • 1
    @DomHastings Ah, my mistake. Didn't read the question properly :-) – squeamish ossifrage Oct 7 '16 at 19:01

Perl, 23 bytes

Includes +1 for -p

Give input string followed by number on separate lines on STDIN <<< "'°º¤o,¸¸,o¤º°'

#!/usr/bin/perl -p
$_ x=<>;s/(.)\K

If the first character in the word is not a regex special character this 22 bytes version works too:

#!/usr/bin/perl -p
$_ x=<>;/./;s/
  • Neat! I think you forgot the /g modifier when you pasted it though ;-) – Dada Oct 7 '16 at 20:46
  • @Dada Oops. Fixed – Ton Hospel Oct 7 '16 at 21:21

MATL, 19 17 14 bytes


This works for ASCII on the online interpreter and for both unicode and ASCII when run using MATLAB.

Try it Online!


        % Implicitly grab the input as a string
        %   STACK:  {'abcdea'}
tt      % Make two copies and push them to the stack
        %   STACK:  {'abcdea'    'abcdea'    'abcdea'}
P       % Flip the second copy around
        %   STACK:  {'abcdea'    'abcdea'    'aedcba'}
=       % Perform an element-wise comparison. Creates a boolean array
        %   STACK:  {'abcdea'    [1 0 0 0 1]}
l)      % Get the first element. If the first and last char are the same this will be
        % TRUE (1), otherwise FALSE (0)
        %   STACK:  {'abcdea'    1 }
:       % Create an array from [1...previous result]. If the first char was repeated,
        % this results in the scalar 1, otherwise it results in an empty array: []
        %   STACK: {'abcdea'    1 } 
&)      % Break the string into pieces using this index. If there were repeated
        % characters, this pops off the first char, otherwise it pops off
        % an empty string
        %   STACK: {'a'    'bcdea'}
li      % Push the number 1 and explicitly grab the second input argument
        %   STACK: {'a'    'bcdea'    1    3}
X"      % Repeat the second string this many times
        %   STACK: {'a'    'bcdeabcdeabcdea'}
h       % Horizontally concatenate the first char (in case of repeat) 
        % or empty string (if no repeat) with the repeated string
        %   STACK: {'abcdeabcdeabcdea'}
        % Implicitly display the result

Retina, 29 bytes

Lines 2 and 5 have a trailing space.


(.) +\1?

Try it online! (The first line enables a linefeed-separated test suite.)

Batch, 117 bytes

@set t=%s%
@if %s:~0,1%==%s:~1% set t=%s:~1%
@for /l %%i in (2,1,%1)do @call set s=%%s%%%%t%%
@echo %s%

Takes the number of repetitions as a command-line parameter and reads the string from STDIN.

Pyth, 13 bytes


Test suite!

Explanation to follow.

Gema, 41 characters

* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}

Sample run:

bash-4.3$ gema '* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}' <<< '_.~"( 12'

bash-4.3$ gema '* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}' <<< "'°º¤o,¸¸,o¤º°' 3"

bash-4.3$ gema '* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}' <<< '** 6'

PowerShell v2+, 48 bytes


Outputs the whole string once, followed by n-1 copies of the string or substring, depending on if the first and last characters match.

The .Substring() method outputs from the index supplied to the end of the string, so if $s[0]-eq$s[-1] evaluates to false (0), we get the whole string. If that statement is true (1), We get the substring starting at the second character.

  • Dangit, ya beat me by a few minutes. I had the same answer (using $a and $b instead of $s and $n). – AdmBorkBork Oct 7 '16 at 13:34

VBA 119 bytes

New to this game and vba wins with the highest bytes :P

PS: can't believe vba stands close to JAVA HAHA

Function l(s,x)
l=s: s=IIf(Left(s,1)=Right(s,1),Mid(s,2,Len(s)),s)
z: x=x-1: If x>0 Then l=l & s: GoTo z:
End Function


|                            code                            |                                     function                                      |
| l=s                                                        | input string s is saved to base                                                   |
| s = IIf(Left(s, 1) = Right(s, 1), Right(s, Len(s) - 1), s) | checks whether 1 and last char is equal,                                          |
|                                                            | if yes removes the first char from s and that s will be used to for further joins |
| z:                                                         | z: is a label                                                                     |
| x = x - 1:                                                 | decreases looping round                                                           |
| If x > 0 Then l = l & s: GoTo z:                           | join strings until no more rounds to do                                           |
  • 3
    Welcome to PPCG! As a QBasic programmer myself, I would say that you can remove most of the spaces and still have valid VBA code, since you can type or paste the shortened code (with the autoformatter adding the spaces), hit run, and it works. That would improve your score considerably. :) – DLosc Oct 7 '16 at 19:13

CJam, 16 15 bytes


Try it online


l]li*            Create a list of n-times the input string.
{(s@)@|@}*       Fold this list by taking out the last character of the first 
                 argument and the first character of the second argument and 
                 replacing them by their unique set union.
                 e.g.: "aba" "aba" -> "ab" 'a"a"| "ba" -> "ab" "a" "ba"
                       "abc" "abc" -> "ab" 'c"a"| "bc" -> "ab" "ca" "bc

K, 12 Bytes


/in action

/explanation (read function from right to left)
x is the string and y is the number of repetitions
(,)y    --enlist x so it becomes 1 value (rather than a list)
y#x     --take y many items of x
,/      --coalesce the list ,/[("-_";"-_")] --> "-_-_"


  • This breaks Rule 1. {,/y#,$[(*x)~*|x;-1;0]_x} for 25 bytes handles first/last matching. If you're happy breaking Rule 1, then you can have {,/y#,x} for 8. – streetster Dec 12 '17 at 12:15

PHP, 72 Bytes


with PHP 7.1 it could be reduce to 65 Bytes


Pip, 18 bytes

Regex solution, taking advantage of the "no spaces in input" rule. Takes the string from stdin and the number as a command-line argument.

(q.s)XaR`(.) \1?`B

Try it online!


 q.s                Read from stdin and append a space
(   )Xa             String-multiply by first cmdline arg
       R            Replace
        `(.) \1?`     Regex: char followed by space followed by (optional) same char again
                 B    Callback function, short for {b}: return 1st capturing group

Thus, a b turns into ab, a a turns into a, and the space at the end of the string is removed. Then the result is autoprinted.

Haskell, 59 bytes

a%b=concat$replicate a b
a@(s:z)#n|s/=last z=n%a|1<2=s:n%z

Ungolfed version:

-- Helper: Appends str to itself n times
n % str = concat (replicate n str)

-- Wave creating function
(x:xs) # n
 -- If start and end of wave differ, 
 | x /= last xs = n%(x:xs)
 | otherwise   = x:(n%xs)

Java 10, 123 111 109 107 102 100 79 bytes

s->n->{var r=s;for(;n-->1;r+=s.matches("(.).*\\1")?s.substring(1):s);return r;}

Try it online.

Alternative with same byte-count (79 bytes):

(s,n)->{for(var t=s.matches("(.).*\\1")?s.substring(1):s;n-->1;s+=t);return s;}

Try it online.

I'll of course try to answer my own question. ;)
-5 bytes thanks to @dpa97.
-21 bytes converting from Java 7 to 10.


s->n->{                // Method with String and integer parameters and String return-type
  var r=s;             //  Result-String, starting at the input-String
  for(;n-->1;          //  Loop `n-1` times
                       //   If the first and last characters are the same:
        s.substring(1) //    Append the result-String with the input-String, 
                       //    excluding the first character
       :               //   Else:
        s);            //    Append the result-String with the input-String
  return r;}           //  Return the result-String
  • 1
    s.split("^.")[1] instead of s.replaceAll("^.", "") should work, save a couple bytes – dpa97 Oct 7 '16 at 19:22
  • @dpa97 Thanks! I've edited it. I always forget about utilizing .split. – Kevin Cruijssen Oct 7 '16 at 19:53
  • @dpa97 I think I've (or we've) been overthinking it.. s.substring(1) is two bytes shorter. ;) – Kevin Cruijssen Oct 8 '16 at 8:20
  • @KevinCurijssen yeah should have seen that, good find. I think I was stuck on the idea of using regex... – dpa97 Oct 10 '16 at 13:30

Javascript ES6, 49 chars



`).map(s=>s.split` `).every(([s,n,k])=>f(s,n)==k))
<pre>_.~"( 12 _.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(
'°º¤o,¸¸,o¤º°' 3 '°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'
-__ 1 -__
-__ 8 -__-__-__-__-__-__-__-__
-__- 8 -__-__-__-__-__-__-__-__-
¯`·.¸¸.·´¯ 24 ¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯
** 6 *******</pre>

QBIC, 65 bytes


I guess I should add LEFT$ and RIGHT$ to QBIC...


;          make the first cmd line parameter into A$
:          make the second cmd line parameter into a (num)
~left..]   Drop the last char if equal to the first char
[1,a...]   FOR the given number of repetitions, concat A$ to B$ (starts out empty)
?B         print B$

C#, 79 bytes

(s,n)=>s+new string('x',n-1).Replace("x",s[0]==s[s.Length-1]?s.Substring(1):s);

A bit of an absurd method of repeating a string. Create a new string of the desired repeat length and then replace each character with the string to repeat. Other than that, looks like pretty much the same strategy as many others.

/*Func<string, int, string> Lambda =*/ (s, n) =>
    s                                      // Start with s to include first char at start
    + new string('x', n - 1).Replace("x",  // Concatenate n-1 strings of...
        s[0] == s[s.Length - 1]            // if first/last char are the same
            ? s.Substring(1)               // then skip the first char for each concat
            : s                            // else concat whole string each time
  • 1
    Hmm, what happens if the input string contains a x? Perhaps it would be better to change that into a space, since "The input string won't contain any whitespaces/tabs/new-lines/etc.". – Kevin Cruijssen Oct 8 '16 at 8:17
  • 1
    It'll work fine if the input has x. It creates the xx...x string first and then replaces each x without re-evaluating the string from the start with what needs to be replaced. – milk Oct 10 '16 at 17:45

SpecBAS - 68 bytes

1 INPUT a$,n: l=LEN a$: ?IIF$(a$(1)<>a$(l),a$*n,a$( TO l-1)*n+a$(l))

Uses inline-IF to check if first and last characters are the same. If not, print string n number of times. Otherwise, splice the string to length-1, repeat that and put last character at end.

Can only accept ASCII characters (or characters built into SpecBAS IDE)

enter image description here

APL, 19 bytes



      '^_^' {⍺,∊1↓⍵⍴⊂⍺↓⍨⊃⍺=⊃⌽⍺} 5


  • ⊃⍺=⊃⌽⍺: see if the first character matches the last character
  • ⍺↓⍨: if this is the case, drop the first character
  • : enclose the result
  • ⍵⍴: replicate it times
  • 1↓: drop the first one (this is shorter than (⍵-1)⍴)
  • : get all the simple elements (undo the boxing)
  • ⍺,: add one instance of the whole string to the front

Postscript, 98 bytes

exch/s exch def/l s length 1 sub def s 0 get s l get eq{/s s 0 l getinterval def}if{s print}repeat

...but you might need a ' flush' tacked onto that to get your PS interpreter to flush the comm buffer, another six bytes :(

Common Lisp (LispWorks), 176 bytes

(defun f(s pos)(if(equal(elt s 0)(elt s #1=(1-(length s))))(let((s1(subseq s 0 1))(s2(subseq s 0 #1#)))(dotimes(j pos)(format t s2))(format t s1))(dotimes(j pos)(format t s))))


    CL-USER 130 > (f "_.~~\"(" 12)

    CL-USER 131 > (f "'°o¤o,??,o¤o°'" 3)

    CL-USER 132 > (f "-__" 1)

    CL-USER 133 > (f "-__" 8)

    CL-USER 134 > (f "ˉ`·.??.·′ˉ" 24)

    CL-USER 135 > (f "**" 6)


~~ =>   ~

\" =>   " 


    (defun f (s pos)
      (if (equal (elt s 0) (elt s (1- (length s))))
          (let ((s1 (subseq s 0 1)) (s2 (subseq s 0 (1- (length s)))))
            (dotimes (j pos)
              (format t s2))
            (format t s1))        
        (dotimes (i pos)
          (format t s))))

Vim, 17 bytes

The easy way to do this is to use a back-reference regex that can tell if the first and last chars match. But long regexes are long. We don't want that.


The wave to repeat is in the buffer. I'm assuming the number to be repeated is in the register "a (type qaNq with N as the number to set it up). The idea is:

  • If the first and last bytes match, delete everything up to the last character.
  • If the first and last bytes don't match, delete all the characters.

Then P the deleted text @a times.

  • lDg*: This maneuver creates a regex that matches any first character, regardless of whether it needs to be escaped or not, or whether it's a word or not. (* would be enough to make the properly escaped regex, but would add unwanted \<\> garbage if it was a word character, like _.)
  • p^: Last step was messy. Clean up to the original position, beginning of the line.
  • v$: In visual mode, $ by default moves to after the end of the line.
  • ?<C-P>$<CR>hd: If the previous regex exists at the end of the line, this search will move to it; otherwise, stay beyond the end of the line. Move left from there and we accomplish the (tedious) delete we need.
  • @aP: Run the number repeat as a macro to be used as an argument to P.

Ruby, 38 bytes


I think this is pretty self-explanatory. I'm still wondering if there's a more concise way to represent the s[0..-2] block, but I haven't found it yet.

Java (117 bytes)

String w(String a,int b){String c=a;for(;b>0;b--)c+=b+a.substring(a.charAt(a.length()-1)==a.charAt(0)?1:0);return c;}
  • 1
    Hi, welcome to PPCG! Hmm, I've posted already a shorter Java 7 answer here. Yours uses an approach similar to the one I had previously. By using this same approach, you could golf b>0;b-- to b-->0;. Also, why is the b+ there at c+=b+a.substring? Still, it's a great first answer if you came up with it independently. Enjoy your stay here on PPCG! :) Also, you might find Tips for golfing in Java interesting to read. – Kevin Cruijssen Oct 7 '16 at 12:20

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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