Moltiplica una stringa per un numero!


34

Qualche tempo fa c'era una sfida sulla moltiplicazione delle stringhe. Ci ha mostrato come possiamo moltiplicare non solo i numeri, ma anche le stringhe. Tuttavia, non possiamo ancora moltiplicare un numero per una stringa correttamente. C'è stato un tentativo di farlo, ma questo è ovviamente sbagliato. Dobbiamo sistemarlo!

Il tuo compito:

Scrivi una funzione o un programma che moltiplica due input, una stringa e un numero intero. Per moltiplicare (correttamente) una stringa per un numero intero, dividere la stringa in caratteri, ripetere ogni carattere un numero di volte uguale all'intero, quindi incollare nuovamente i caratteri. Se il numero intero è negativo, utilizziamo il suo valore assoluto nel primo passaggio, quindi invertiamo la stringa. Se l'ingresso è 0, non viene emesso nulla (qualsiasi cosa moltiplicata per 0 è uguale a nulla).

Ingresso:

Una stringa composta esclusivamente da caratteri ASCII e newline stampabili e un numero intero (possibile negativo).

Produzione:

La stringa moltiplicata per l'intero.

Esempi:

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

                               WWoorrlldd!!

punteggio:

Questo è , vince il conteggio di byte più basso!


4
Possiamo supporre che la stringa sia stampabile solo in ASCII, più newline?
mbomb007,

Possiamo produrre un elenco di stringhe?
totalmente umano l'

Soluzione parziale in Retina. Funziona solo con valori positivi dell'intero. Probabilmente non avrò il tempo di finirlo se qualcuno lo vuole. tio.run/##K0otycxL/P8/…
mbomb007

@ mbomb007, sì, scusami per averci dedicato così tanto tempo.
Gryphon - Ripristina Monica il

@totallyhuman, no non puoi.
Gryphon - Ripristina Monica l'

Risposte:


31

Gelatina , 6 5 4 byte

²Ɠxm

Provalo online!

Come funziona

²Ɠ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.

1
OK, ora sono davvero colpito. Mi piacerebbe una spiegazione di questa particolare meraviglia in miniatura.
Gryphon - Ripristina Monica l'

Sicuro. Non appena ho creato una suite di test e ho finito di giocare a golf.
Dennis,

4
OK, se riesci a rimpicciolirlo, ho intenzione di smettere di provare a fare una domanda che ti porterà> 10 byte.
Gryphon - Ripristina Monica l'

13
OK, tutto qui. Sto imparando la gelatina. Voglio essere in grado di fare anche magia.
Gryphon - Ripristina Monica l'

2
Sappiamo tutti come una discussione sulle catene di gelatina finisca per essere un disastro ...
Erik the Outgolfer,

9

JavaScript (ES6), 63 byte

Accetta input nella sintassi del curry (s)(n) .

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

Casi test


3
+1 per reduce!
Neil,



6

05AB1E , 10 byte

S²Ä×J²0‹iR

Provalo 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

TFW, trascorri 30 minuti cercando di trovare qualcosa per dimostrare a @Riley che ²0‹inon è il percorso migliore e trovare letteralmente 0 alternative.
Magic Octopus Urn l'

@MagicOctopusUrn Ho usato qualcosa come ²0‹iprima e penso sempre che ci debba essere qualcosa di meglio.
Riley,

Penso di aver provato a trovare un'alternativa circa 10 volte adesso ... sprecando 3 ore complessive della mia vita ._. Ä.D)øJ¹0‹iRè il meglio che posso fare senza copiarti, penso che il tuo sia ottimizzato.
Magic Octopus Urn l'

Se ti interessa, Emigna ha usato è qui , anche se non riesco a trovare un modo per applicarlo in questo scenario. Salverebbe un massimo di 1 byte, se quello.
Magic Octopus Urn

SÂΛ@²Ä×J, usando Îper premere 0 e input funziona se si cambia l'ordine. Salva 1 byte! (Sostituito anche l'if, quindi non è necessario
chiuderlo

5

MATL , 9 byte

y|Y"w0<?P

Gli input sono: numero, quindi stringa.

Stringhe con a capo sono inseriti utilizzando char 10come segue: ['first line' 10 'second line'].

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

Considera gli input -3 e '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)

5

Haskell , 41 36 byte

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

Provalo online!

Esempio di utilizzo: f (-3) "abc" rese "cccbbbaaa".

Modifica: -5 byte grazie a xnor!


1
C'è (<*[1..n])per ((<$[1..n])=<<).
xnor

@xnor Grazie! Buono a sapersi.
Laikoni,

5

V , 29, 23, 18 , 17 byte

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

Provalo online!

hexdump:

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

Grazie a @ nmjcman101 per aver salvato 6 byte, il che mi ha incoraggiato a salvarne altri 5!

La revisione originale è stata piuttosto terribile, ma ora sono davvero orgoglioso di questa risposta perché gestisce numeri negativi sorprendentemente bene. (V ha quasi nessun supporto numerico e nessun supporto per i numeri negativi)

Spiegazione:

æ_          " 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

A questo punto, il buffer si presenta così:

H
e
l
l
o

w
o
r
l
d
!
<cursor>

È importante non la nuova riga finale e che il cursore sia su di essa.

À           " 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.

Alcuni byte per te Provalo online! Odio sempre i "numeri negativi significano qualcos'altro!" anche custodia per bordi. Questo è un caso in cui i tuoi 0casi speciali in V sono stati super utili.
nmjcman101,

Mi dispiace per i numeri negativi speciali. Tuttavia, molte risposte sono riuscite a incorporarle nella loro risposta principale. Impressionante su questo V però.
Gryphon - Ripristina Monica il

@ nmjcman101 Oh wow, è così ovvio, non so come non ci abbia pensato. Grazie!
DJMcMayhem

@Gryphon Oh lo so. La sfida va bene, non mi piace la mia lingua per essere così cattivo in quello in cui dovrebbe essere bravo. : P
DJMcMayhem

5

R, 83 78 76 byte

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

Funzione anonima.

Federico ha salvato 3 byte, Giuseppe ha salvato 2 4.

Spiegazione:

     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

test:

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

2
Molto bene ! È possibile salvare alcuni byte scrivendo rep(foo,,,3)o rep(foo,e=3)(stessa lunghezza) ;-)
Frédéric,

@ Frédéric mi hai battuto, stavo per dire la stessa cosa!
Giuseppe,

1
sì, nessun problema! Fondamentalmente, volevo sbarazzarmi delle parentesi graffe, quindi avevo bisogno di liberarmi di a=. Quindi, ho usato il valore di acome argomento per la funzione inversa se i<0, avendo il condizionale restituire la funzione (motivo per cui avevo bisogno dei backquotes). Ma dovevo applicare anche la funzione di identità per il i>=0caso, quindi ho usato quello (che è abbastanza vicino. (è in effetti una funzione. R è strano.
Giuseppe,

1
tra l'altro, i documenti R per Paren affermano che (è semanticamente equivalente all'identitàfunction(x)x
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


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
{}

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

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


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

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
{}

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

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

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!


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


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!


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
}

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!


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!


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!


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

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]



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;

}


This does not seem to work for negative n.
gastropner
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.