39
\$\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\$
6
  • 5
    \$\begingroup\$ Can we assume the string is printable ASCII-only, plus newlines? \$\endgroup\$
    – mbomb007
    Jul 11, 2017 at 21:45
  • \$\begingroup\$ Can we output a list of strings? \$\endgroup\$ Jul 11, 2017 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, 2017 at 21:59
  • \$\begingroup\$ @mbomb007, yes, sorry for taking so long about that. \$\endgroup\$
    – Gryphon
    Aug 2, 2017 at 0:08
  • \$\begingroup\$ @totallyhuman, no you may not. \$\endgroup\$
    – Gryphon
    Aug 8, 2017 at 3:52

57 Answers 57

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

QBIC, 32 bytes

g=sgn(c)[_l;||[:*g|?_sA,b*g,1|';

Explanation

            Takes inputs A$ ('Hello'), and c (-3) from the cmd line
g=sgn(c)    Save the sign of c          -1
[_l;||      FOR each char in A$
[:*g|       FOR the number of repetitions wanted    (ie: -3 * -1)
            Note that : reads a number from the cmd line, and c is the first 
            available variable to save it in after a and b got used as FOR counters.
            Also note that a negative value times the sign becomes positive.
?_s         PRINT a substring
  A         of A$
 ,b*g       startng at char n, where n is the first FOR loop counter times the sign
                That means that when c is negative, so is this. A negative starting index
                on Substring instructs QBIC to take from the right.
 ,1|        taking 1 char.
';          This bit injects a literal ; in the output QBasic, to suppress newlines om PRINT
\$\endgroup\$
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, 2017 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, 2017 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, 2020 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\$ Jul 13, 2017 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, 2017 at 5:06
  • \$\begingroup\$ @WheatWizard Thanks! I didn't know the spaces don't count. \$\endgroup\$
    – Zack Lee
    Jul 13, 2017 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, 2017 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, 2017 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, 2017 at 22:44
1
\$\begingroup\$

Unwanted, Unnecessary, Opportunistic, 7 bytes

IAM*|V^
\$\endgroup\$
1
\$\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\$
1
\$\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
\$\begingroup\$

Vyxal, 7 bytes

ȧ•?0<[Ṙ

Try it Online!

There's gotta be a better way to do this.

 •      # Repeat each char by...
ȧ       # absolute value of input
  ?0<[  # If it's negative
      Ṙ # Reverse
\$\endgroup\$
1
\$\begingroup\$

><> (Fish), 61 bytes

:&0)?v>i:0(?^\
-$0&0/\p3a'r'&
 .07~v?:<+1&:/
{:}+1/ >o< ~\.28

Try it

Explanation

enter image description here

Takes the number as the initial stack value, and the string as the STDIN.

Uses source code modification: Inserts a r command at 10,3 if the number is positive. If so invert the number. The & instruction is nicely in the perfect place both from the top and from the right side.

The {:} copies the character -n times.

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

Thunno 2, 7 bytes

AḄ$0<?r

Attempt This Online!

Explanation

AḄ$0<?r  # Implicit input
 Ḅ       # Multiply each character of the second input by...
A        # ...the absolute value of the first input
  $      # Push the first input again
   0<    # And check if it's negative
     ?   # If it is negative:
      r  #  Reverse the string
         # Implicit output
\$\endgroup\$
2
  • \$\begingroup\$ This doesn't work for cases like String, -3, as negative numbers need to reverse the input them multiply \$\endgroup\$
    – lyxal
    Jun 23, 2023 at 23:53
  • \$\begingroup\$ @lyxal thanks, fixed. \$\endgroup\$
    – The Thonnu
    Jun 24, 2023 at 5:44
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\$

C (gcc), 80 bytes

i;L;f(s,n)char*s;{L=strlen(s);for(i=0;i*i<L*n*L*n;)putchar(s[i++/n+~-L*(n<0)]);}

Try it online!

-1 byte from ceilingcat

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

Raku, 50 bytes

{($^a.comb »x»$^b.abs).join.&{$b <0??.flip!!$_}}

Try it online!

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

JavaScript (Node.js), 61 bytes

n=>g=(h,i=n,[c,...x]=h)=>c?i?i>0?c+g(h,i-1):g(h,i+1)+c:g(x):h

Try it online!

No longer longer than Q256411, but even same length it's only

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

Japt -P, 10 bytes

ÆVÃÕzUÌÉ©2

Try it

ÆVÃÕzUÌÉ©2     :Implicit input of integer U & string V
Æ              :Map the range [0,U)
 V             :  Return V
  Ã            :End map
   Õ           :Transpose
    z          :Rotate clockwise this many times
     UÌ        :  Sign of difference between U & -1
       É       :  Subtract 1
        ©2     :  Logical AND with 2
               :Implicitly join & output
\$\endgroup\$
1
2

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.