Multipliez une chaîne par un nombre!

34

Il y a quelque temps, il y avait un défi à relever concernant la multiplication de chaînes. Cela nous a montré comment nous pouvons multiplier non seulement des nombres, mais aussi des chaînes. Cependant, nous ne pouvons toujours pas multiplier un nombre par une chaîne correctement. Il y a eu une tentative de le faire mais c'est évidemment faux. Nous devons régler cela!

Ta tâche:

Ecrivez une fonction ou un programme qui multiplie deux entrées, une chaîne et un entier. Pour (correctement) multiplier une chaîne par un entier, divisez la chaîne en caractères, répétez chaque caractère un nombre de fois égal à celui-ci, puis collez les caractères ensemble. Si le nombre entier est négatif, nous utilisons sa valeur absolue dans la première étape, puis inversons la chaîne. Si l'entrée est 0, rien ne sort (rien multiplié par 0 ne vaut rien).

Contribution:

Une chaîne composée uniquement de caractères ASCII imprimables et de nouvelles lignes, ainsi qu'un entier (négatif possible).

Sortie:

La chaîne multipliée par le nombre entier.

Exemples:

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

                               WWoorrlldd!!

Notation:

C'est le , le plus petit nombre d'octets gagne!

Gryphon - Rétablir Monica
la source
4
Pouvons-nous supposer que la chaîne est imprimable uniquement en ASCII, plus des nouvelles lignes?
mbomb007
Pouvons-nous sortir une liste de chaînes?
totalement humain
Solution partielle dans la rétine. Ne fonctionne que pour les valeurs positives de l'entier. Je ne prendrai probablement pas le temps de le terminer si quelqu'un le souhaite. tio.run/##K0otycxL/P8/…
mbomb007
@ mbomb007, oui, désolé d'avoir pris autant de temps à ce sujet.
Gryphon - Réintégrer Monica
@totallyhuman, non vous ne pouvez pas.
Gryphon - Rétablir Monica

Réponses:

31

Gelée , 6 5 4 octets

²Ɠxm

Essayez-le en ligne!

Comment ça marche

²Ɠxm  Main link. Argument: n (integer)

²     Yield n².
 Ɠ    Read and eval one line of input. This yields a string s.
  x   Repeat the characters of s in-place, each one n² times.
   m  Takes each |n|-th character of the result, starting with the first if n > 0, 
      the last if n < 0.
Dennis
la source
1
OK, maintenant je suis vraiment impressionné. J'aimerais une explication de cette merveille en miniature.
Gryphon - Réintégrez Monica
Sûr. Dès que j'ai fait une suite de tests et que j'ai fini de jouer au golf.
Dennis
4
OK, si vous pouvez réduire cela au minimum, je vais arrêter d'essayer de poser une question qui vous prendra> 10 octets.
Gryphon - Rétablir Monica
13
OK ça y est. J'apprends Jelly. Je veux aussi pouvoir faire de la magie.
Gryphon - Réintégrez Monica
2
Nous savons tous à quel point une discussion sur les chaînes de gelée finit par être un gâchis ...
Erik the Outgolfer
9

JavaScript (ES6), 63 octets

Prend la syntaxe de currying (s)(n).

s=>n=>[...s].reduce((s,c)=>n<0?c.repeat(-n)+s:s+c.repeat(n),'')

Cas de test

Arnauld
la source
3
+1 pour reduce!
Neil
9

Python 3 , 44 octets

f=lambda s,n:s and s[0]*n+f(s[1:],n)+s[0]*-n

Essayez-le en ligne!

Dennis
la source
Le cas de base semble ignorer le dernier caractère.
xnor
Je ne sais pas trop pourquoi j'ai fait ça ... Merci!
Dennis
1
41 bytes. but idk if a function call as f(n,*s) is considered valid
Felipe Nardi Batista
9

Python 2, 59 57 50 46 bytes

-2 bytes thanks to Anders Kaseorg. -4 bytes thanks to Dennis.

lambda s,n:''.join(i*n**2for i in s)[::n or 1]

Try it online!

totallyhuman
la source
6

05AB1E, 10 bytes

S²Ä×J²0‹iR

Try it online!

S          # Split the string into characters
 ²Ä×       # Repeat each character abs(integer) times
    J      # Join into a string
     ²0‹i  # If the integer is less than 0...
         R #   Reverse the string
Riley
la source
TFW you spend 30 minutes trying to come up with something to prove to @Riley that ²0‹i isn't the best route and come up with literally 0 alternatives.
Magic Octopus Urn
@MagicOctopusUrn I've used something like ²0‹i before and I always think there has to be something better.
Riley
I think I've tried to find an alternative around 10 times now... wasting a cumulative 3 hours of my life ._. Ä.D)øJ¹0‹iR is the best I can do without copying you, I think yours is optimized.
Magic Octopus Urn
If you care, Emigna used è here, though I can't find a way to apply it in this scenario. Would save a maximum of 1 byte, if that.
Magic Octopus Urn
SÂΛ@²Ä×J, using Î to push 0 and input works if you change the order. Saves 1 byte! (Also replaced the if, so it doesn't need to be closed)
kalsowerus
5

MATL, 9 bytes

y|Y"w0<?P

Inputs are: number, then string.

Strings with newlines are input using char 10 as follows: ['first line' 10 'second line'].

Try it online! Or verify all test cases.

Explanation

Consider inputs -3 and 'String'.

y      % Implicitly take two inputs. Duplicate from below
       % STACK: -3, 'String', -3
|      % Absolute value
       % STACK: -3, 'String', 3
Y"     % Run-length decoding
       % STACK: -3, 'SSStttrrriiinnnggg'
w      % Swap
       % STACK: 'SSStttrrriiinnnggg', -3
0<     % Less than 0?
       % STACK: 'SSStttrrriiinnnggg', 1
?      % If so
  P    %   Flip
       %   STACK: 'gggnnniiirrrtttSSS'
       % End (implicit). Display (implicit)
Luis Mendo
la source
5

Haskell, 41 36 bytes

f n|n<0=reverse.f(-n)|1<3=(<*[1..n])

Try it online!

Example usage: f (-3) "abc" yields "cccbbbaaa".

Edit: -5 bytes thanks to xnor!

Laikoni
la source
1
There's (<*[1..n]) for ((<$[1..n])=<<).
xnor
@xnor Thanks! That's good to know.
Laikoni
5

V, 29, 23, 18, 17 bytes

æ_ñÀuñÓ./&ò
ÀäëÍî

Try it online!

Hexdump:

00000000: e65f f1c0 75f1 d32e 2f26 f20a c0e4 ebcd  ._..u.../&......
00000010: ee                                       .

Thanks to @nmjcman101 for saving 6 bytes, which encouraged me to save another 5!

The original revision was pretty terrible, but now I'm really proud of this answer because it handles negative numbers surprisingly well. (V has next to no numerical support and no support for negative numbers)

Explanation:

æ_          " Reverse the input
  ñ  ñ      " In a macro:
   À        "   Run the arg input. If it's positive it'll give a count. If it's negative
            "   running the '-' will cause V to go up a line which will fail since we're
            "   on the first line, which will break out of this macro
    u       "   (if arg is positive) Undo the last command (un-reverse the line)
      Ó./&ò " Put every character on it's own line

At this point, the buffer looks like this:

H
e
l
l
o

w
o
r
l
d
!
<cursor>

It's important to not the trailing newline, and that the cursor is on it.

À           " Run arg again. If it's negative, we will move up a line, and then give the 
            " absolute value of the count. If it's positive (or 0) it'll just give the
            " count directly (staying on the last line)
 ä          " Duplicate... (count times)
  ë         "   This column. 
   Íî       " Remove all newlines.
DJMcMayhem
la source
A few bytes for ya Try it online! I always hate the "Negative numbers mean something else!" edge case too. This is a case where your 0 special cases in V came in super handy.
nmjcman101
Sorry about the negative numbers special. However, a lot of answers managed to incorporate that into their main answer. Impressive on this V one though.
Gryphon - Reinstate Monica
@nmjcman101 Oh wow, that's so obvious, I don't know how I didn't think of it. Thank you!
DJMcMayhem
@Gryphon Oh I know. The challenge is fine, I just dislike my own language for being so bad at what it's supposed to be good at. :P
DJMcMayhem
5

R, 83 78 76 bytes

function(s,i)cat('if'(i<0,rev,`(`)(rep(el(strsplit(s,'')),e=abs(i))),sep='')

Anonymous function.

Frederic saved 3 bytes, Giuseppe saved 2 4.

Explanation:

     el(strsplit(s,''))                      # split string into list characters
 rep(                  ,e=abs(i)))           # repeat each character abs(i) times


    'if'(i<0,rev,   ){...}                 # if i>0, reverse character list
                 `(`                       # otherwise leave it alone: `(` is the identity function
cat(                      ,sep='')         # print the result

Tests:

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

WWoorrlldd!!
BLT
la source
2
Well done ! You could save a few bytes by writing rep(foo,,,3) or rep(foo,e=3) (same lenght) ;-)
Frédéric
@Frédéric you beat me to it, I was going to say the same thing!
Giuseppe
1
yeah, no problem! Basically, I wanted to get rid of the braces, so I needed to get rid of a=. Hence, I used the value of a as an argument to the reverse function if i<0, by having the conditional return the function (which is why I needed the backquotes). But I needed to also apply the identity function for the i>=0 case, so I used ( which is close enough. ( is in fact a function. R is weird.
Giuseppe
1
btw, the R docs for Paren say that ( is semantically equivalent to the identity function(x)x
Giuseppe
1
76 bytes
Giuseppe
4

05AB1E, 10 bytes

0‹FR}ʒ¹Ä×?

Try it online!

Explanation

0‹F         # input_1 < 0 times do:
   R        # reverse input_2
    }       # end loop
     ʒ      # filter
      ¹Ä×   # repeat current char abs(input_1) times
         ?  # print without newline
Emigna
la source
4

PHP>=7.1, 65 bytes

for([,$s,$n]=$argv;$i<strlen($s)*abs($n);)echo$s[$i++/$n-($n<0)];

PHP Sandbox Online

Jörg Hülsermann
la source
1
In integer context, $n<0 has the same value as $n<0?:0 but it's 3 bytes shorter :-)
axiac
4

Brain-Flak (BrainHack), 154 152 bytes

([(({})(<()>))]<>)<>{({}()<([{}]()<([{}])>)<>({}<>)<>>)<>}{}<>{}<>({}<([][()]){{}({<({}<(({}<>)<>)>())>[()]}<{}{}>)([][()])}{}{}<>>){{}{({}<>)<>}(<>)}{}

Try it online!

Just here to give DJMcMayhem some competition. ;)

Explanation

Here's a modified version of DJMcMayhem's explanation

#Compute the sign and negative absolute value 
([(({})<(())>)]<>)<>{({}()<([{}]()<([{}])>)<>({}<>)<>>)<>}{}<>{}<>

#Keep track of the sign
({}<

    #For each char in the input string:
    ([][()])
    {
        {}

        #Push n copies to the alternate stack
        ({<({}<(({}<>)<>)>())>[()]}<{}{}>)

        #Endwhile
        ([][()])
    }{}{}<>

#Push the sign back on
>)

#If so...
{{}

    #Reverse the whole stack
    {({}<>)<>}

    #And toggle over, ending the loop
    (<>)
}

#Pop the counter off
{}
Wheat Wizard
la source
4

J, 19 15 13 bytes

(#~|)A.~0-@>]

Try it online!

Explanation

        0-@>]      NB. first or last index depending on sign of right arg
     A.~           NB. get first or last Anagram of left arg
(#~|)              NB. copy left arg, absolute-value-of-right-arg times
Tikkanz
la source
2
(#~|)A.~0-@>] for 13 bytes
miles
Very nice @miles !
Tikkanz
No problem. You also don't need to count the parentheses used to invoke the verb.
miles
1
Also 13 bytes: #~ ::(|.@#~|)
FrownyFrog
3

Dyalog APL, 15 bytes

{⌽⍣(⍵<0)⊢⍺/⍨|⍵}

String as a left argument, number as a right argument.

Try it online!

How?

⍺/⍨ - repeat the string

|⍵ - abs(number) times

⌽⍣ - reverse if

(⍵<0) - the number is below 0

Uriel
la source
Umm, it'd be nice if the TIO like worked?
Gryphon - Reinstate Monica
@Gryphon and here goes the byte...
Uriel
Yep, I'd just realized that and was typing out my comment to tell you.
Gryphon - Reinstate Monica
3

MATLAB, 37 bytes

@(s,n)flip(repelem(s,abs(n)),(n<0)+1)

This defines and anonymous function with inputs s: string and n: number.

Example runs:

>> @(s,n)flip(repelem(s,abs(n)),(n<0)+1)
ans = 
    @(s,n)flip(repelem(s,abs(n)),(n<0)+1)

>> f = ans;

>> f('String', 3)
ans =
SSStttrrriiinnnggg

>> f('String', -3)
ans =
gggnnniiirrrtttSSS

>> f('String', 0)
ans =
   Empty matrix: 1-by-0
Luis Mendo
la source
Choosing which dimension to flip along was way better than the mess I wrote 😛 +1. and I always forget repelem exists.
Stewie Griffin
@StewieGriffin Well, you could incorporate that in your answer too :-) (+1 already). I think there's no repelem in Octave, for now
Luis Mendo
3

Brain-Flak (Haskell), 202 192 bytes

(({})<(([({})]<>)){({}()<([{}])<>({}<>)<>>)<>}{}([{}]<><{}>)([][()]){{}({<({}<(({}<>)<>)>[()])>()}<{}{}>)([][()])}{}{}<>>)([({}<(())>)](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}{{}{({}<>)<>}(<>)}{}

Try it online!

This is probably the worst possible language to do it in, but it's done. Thanks to @Wheatwizard for providing the Haskell interpreter, which allows mixed input formats. This would be about 150 bytes longer without it.

Explanation:

#Keep track of the first input (n)
(({})<

    #Push abs(n) (thanks WheatWizard!)
    (([({})]<>)){({}()<([{}])<>({}<>)<>>)<>}{}([{}]<><{}>)

    #For each char in the input string:
    ([][()])
    {
        {}

        #Push n copies to the alternate stack
        ({<({}<(({}<>)<>)>[()])>()}<{}{}>)

        #Endwhile
        ([][()])
    }{}{}<>

#Push the original n back on
>)

#Push n >= 0
([({}<(())>)](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}

#If so...
{{}

    #Reverse the whole stack
    {({}<>)<>}

    #And toggle over, ending the loop
    (<>)
}

#Pop the counter off
{}
DJMcMayhem
la source
You could use my 52 byte abs to save 2 bytes, you could also use the 50 byte -abs I gave you and increment instead of decrementing to save 6 bytes.
Wheat Wizard
3

Java (OpenJDK 8), 99 98 89 87 85 bytes

s->n->{for(int i=s.length*(n<0?n:-n),r=n<0?0:~i;i++<0;)System.out.print(s[(i+r)/n]);}

Try it online!

  • -2 bytes thanks to @Xanderhall
  • -2 bytes thanks to @Nevay
Olivier Grégoire
la source
Ideas that don't work (way longer): reverse the string before, use a stream,
Olivier Grégoire
1
Save 2 bytes with s[(n<0?-l-~i:i)/n]
Xanderhall
@Xanderhall Thanks! I've been looking for that one for so long my eyes bleed. I knew it was possible, I just messed everything up when implementing it.
Olivier Grégoire
1
@user902383 Yes, it's mandatory. If they were optional, a lot of things would be unreadable. Also, my function is not a "single statement", but a for-loop, which encompass several statements.
Olivier Grégoire
1
You can save 1 byte by incrementing i in the condition s->n->{for(int l=s.length*(n<0?-n:n),i=0;i++<l;)System.out.print(s[(n<0?i-l:i-1)/n]);}. Another byte can be saved by iterating from -l to 0 instead (s->n->{for(int i=s.length*(n<0?n:-n),r=n<0?0:~i;i++<0;)System.out.print(s[(i+r)/n]);}).
Nevay
2

Octave, 49 bytes

@(s,n){t=repmat(s,abs(n),1)(:)',flip(t)}{2-(n>0)}

Try it online!

I will provide an explanation tomorrow.

Stewie Griffin
la source
2

Ruby, 59 +1 = 60 bytes

Uses -n flag.

n=eval$_
a=$<.read
a.reverse!if n<0
a.chars{|i|$><<i*n.abs}

Try it online!

Pavel
la source
1
eval$_ is shorter than $_.to_i by 1 byte. String#chars can also accept a block the same way String#each_char can. Finally, reverse the input before processing each character so you can print it directly instead (switching your flag to -n). All of this combines to become 55+1=56 bytes.
Value Ink
2

Charcoal, 16 bytes

Fθ¿‹η0F±Iη←ιFIηι

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

Fθ              For each character in the input string
  ¿‹η0          If the input number is less than zero
      F±Iη      Repeat the negation of the input number times
          ←ι    Print the character leftwards (i.e. reversed)
      FIη       Otherwise repeat the input number times
         ι      Print the character
Neil
la source
2

Japt, 12 bytes

®pVaìr!+sVg

Try it online!

Explanation

Implicit input of string U and integer V.

®pVaÃ

Map (®) each letter of U (implicitly) to itself repeated (p) abs(V) (Va) times.

¬r

Turn the string into an array of chars (¬) and reduce (r) that with...

!+sVg

"!+".slice(sign(V)) - this either reduces with +a + b, or with !+b + a.
Thanks @Arnauld for the backwards-reduce idea!

Justin Mariner
la source
I feel like £gY*Vg)pVa should lead to a shorter solution but my brain has shut down for the holidays so I can't quite figure it out. You may be able to do something with it, though.
Shaggy
2

WendyScript, 46 bytes

<<f=>(s,x){<<n=""#i:s#j:0->x?x>0n+=i:n=i+n/>n}

f("Hello World", -2) // returns ddllrrooWW  oolllleeHH

Try it online!

Explanation (Ungolfed):

let f => (s, x) {
  let n = ""
  for i : s
    for j : 0->x
      if x > 0 n += i
      else n = i + n
  ret n
}
Felix Guo
la source
2

C89 bytes

main(int c,char**v){for(;*v[1];v[1]++)for(c=atoi(v[2]+(*v[2]=='-'));c--;)putchar(*v[1]);}

I saw Ben Perlin's version and wondered if you couldn't be shorter still and also have a full program; surely, atoi() and putchar() aren't that expensive in terms of bytes? Seems I was right!

Andrea
la source
2

Pyth, 13 11 bytes

*sm*.aQdz._

Try it!

-2 bytes thanks to @jacoblaw

explanation

*sm*.aQdz._   
  m     z     # map onto the input string (lambda var: d)
   *.aQd      # repeat the char d as often as the absolute value of the input number 
 s            # sum the list of strings into a single string
*        ._Q   # Multiply with the sign of the implicit input value: reverse for negative Q 

old approach, 13 bytes

_W<Q0sm*.aQdz

Try it!

KarlKastor
la source
you can save two bytes with this reversal logic
jacoblaw
2

Python 3, 68 bytes

h=lambda s,n:h(s[::-1],-n)if n<0 else s[0]*n+h(s[1:],n)if s else s*n

Try it online!

Kavi
la source
Hello, and welcome to the site! Unfortunately, this answer is invalid right now, since it doesn't support Negative numbers. The challenge says: If the integer is negative, we use its absolute value in the first step, and then reverse the string.
DJMcMayhem
Thanks for fixing it! BTW, you could take two bytes off by removing the spaces after parenthesis )
DJMcMayhem
Edited, thanks for the contribution
Kavi
n<0 else => n<0else
Zacharý
1

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
steenbergh
la source
1

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]

J42161217
la source
1

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;

}

Ben Perlin
la source
This does not seem to work for negative n.
gastropner