Decimal Multiplication of Strings

14

Given 2 inputs, a string and a decimal number, output the string multiplied by that number.

The catch is that the number can be a float or an integer.

You should output the string floor(n) time and then the first floor((n-floor(n))*len(string)) letters again.

Other notes:

  • The input will not always be a float, it may be an int. So 1.5, 1, and 1.0 are all possible. It will always be in base 10 though, and if you wish an exception please comment.
  • The string input may contain whitespace, quotes and other characters. No newlines or control chars though.
  • No built-ins for direct string repeating, even string multiplication like the python 'a'*5 are allowed. However string addition is allowed.

Test cases:

The comma & space separate the inputs.

test case, 1 -> test case

case, 2.5 -> casecaseca

(will add more later), 0.3333 -> (will(space)

cats >= dogs, 0.5 -> cats >

Final Note:

I am seeing a lot of answers that use builtin string multiplication or repeation functions. This is not allowed. @VTC's answer is valid though, because it does not multiply the string, only the float input. So the definitive rule is: If it directly multiplies the string, you can't do it.

Rɪᴋᴇʀ

Posted 2016-02-08T15:42:41.037

Reputation: 7 410

The wording was modified repeatedly (I did not see the first revision). I suggest to remove direct string repeating (what does this mean?). But all in all you're right – edc65 – 2016-02-08T16:10:16.953

1Related quine version – Sp3000 – 2016-02-08T16:47:40.860

@Sp3000 yeah, I know. I think the difference is significant enough. – Rɪᴋᴇʀ – 2016-02-08T17:18:10.167

"No built-ins for direct string repeating, even string multiplication like the python 'a'*5 are allowed." You don't explain the difference between these. They sound the same to me. – msh210 – 2016-02-08T20:50:22.913

@edc65 In Perl you can do list repetition then concatenate the elements of that list, which isn't direct string repetition. In Perl 5: join "", ("case") x 2 vs "case" x 2, in Perl 6 [~] "case" xx 2 vs the same "case" x 2 – Brad Gilbert b2gills – 2016-02-08T20:59:23.607

@BradGilbertb2gills yes, that is allowed. So are stack duplication operators and number*number multiplication. – Rɪᴋᴇʀ – 2016-02-08T21:31:28.550

Answers

4

Jelly, 5 bytes

×L}Rị

Doesn't use a repetition built-in. Try it online!

How it works

×L}Rị  Main link. Left input: n (multiplier). Right input: S (string)

 L}    Yield the length of S.
×      Multiply it with n.
   R   Range; turn n×len(S) into [1, ... floor(n×len(S))].
    ị  Retrieve the elements of S at those indices.
       Indices are 1-based and modular in Jelly, so this begins with the first and
       jump back after reaching the last.

Dennis

Posted 2016-02-08T15:42:41.037

Reputation: 196 637

7

Java 7, 89

void g(char[]a,float b){for(int i=0,l=a.length;i<(int)(l*b);)System.out.print(a[i++%l]);}

takes char[] and float and outputs to STDOUT. basic looping.

Marky Markov

Posted 2016-02-08T15:42:41.037

Reputation: 141

3Good golfing, even for java. :P – Rɪᴋᴇʀ – 2016-02-08T16:33:01.430

this was suggested on my other answer too, but i don't think i will do this. it does not seem right to me. – Marky Markov – 2016-02-08T16:44:18.633

Eh, fair enough. It is recognized here, but alright. :D – Addison Crump – 2016-02-08T16:44:45.673

I recommend declaring your language as Java 7. Then no one can tell you to use lambdas. – feersum – 2016-02-08T16:46:49.640

6

JavaScript (ES6), 50 bytes

Edit 2 bytes more to include definition of function f. 1 byte less using the tip of @manatwork. Note: using ~ we have more iterations than necessary, but this is code golf and even 1 byte counts

f=(s,n,l=s.length*n)=>~n?f(s+s,n-1,l):s.slice(0,l)

TEST

f=(s,n,l=s.length*n)=>~n?f(s+s,n-1,l):s.slice(0,l)

//TEST
console.log=x=>O.textContent+=x+'\n'
;[
 ['test case', 1, 'test case'],
 ['case', 3.5, 'casecasecaseca'],
 ['(will add more later)', 0.3333, '(will '],
 ['cats >= dogs', 0.5, 'cats >']]
.forEach(t=>{
  var s=t[0],n=t[1],x=t[2],r=f(s,n);
  console.log("«"+s+"» "+n+' => «'+r+'» '+(x==r?'OK':'FAIL expected '+x));
 })
<pre id=O></pre>

edc65

Posted 2016-02-08T15:42:41.037

Reputation: 31 086

Okay, thanks. So far most of the answers have had no problem, and it is really easy to fix. Thanks for correcting it. – Rɪᴋᴇʀ – 2016-02-08T16:28:00.860

Tiny typo: n>0 in the code vs. n>1 in the test case. – manatwork – 2016-02-08T16:38:11.643

@manatwork thanks. It should work either way – edc65 – 2016-02-08T17:36:19.137

Oh. Indeed. But then why not just ~n? (Really just a question. Tried only the given test cases.) – manatwork – 2016-02-08T17:42:08.070

3@edc65 Where is f defined in your solution? Aren't you missing f=? – andlrc – 2016-02-08T18:38:52.033

@dev-null oh oh oh you'r perfectly right, this is recursive. My fault. Thanks for pointing it out – edc65 – 2016-02-08T21:21:07.167

6

Pyth, 9 8

s@Lz*lzQ

Saved 1 byte thanks to Pietu1998

This takes floor(n * len(string)) letters from the string, using cyclical indexing. I believe this is always equivalent to the given formula.

Test Suite

FryAmTheEggman

Posted 2016-02-08T15:42:41.037

Reputation: 16 206

1No plz don't take this from me this soon. xD – Addison Crump – 2016-02-08T16:02:35.317

@VoteToClose I actually didn't read your answer at all, scouts honour :P I didn't even realise that string repetitions were disallowed, this was just shorter that what I came up with that way... – FryAmTheEggman – 2016-02-08T16:14:46.317

1You don't even need the second s. range is funny like that. – PurkkaKoodari – 2016-02-08T19:47:32.180

1NOO! cries in a corner Ah, oh well. – Addison Crump – 2016-02-08T19:54:42.527

4

Vitsy, 9 bytes

Expects the word as an argument, and the number to multiply by through STDIN.

zlW*\[DO{]
z          Grab all string argument input.
 l         Get the length of the stack.
  W        Parse STDIN.
   *       Multiply the top two items (length of string and the number of repetitions)
    \[   ] Do the stuff in the loop.
      DO{  Output one char at a time, making sure to duplicate first.

Try it online!

Addison Crump

Posted 2016-02-08T15:42:41.037

Reputation: 10 763

True to your word, you answered fast. – Rɪᴋᴇʀ – 2016-02-08T15:48:30.107

@RikerW Martin out FGITW'd me. – Addison Crump – 2016-02-08T15:51:11.227

Why do you Grab all string argument input. and then Parse STDIN. again? – Rɪᴋᴇʀ – 2016-02-08T16:08:13.023

@RikerW Arguments that are doubles are automatically parsed, pushing them to the stack immediately. Handling that takes more bytes than it's worth. – Addison Crump – 2016-02-08T16:09:31.987

Oh okay. That makes more sense now. – Rɪᴋᴇʀ – 2016-02-08T16:10:01.830

3

CJam, 10 bytes

l_,l~*,\f=

The string is supplied on the first line of STDIN, the float on the second.

Test it here.

Explanation

l    e# Read string.
_,   e# Duplicate and get its length.
l~   e# Read second line and evaluate.
*    e# Multiply them. If the result, N, was floored it would give us the number of
     e# characters in the required output.
,    e# Get range [0 1 ... ⌊N⌋-1].
\f=  e# For each character in that range, fetch the corresponding character from the
     e# string using cyclic indexing.

Martin Ender

Posted 2016-02-08T15:42:41.037

Reputation: 184 808

3

Python 2, 71 bytes

lambda s,x:"".join(s for i in range(int(x)))+s[:int(len(s)*(x-int(x)))]

Try it here!

Creates an unnamed lambda which takes the string as first argument and the float as second. Returns the repeated string.

This could be 46 if string repetition builtins were allowed :(

Denker

Posted 2016-02-08T15:42:41.037

Reputation: 6 639

1Much sad. Such string multiplication rules. +1 A+ for effurt. – Addison Crump – 2016-02-08T16:15:01.017

3

Ruby, 49 48 characters

->s,n{(0...(n*l=s.size).to_i).map{|i|s[i%l]}*''}

Sample run:

2.1.5 :001 > ->s,n{(0...(n*l=s.size).to_i).map{|i|s[i%l]}*''}['case', 2.5]
 => "casecaseca" 

manatwork

Posted 2016-02-08T15:42:41.037

Reputation: 17 865

3

Perl 6,  46 41  39 bytes

{([~] $^a xx$^b)~$a.substr(0,$a.chars*($b%1))}    # 46 bytes
{substr ([~] $^a xx$^b+1),0,$a.chars*$^b}         # 41 bytes
{substr ([~] $^a xx$^b+1),0,$a.comb*$b}           # 39 bytes

Perl 6 has both a string repetition operator x and a list repetition operator xx.

Since the rules disallow string repetition, we repeat it as if it was a single element list instead. Then the list gets concatenated together, and a substring of it is returned.

Usage:

# give it a lexical name
my &code = {substr ([~] $^a xx$^b+1),0,$a.chars*$^b}
#          {substr ($^a x$^b+1),0,$a.chars*$^b}

say code('test case', 1).perl;                  # "test case"
say code('case', 2.5).perl;                     # "casecaseca"
say code('(will add more later)', 0.3333).perl; # "(will "
say code('cats >= dogs', 0.5).perl;             # "cats >"

Brad Gilbert b2gills

Posted 2016-02-08T15:42:41.037

Reputation: 12 713

substr ([~] $^a xx$^b+1),0,$a.comb*$b} saves two chars – raiph – 2016-02-10T04:31:26.573

2

osascript, 173 bytes

Oh my days, this is worse than I thought.

on run a
set x to a's item 1's characters
set y to a's item 2
set o to""
set i to 1
set z to x's items's number
repeat y*z
set o to o&x's item i
set i to i mod z+1
end
o
end

Returns the value of the string, another answer using cyclical indexing. Expects input as "string" "repetitions".

Addison Crump

Posted 2016-02-08T15:42:41.037

Reputation: 10 763

Oh my days, this is worse than I thought. So true, so true. – Rɪᴋᴇʀ – 2016-02-08T16:28:23.180

Is there a multiple var set at once command? ie set x,y to a's items? – Rɪᴋᴇʀ – 2016-02-08T16:29:10.097

@RikerW I don't think so. If there is, I'm seriously missing out. – Addison Crump – 2016-02-08T16:34:37.243

2

Haskell, 44 bytes

c x=x++c x
s#n=take(floor$n*sum[1|a<-s])$c s

Usage example: "(will add more later)" # 0.3333 -> "(will ".

How it works: c concatenates infinite copies of the string x. It behaves like the built-in cycle. sum[1|a<-s] is a custom length function that works with Haskell's strict type system as it returns a Double (the built-in length returns an Int which cannot be multiplied with n). # takes floor (n * length(s)) characters from the cycled string s.

nimi

Posted 2016-02-08T15:42:41.037

Reputation: 34 639

2

PHP 5, 96 87

9 bytes saved thanks to @manatwork

<?for($i=$z=0;$i++<floor(strlen($a=$argv[1])*$argv[2]);$z++)echo$a[$z]?:$a[$z=0‌​];

Pretty straight forward looping answer.

Ungolfed

<?
$a=$argv[1];
$z=0;
for($i=0; $i < floor(strlen($a)*$argv[2]); $i++) {
    // if the string offset is not set
    // then reset $z back to 0 so we can
    // echo the beginning of ths string again
    @$a[$z] ?: $z=0;
    echo $a[$z];
    $z++;
}

Samsquanch

Posted 2016-02-08T15:42:41.037

Reputation: 271

Not sure when should that error suppression help, for me seems to work without @ too: <?for($i=$z=0;$i++<floor(strlen($a=$argv[1])*$argv[2]);$z++)echo$a[$z]?:$a[$z=0]; – manatwork – 2016-02-08T17:26:23.023

I was getting a notice on case #2 which caused the output to render incorrectly, which is when I added in the suppression. (running in CLI mode) – Samsquanch – 2016-02-08T17:30:40.467

“PHP 5.3 or later, the default value is E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED.” – error_reporting So we prefer to base our solutions on default configuration and not to care about notices and other good habits. For example ignoring the initialization of $z and $i.

– manatwork – 2016-02-08T17:37:29.380

Oh, cool. Thanks for the info! – Samsquanch – 2016-02-08T18:05:03.743

2

Perl, 51 + 3 = 54 bytes

$l=<>*y///c;for$i(1..$l){push@a,/./g}say@a[0..$l-1]

Requires: -n, -l and -M5.010 | -E:

 $ perl -nlE'$l=<>*y///c;for$i(1..$l){push@a,/./g}say@a[0..$l-1]' <<< $'test case\n1'
 test case
 $ perl -nlE'$l=<>*y///c;for$i(1..$l){push@a,/./g}say@a[0..$l-1]' <<< $'case\n2.5'
 casecaseca
 $ perl -nlE'$l=<>*y///c;for$i(1..$l){push@a,/./g}say@a[0..$l-1]' <<< $'(will add more later)\n0.3333'
 (will 
 $ perl -nlE'$l=<>*y///c;for$i(1..$l){push@a,/./g}say@a[0..$l-1]' <<< $'cats >= dogs\n0.5'
 cats >

Explanation:

$l=<>*y///c;              # Calculate output length (eg. 2.5 * input length)
for$i(1..$l){push@a,/./g} # Push a lot of chars from input into @a
say@a[0..$l-1]            # Slice @a according to output length

andlrc

Posted 2016-02-08T15:42:41.037

Reputation: 1 613

2

R, 59 bytes

function(s,l)cat(rawToChar(array(charToRaw(s),nchar(s)*l)))

As an unnamed function. This uses charToRaw to split the string into a vector of raws. This is filled into an array of length * l, converted back to char and output.
I was going to use strsplit, but it ended up being longer.

Test

> f=
+ function(s,l)cat(rawToChar(array(charToRaw(s),nchar(s)*l)))
> f('test case', 1) # -> test case
test case
> f('case', 2.5) # -> casecaseca
casecaseca
> f('(will add more later)', 0.3333) # -> (will(space)
(will 
> f('cats >= dogs', 0.5) # -> cats >
cats >
> 

MickyT

Posted 2016-02-08T15:42:41.037

Reputation: 11 735

1

c (preprocessor macro), 71

j,l;
#define f(s,m) l=strlen(s);for(j=0;j<(int)(l*m);)putchar(s[j++%l])

Not much tricky here. Just need to make sure l*m is cast to an int before comparing to j.

Try it online.

Digital Trauma

Posted 2016-02-08T15:42:41.037

Reputation: 64 644

1

Oracle SQL 11.2, 154 152 bytes

WITH v(s,i)AS(SELECT SUBSTR(:1,1,FLOOR(FLOOR((:2-FLOOR(:2))*LENGTH(:1)))),1 FROM DUAL UNION ALL SELECT :1||s,i+1 FROM v WHERE i<=:2)SELECT MAX(s)FROM v;

Un-golfed

WITH v(s,i) AS
(
  SELECT SUBSTR(:1,1,FLOOR(FLOOR((:2-FLOOR(:2))*LENGTH(:1)))),1 FROM DUAL 
  UNION ALL 
  SELECT :1||s,i+1 FROM v WHERE i<=:2
)
SELECT MAX(s) FROM v;

I went the recursive way, with the initialisation select taking care of the decimal part.

Saved 2 bytes thanks to @MickyT

Jeto

Posted 2016-02-08T15:42:41.037

Reputation: 1 601

You can save a couple by removing spaces after the ) in the WITH clause and the final select. – MickyT – 2016-02-08T19:44:23.043

Another saving would be to replace FLOOR(FLOOR((:2-FLOOR(:2))*LENGTH(:1))) with MOD(:2,1)*LENGTH(:1) – MickyT – 2016-02-08T20:56:37.743

And one last one :), you can use LPAD rather than SUBSTR – MickyT – 2016-02-08T21:07:07.430

1

Seriously, 24 bytes

,╗,mi@≈╜n╜l(*≈r`╜E`MΣ)kΣ

Try it online!

Explanation:

,╗,mi@≈╜n╜l(*≈r`╜E`MΣ)kΣ
,╗                        get first input (string) and push it to register 0
  ,mi@≈                   get input 2 (x), push frac(x) (f), int(x) (n)
       ╜n                 push n copies of the string
         ╜l(*≈            push length of string, multiply by f, floor (substring length) (z)
              r`╜E`MΣ     push s[:z]
                     )kΣ  move fractional part of string to bottom, concat entire stack

Mego

Posted 2016-02-08T15:42:41.037

Reputation: 32 998

1

Pyth, 9 bytes

V*Elzp@zN

Basically just doing

             z = input()
V*Elz        for N in range(evaluatedInput()*len(z)):    # flooring is automatic
     p@zN        print(z[N], end="")                     # modular indexing

busukxuan

Posted 2016-02-08T15:42:41.037

Reputation: 2 728