28
\$\begingroup\$

Input:

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

Output:

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
'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'

-__                length 1
-__

-__                length 8
-__-__-__-__-__-__-__-__

-__-               length 8
-__-__-__-__-__-__-__-__-

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

**                 length 6
*******

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

29 Answers 29

23
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – hvd
    Oct 9, 2016 at 12:40
14
\$\begingroup\$

05AB1E, 13 bytes

Uses CP-1252 encoding.

D¬U¤XQi¦}I<×J

Try it online!

Explanation

-___- 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
\$\endgroup\$
11
\$\begingroup\$

JavaScript (ES6), 47 bytes

f=
(s,n)=>s+s.slice(s[0]==s.slice(-1)).repeat(n-1)
;
<div oninput=o.textContent=n.value&&f(s.value,n.value)><input id=s><input id=n type=number min=1><div id=o>

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

Perl, 29 bytes

28 bytes code + 1 for -p.

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

s/^((.).*?)(\2?)$/$1x<>.$3/e

Usage

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

Online example.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ 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 :-) \$\endgroup\$
    – Dada
    Oct 7, 2016 at 11:18
  • \$\begingroup\$ @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! \$\endgroup\$ Oct 7, 2016 at 12:28
  • 1
    \$\begingroup\$ 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...) \$\endgroup\$
    – Dada
    Oct 7, 2016 at 12:37
  • \$\begingroup\$ 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 \$\endgroup\$
    – r3mainer
    Oct 7, 2016 at 16:09
  • 1
    \$\begingroup\$ @DomHastings Ah, my mistake. Didn't read the question properly :-) \$\endgroup\$
    – r3mainer
    Oct 7, 2016 at 19:01
7
\$\begingroup\$

Pyke, 15 14 10 bytes

tQQhQeq>*+

Try it here!

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

Perl, 23 bytes

Includes +1 for -p

Give input string followed by number on separate lines on STDIN

wave.pl <<< "'°º¤o,¸¸,o¤º°'
3"

wave.pl:

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

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/
$&?//g
\$\endgroup\$
2
  • \$\begingroup\$ Neat! I think you forgot the /g modifier when you pasted it though ;-) \$\endgroup\$
    – Dada
    Oct 7, 2016 at 20:46
  • \$\begingroup\$ @Dada Oops. Fixed \$\endgroup\$
    – Ton Hospel
    Oct 7, 2016 at 21:21
4
\$\begingroup\$

Retina, 29 bytes

Lines 2 and 5 have a trailing space.

 .+
$* 
 $


 $`
(.) +\1?
$1

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

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

Batch, 117 bytes

@set/ps=
@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.

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

MATL, 19 17 14 bytes

ttP=l):&)liX"h

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

Try it Online!

Explanation

        % 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
\$\endgroup\$
3
\$\begingroup\$

Pyth, 13 bytes

+z*@tBzqhzezt

Test suite!

Explanation to follow.

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

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"
'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'

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

PowerShell v2+, 48 bytes

Param($s,$n)$s+$s.Substring($s[0]-eq$s[-1])*--$n

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.

\$\endgroup\$
1
  • \$\begingroup\$ Dangit, ya beat me by a few minutes. I had the same answer (using $a and $b instead of $s and $n). \$\endgroup\$ Oct 7, 2016 at 13:34
3
\$\begingroup\$

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

Explanation:

+------------------------------------------------------------+-----------------------------------------------------------------------------------+
|                            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                                           |
+------------------------------------------------------------+-----------------------------------------------------------------------------------+
\$\endgroup\$
1
  • 3
    \$\begingroup\$ 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. :) \$\endgroup\$
    – DLosc
    Oct 7, 2016 at 19:13
3
\$\begingroup\$

K, 12 Bytes

{,/[y#(,)x]}


/in action
{,/[y#(,)x]}["lollol";4]
"lollollollollollollollol"
{,/[y#(,)x]}["-_";10]
"-_-_-_-_-_-_-_-_-_-_"

/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 ,/[("-_";"-_")] --> "-_-_"

Thanks

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – mkst
    Dec 12, 2017 at 12:15
2
\$\begingroup\$

PHP, 72 Bytes

<?=($a=$argv[1]).str_repeat(substr($a,$a[0]==substr($a,-1)),$argv[2]-1);

with PHP 7.1 it could be reduce to 65 Bytes

<?=($a=$argv[1]).str_repeat(substr($a,$a[0]==$a[-1]),$argv[2]-1);
\$\endgroup\$
2
\$\begingroup\$

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!

Explanation:

 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.

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

CJam, 16 15 bytes

l]li*{(s@)@|@}*

Try it online

Explanation:

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
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I like your wave-input. :) \$\endgroup\$ Oct 7, 2016 at 17:49
2
\$\begingroup\$

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)
\$\endgroup\$
2
\$\begingroup\$

Java 11, 123 111 109 107 102 100 79 58 bytes

s->n->s+s.substring(s.matches("(.).*\\1")?1:0).repeat(n-1)

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.
-21 bytes converting from Java 10 to 11.

Explanation:

s->n->             // Method with String & integer parameters and String return-type
  s                //  Return the input-String as result
   +               //  Appended with:
    s.subtring(    //   A substring of the input-String:
      s.matches("(.).*\\1")?
                   //    If the first and last characters are the same:
       1           //     Remove the first character in the substring-call
      :            //    Else:
       0)          //     Use the input-String as is
     .repeat(n-1)  //   Repeated the input-integer minus 1 amount of times
\$\endgroup\$
4
  • 1
    \$\begingroup\$ s.split("^.")[1] instead of s.replaceAll("^.", "") should work, save a couple bytes \$\endgroup\$
    – dpa97
    Oct 7, 2016 at 19:22
  • \$\begingroup\$ @dpa97 Thanks! I've edited it. I always forget about utilizing .split. \$\endgroup\$ Oct 7, 2016 at 19:53
  • \$\begingroup\$ @dpa97 I think I've (or we've) been overthinking it.. s.substring(1) is two bytes shorter. ;) \$\endgroup\$ Oct 8, 2016 at 8:20
  • \$\begingroup\$ @KevinCurijssen yeah should have seen that, good find. I think I was stuck on the idea of using regex... \$\endgroup\$
    – dpa97
    Oct 10, 2016 at 13:30
1
\$\begingroup\$

Javascript ES6, 49 chars

(s,n)=>s.replace(/(.).*?(?=\1?$)/,m=>m.repeat(n))

Test:

f=(s,n)=>s.replace(/(.).*?(?=\1?$)/,m=>m.repeat(n))
console.log(document.querySelector("pre").textContent.split(`
`).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>

\$\endgroup\$
1
\$\begingroup\$

QBIC, 65 bytes

;:~left$$|(A,1)=right$$|(A,1)|A=left$$|(A,len(A)-1)][1,a|B=B+A]?B

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

Explanation:

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

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
    )
;
\$\endgroup\$
2
  • 1
    \$\begingroup\$ 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.". \$\endgroup\$ Oct 8, 2016 at 8:17
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – milk
    Oct 10, 2016 at 17:45
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

APL, 19 bytes

{⍺,∊1↓⍵⍴⊂⍺↓⍨⊃⍺=⊃⌽⍺}

Usage:

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

Explanation:

  • ⊃⍺=⊃⌽⍺: 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
\$\endgroup\$
1
\$\begingroup\$

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 :(

\$\endgroup\$
1
\$\begingroup\$

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))))

Usage:

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

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

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

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

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

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

Explanation:

~~ =>   ~

\" =>   " 

Ungolf:

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

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.

lDg*p^v$?<C-P>$<CR>hd@aP

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

Ruby, 38 bytes

->s,n{s[0]==s[-1]?s[0..-2]*n+s[0]:s*n}

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.

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

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;}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Oct 7, 2016 at 12:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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