35
\$\begingroup\$

There was a challenge up a while ago about multiplying strings. It showed us how we can multiply not only numbers, but also strings. However, we still can't multiply a number by a string properly. There has been one attempt to do so but this is obviously wrong. We need to fix that!

Your Task:

Write a function or program that multiplies two inputs, a string and an integer. To (properly) multiply an string by an integer, you split the string into characters, repeat each character a number of times equal to the integer, and then stick the characters back together. If the integer is negative, we use its absolute value in the first step, and then reverse the string. If the input is 0, output nothing (anything multiplied by 0 equals nothing).

Input:

A string that consists solely of printable ASCII characters and newlines, and an integer (possible negative).

Output:

The string multiplied by the integer.

Examples:

Hello World!, 3            --> HHHeeellllllooo   WWWooorrrlllddd!!!
foo, 12                    --> ffffffffffffoooooooooooooooooooooooo
String, -3                 --> gggnnniiirrrtttSSS
This is a fun challenge, 0 --> 
Hello
World!, 2                  --> HHeelllloo

                               WWoorrlldd!!

Scoring:

This is , lowest byte count wins!

\$\endgroup\$
5
  • 4
    \$\begingroup\$ Can we assume the string is printable ASCII-only, plus newlines? \$\endgroup\$ – mbomb007 Jul 11 '17 at 21:45
  • \$\begingroup\$ Can we output a list of strings? \$\endgroup\$ – totallyhuman Jul 11 '17 at 21:50
  • \$\begingroup\$ Partial solution in Retina. Only works for positive values of the integer. I probably won't make time to finish it if someone wants to. tio.run/##K0otycxL/P8/… \$\endgroup\$ – mbomb007 Jul 11 '17 at 21:59
  • \$\begingroup\$ @mbomb007, yes, sorry for taking so long about that. \$\endgroup\$ – Gryphon Aug 2 '17 at 0:08
  • \$\begingroup\$ @totallyhuman, no you may not. \$\endgroup\$ – Gryphon Aug 8 '17 at 3:52

49 Answers 49

1
2
1
\$\begingroup\$

Mathematica, 89 bytes

(T=Table;t=""<>T[s[[i]]~T~Abs@#2,{i,Length[s=Characters@#]}];If[#2>0,t,StringReverse@t])&

input

["Hello World!", 3]

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

Braingolf, 22 bytes

1-v{R.[v.R]v}R[v>R]v&@

Try it online!

Eeh, not bad.

Takes input as an integer and an array of characters.

Alternatively:

Braingolf, 31 bytes

l1->[M]1-v&,{R.[v.R]v}R[v>R]v&@

Try it online!

Takes input as an integer and a string

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

C, 109 bytes

char *f(int n, char *s){char *o=calloc(n,strlen(s)+1),*t=o;while(*s){for(int i=n;i--;)*t++=*s;s++;}return o;}

Starting with a function declaration that takes an int and a string and produces a string (it seems implied that memory is not preallocated and must be created) it seems that the straight-forward approach is shorter than any attempts at being cleaver that I had tried.

char *f(int n, char *s){
  char *o=calloc(n, strlen(s)+1),
    *t=o;

  while (*s) {
    for(int i=n; i--; )
      *t++=*s;
    s++;
  }

 return o;

}

\$\endgroup\$
1
  • \$\begingroup\$ This does not seem to work for negative n. \$\endgroup\$ – gastropner Dec 8 '17 at 10:43
1
\$\begingroup\$

Julia, 44 bytes

(s,x)->for i in split(s,"") print(i^abs(x))end
\$\endgroup\$
1
  • \$\begingroup\$ That doesn't quite work. When the integer argument is negative, the string should be reversed. \$\endgroup\$ – Dennis Jul 12 '17 at 14:39
1
\$\begingroup\$

K/Kona, 19 18 bytes

{,/$[y>0;;|:]y#'x}

Now, in the 0 case, it does output something, but that's the empty string so I'm sure that's all gravy.

I actually missed the negative input part of this initially, which cost me eleven bytes! Definitely not my best work

Usage:

k){,/$[y>0;;|:]y#'x}["Hello World";3]
"HHHeeellllllooo   WWWooorrrlllddd!!!"
k){,/$[y>0;;|:]y#'x}["Hello World!";0]
""
k){,/$[y>0;;|:]y#'x}["String";-3]
"gggnnniiirrrtttSSS"
\$\endgroup\$
1
  • \$\begingroup\$ Can trim a couple bytes by using (y<0)|:/ instead of $[y>0;;|:]. \$\endgroup\$ – coltim Dec 30 '20 at 17:25
1
\$\begingroup\$

PowerShell, 89 bytes

param($s,$n)-join($s[((0..($L=$s.Length)),(-1..-$L))[$n[0]-eq45]]|%{"$_"*"$n".trim('-')})

Try it online!

Generates a list of characters in the string, either forward or reversed, string-multiplies each, and joins the resulting array. $n[0]-eq45 is the ASCII code of - and .Trim('-') is shorter than [Math]::Abs($n)

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

C#, 70 Bytes

using System.Linq;(s,n)=>string.Join("",s.Select(c=>new string(c,n)));

The select function is used to create a new string with the original character repeated n-times, results are joined together.

\$\endgroup\$
1
  • \$\begingroup\$ Hello and Welcome to PPCG! Unfortunatley your answer does not work for negatives or zero. You can also shorten your code by using currying i.e. s=>n=>, string.Concat() and you don't need the trailing semi colon. \$\endgroup\$ – TheLethalCoder Jul 13 '17 at 13:00
1
\$\begingroup\$

C#, 108 bytes

using System.Linq;s=>n=>{var a=s.Select(c=>new string(c,n>0?n:-n));return string.Concat(n<0?a.Reverse():a);}

Full/Formatted Version:

using System;
using System.Linq;

namespace TestBed
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string, Func<int, string>> f = s => n =>
            {
                var a = s.Select(c => new string(c, n > 0 ? n : -n));

                return string.Concat(n < 0 ? a.Reverse() : a);
            };

            Console.WriteLine(f("Hello World!")(3));
            Console.WriteLine(f("foo")(12));
            Console.WriteLine(f("String")(-3));
            Console.WriteLine(f("This is a fun challenge")(0));
            Console.WriteLine(f(@"Hello
World!")(2));

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

Brainfuck, 26 bytes

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

Try it online!

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

vim, 45 bytes

:s/\(.\)/\1<C-v>
/g
adl<esc>gJaP<esc>"add
:%norm @a
:%j!

<esc> is 0x1b, and <C-v> is 0x16.

:s/\(.\)/\1<C-v><nl>/g splits the string into one character per line.

adl<esc>gJaP<esc>"add then constructs a command in buffer a that will copy a line n times, where n is the number that was previously on this line.

%norm @a and :%j! then apply that command to each line in the file and rejoin the lines respectively.

Try it online

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

C++, 152 bytes

#define l(x,n)for(int x=0;x<n;++x)
typedef std::string s;s f(s t,int c){s r;l(i,t.size())l(j,abs(c))r+=t[i];if(c<0)reverse(r.begin(),r.end());return r;}

And here's the full code you can test with.

#include <iostream>

#define l(x,n)for(int x=0;x<n;++x)
typedef std::string s;s f(s t,int c){s r;l(i,t.size())l(j,abs(c))r+=t[i];if(c<0)reverse(r.begin(),r.end());return r;}

int main(int argc, const char * argv[]) {
    std::cout << f("Hello World!", 3) << std::endl;
    std::cout << f("foo", 12) << std::endl;
    std::cout << f("String", -3) << std::endl;
    std::cout << f("This is a fun challenge", 0) << std::endl;
    std::cout << f("Hello\nWorld!", 2) << std::endl;
    return 0;
}
\$\endgroup\$
6
  • \$\begingroup\$ To start you certainly don't need all the whitespace here. \$\endgroup\$ – Wheat Wizard Jul 13 '17 at 5:06
  • \$\begingroup\$ @WheatWizard Thanks! I didn't know the spaces don't count. \$\endgroup\$ – Zack Lee Jul 13 '17 at 14:34
  • \$\begingroup\$ I'm not getting the same byte count. I'm getting 202 bytes. If I remove all the unnecessary whitespace it goes down to 140, but I don't see where the 134 number is coming from. \$\endgroup\$ – Wheat Wizard Jul 13 '17 at 14:37
  • 1
    \$\begingroup\$ @ZackLee Spaces do count. You can just remove a lot of them by writing the whole thing on one line and writing (for example) for( instead of for ( \$\endgroup\$ – F1Krazy Jul 13 '17 at 15:00
  • \$\begingroup\$ You need to count those typedefs and defines. And the #include. And the using nam...you need to count everything that isn't main. \$\endgroup\$ – Ray Jul 13 '17 at 22:44
1
\$\begingroup\$

Unwanted, Unnecessary, Opportunistic, 7 bytes

IAM*|V^
\$\endgroup\$
1
\$\begingroup\$

Forth, 132 bytes.

My first golf, Idk what I'm doing I'm sure it could be improved a lot.

: Z chars + c@ emit ; : X 0 do dup n Z loop ; : Y dup 0 < if negate then dup 0 > if n count 0 do over i 1 + swap X drop loop then ;

or

: Z chars + c@ emit ;
: X 0 do dup n Z loop ;
: Y dup 0 < if negate then dup 0 > if n count 0 do over i 1 + swap X drop loop then ;

The negate and comparisons are just for the 0 and negative cases. This is assuming we've already been given the string at 'n', I'm unsure if this is allowed.

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

Mathematica, 56 bytes

""<>Thread@Table[Reverse[Characters@#2,2+Sign@#],Abs@#]&

Try it at the Wolfram sandbox! (Doesn't work in Mathics…)

Takes the number then the string as input.

The Reverse function can take a second parameter saying what level of the array to reverse at (so Reverse[{{1,2},{3,4}}] returns {{3,4},{1,2}} but Reverse[{{1,2},{3,4}},2] gives {{2,1},{4,3}}, for instance). When the input number is negative, we reverse at level 1, but when it's zero or positive, we reverse at level 2 or 3. Since Characters@#2 is a list with only one level, reversing at deeper levels has no effect.

Once that's done, we repeat the list of characters then transpose the resulting array using Thread so the repeated characters end up next to each other.

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

tcl, 120

proc M s\ n {if $n<0 {set s [string rev $s];set n [expr -$n]};lmap c [split $s ""] {append x [string repe $c $n]};set x}

demo

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

Retina, 76 bytes

Os^$`(?<=^-.+¶.*).

^.+
$*
s`(?<=¶.*)
	
{`^1

}s`(?<=^1.*)	(.)
	$1$1
\`^¶|	

Try it online!

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

Husk, 13 bytes

So?I↔>0o`ȯṁRa

Try it online!

Ungolfed/Explanation

       o`ȯṁ    -- with the input string..
           Ra  -- ..multiply each character by the absolute value |N|
So?            -- depending on N either apply..
   I           -- ..the identity..
     >0        -- ..if N>0 or else..
    ↔          -- ..reverse it
\$\endgroup\$
0
\$\begingroup\$

Clojure, 24 bytes

#(for[c % _(range %2)]c)

Returning a string instead of a sequence of characters pushes this to 35 bytes:

#(apply str(for[c % _(range %2)]c))
\$\endgroup\$
0
\$\begingroup\$

[C#], 103 bytes

var r=n<0?-n:n;var a=new int[p.Length*r].Select((_,i)=>p[i/r]);return String.Concat(n<0?a.Reverse():a);

Try It Online!

Tried something a little different from the other C# answers, without using 'new string(str, x)'.

\$\endgroup\$
1
2

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.