Multiplique uma string por um número!

34

um tempo, havia um desafio sobre a multiplicação de strings. Ele nos mostrou como podemos multiplicar não apenas números, mas também seqüências de caracteres. No entanto, ainda não podemos multiplicar um número por uma sequência corretamente. Houve uma tentativa de fazê-lo, mas isso está obviamente errado. Precisamos consertar isso!

Sua tarefa:

Escreva uma função ou programa que multiplique duas entradas, uma string e um número inteiro. Para (adequadamente) multiplicar uma sequência por um número inteiro, divida-a em caracteres, repita cada caractere um número de vezes igual ao número inteiro e cole os caracteres novamente. Se o número inteiro for negativo, usamos seu valor absoluto na primeira etapa e, em seguida, invertemos a string. Se a entrada for 0, não produza nada (nada multiplicado por 0 é igual a nada).

Entrada:

Uma sequência que consiste apenas em caracteres ASCII imprimíveis e novas linhas e um número inteiro (possível negativo).

Saída:

A sequência multiplicada pelo número inteiro.

Exemplos:

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

                               WWoorrlldd!!

Pontuação:

Isso é , a menor contagem de bytes ganha!

Gryphon - Restabelecer Monica
fonte
4
Podemos assumir que a string é apenas para impressão ASCII, além de novas linhas?
mbomb007
Podemos produzir uma lista de strings?
totallyhuman
Solução parcial em Retina. Funciona apenas para valores positivos do número inteiro. Provavelmente não terei tempo para terminar se alguém quiser. Você pode
usar o seguinte
@ mbomb007, sim, desculpe por demorar tanto sobre isso.
Gryphon - Restabelece Monica
@totallyhuman, não, você não pode.
Gryphon # Reinstate Monica

Respostas:

31

Gelatina , 6 5 4 bytes

²Ɠxm

Experimente online!

Como funciona

²Ɠ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
fonte
1
OK, agora estou realmente impressionado. Eu adoraria uma explicação dessa maravilha em miniatura.
Gryphon - Restabelece Monica
Certo. Assim que fiz uma suíte de testes e acabei de jogar golfe.
1111 Dennis
4
OK, se você puder diminuir isso, vou desistir de tentar fazer uma pergunta que levará 10 bytes.
Gryphon - Restabelece Monica
13
OK é isso. Estou aprendendo geléia. Eu quero ser capaz de fazer mágica também.
Gryphon - Restabelece Monica
2
Todos nós sabemos como uma discussão sobre cadeias de geléia acaba sendo uma bagunça ...
Erik o Outgolfer
9

JavaScript (ES6), 63 bytes

Recebe entrada na sintaxe de currying (s)(n).

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

Casos de teste

Arnauld
fonte
3
+1 para reduce!
1111 Neil
9

Python 3 , 44 bytes

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

Experimente online!

Dennis
fonte
O caso base parece ignorar o último caractere.
Xnor
Não tenho certeza por que fiz isso ... Obrigado!
Dennis
1
41 bytes . mas idk se uma chamada de função, como f(n,*s)é considerado válido
Felipe Nardi Batista
9

Python 2 , 59 57 50 46 bytes

-2 bytes graças a Anders Kaseorg. -4 bytes graças a Dennis.

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

Experimente online!

totalmente humano
fonte
6

05AB1E , 10 bytes

S²Ä×J²0‹iR

Experimente 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
fonte
TFW, você gasta 30 minutos tentando inventar algo para provar ao @Riley que ²0‹inão é a melhor rota e criar literalmente 0 alternativas.
Magic Octopus Urn
@MagicOctopusUrn Eu usei algo como ²0‹iantes e sempre acho que tem que haver algo melhor.
Riley
Acho que tentei encontrar uma alternativa cerca de 10 vezes agora ... desperdiçando 3 horas acumuladas da minha vida. Ä.D)øJ¹0‹iRé o melhor que posso fazer sem copiar você, acho que o seu está otimizado.
Magic Octopus Urn
Se você se importa, Emigna usou è aqui , embora não encontre uma maneira de aplicá-lo neste cenário. Economizaria no máximo 1 byte, se isso.
Magic Octopus Urn
SÂΛ@²Ä×J, usando Îpara pressionar 0 e a entrada funciona se você alterar a ordem. Economiza 1 byte! (Também substituiu o caso, por isso não precisa ser fechado)
kalsowerus
5

MATL , 9 bytes

y|Y"w0<?P

As entradas são: número e sequência.

Cordas com novas linhas são introduzidos usando carvão animal 10como se segue: ['first line' 10 'second line'].

Experimente online! Ou verifique todos os casos de teste .

Explicação

Considere entradas -3e '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
fonte
5

Haskell , 41 36 bytes

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

Experimente online!

Exemplo de uso: f (-3) "abc"rendimentos "cccbbbaaa".

Edit: -5 bytes graças ao xnor!

Laikoni
fonte
1
(<*[1..n])para ((<$[1..n])=<<).
Xnor
@xnor Obrigado! É bom saber disso.
Laikoni
5

V , 29, 23, 18 , 17 bytes

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

Experimente online!

Hexdump:

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

Agradeço a @ nmjcman101 por salvar 6 bytes, o que me incentivou a salvar outros 5!

A revisão original foi bastante terrível, mas agora estou realmente orgulhosa dessa resposta, porque lida com números negativos surpreendentemente bem. (V tem quase nenhum suporte numérico e nenhum número negativo)

Explicação:

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

Nesse ponto, o buffer fica assim:

H
e
l
l
o

w
o
r
l
d
!
<cursor>

É importante não a nova linha à direita, e que o cursor esteja nela.

À           " 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
fonte
Alguns bytes para você Experimente online! Eu sempre odeio o "números negativos significam outra coisa!" caso borda também. Este é um caso em que seus 0casos especiais em V foram super úteis.
nmjcman101
Desculpe pelos números negativos especiais. No entanto, muitas respostas conseguiram incorporar isso em sua resposta principal. Impressionante neste V um embora.
Gryphon - Reinstala Monica
@ nmjcman101 Oh uau, isso é tão óbvio, eu não sei como não pensei nisso. Obrigado!
DJMcMayhem
@ Gregry Oh, eu sei. O desafio é bom, eu simplesmente não gosto da minha própria língua por ser tão ruim no que deveria ser boa. : P
DJMcMayhem
5

R, 83 78 76 bytes

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

Função anônima.

Frederic salvou 3 bytes, Giuseppe salvou 2 4.

Explicação:

     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

Testes:

> 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
fonte
2
Bem feito ! Você poderia economizar alguns bytes por escrito rep(foo,,,3)ou rep(foo,e=3)(mesmo tamanho) ;-)
Frédéric
@ Frédéric você me venceu, eu ia dizer a mesma coisa!
Giuseppe
1
Sim, não há problema! Basicamente, eu queria me livrar do aparelho, então precisava me livrar dele a=. Portanto, usei o valor de acomo argumento para a função reversa se i<0, tendo o retorno condicional da função (é por isso que eu precisava das aspas). Mas eu também precisava aplicar a função de identidade para o i>=0caso, então usei o (que é próximo o suficiente. (é de fato uma função. R é estranho.
11137 Giuseppe
1
btw, os docs R para Paren dizer que (é semanticamente equivalente à identidadefunction(x)x
Giuseppe
1
76 bytes
Giuseppe
4

05AB1E , 10 bytes

0‹FR}ʒ¹Ä×?

Experimente online!

Explicação

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
fonte
4

PHP> = 7.1, 65 bytes

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

Sandbox do PHP Online

Jörg Hülsermann
fonte
1
No contexto inteiro, $n<0tem o mesmo valor como $n<0?:0, mas é mais curta 3 bytes :-)
axiac
4

Brain-Flak (BrainHack) , 154 152 bytes

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

Experimente online!

Só aqui para dar ao DJMcMayhem alguma competição. ;)

Explicação

Aqui está uma versão modificada da explicação de DJMcMayhem

#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
{}
Assistente de Trigo
fonte
4

J , 19 15 13 bytes

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

Experimente online!

Explicação

        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
fonte
2
(#~|)A.~0-@>]para 13 bytes
milhas
Muito bom @miles!
Tikkanz
Sem problemas. Você também não precisa contar os parênteses usados ​​para invocar o verbo.
miles
1
Também 13 bytes:#~ ::(|.@#~|)
FrownyFrog
3

Dyalog APL, 15 bytes

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

String como argumento à esquerda, número como argumento à direita.

Experimente online!

Quão?

⍺/⍨ - repita a corda

|⍵ - abs (número) vezes

⌽⍣ - inverter se

(⍵<0) - o número está abaixo de 0

Uriel
fonte
Umm, seria bom se o TIO desse certo?
Gryphon - Reinstate Monica
@Gryphon e aqui vai o byte ...
Uriel
Sim, eu acabei de perceber isso e estava digitando meu comentário para contar.
Gryphon - Restabelece Monica
3

MATLAB, 37 bytes

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

Isso define uma função anônima com as entradas s: string e n: number.

Exemplo é executado:

>> @(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
fonte
Escolher qual dimensão virar era muito melhor do que a bagunça que escrevi 😛 +1. e eu sempre esqueço que repelemexiste.
Stewie Griffin
@ StewieGriffin Bem, você também pode incorporar isso na sua resposta :-) (já +1). Eu acho que não há repelemno Octave, por enquanto #
Luis Mendo
3

Flak cerebral (Haskell) , 202 192 bytes

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

Experimente online!

Esta é provavelmente a pior linguagem possível, mas está pronta. Agradecemos a @Wheatwizard por fornecer o intérprete Haskell, que permite formatos de entrada mistos. Isso seria cerca de 150 bytes a mais sem ele.

Explicação:

#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
fonte
Você pode usar meus 52 bytes de abs para economizar 2 bytes, também pode usar os 50 bytes -abs que eu dei e incrementar em vez de diminuir para economizar 6 bytes.
Assistente de trigo
1
Alguma competição amigável.
Assistente de trigo
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
fonte
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
fonte
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
fonte
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
fonte
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
fonte
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
fonte
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
fonte
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
fonte
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
fonte
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
fonte
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
fonte
1

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

Skidsdev
fonte
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
fonte
This does not seem to work for negative n.
gastropner