2
\$\begingroup\$

Challenge description

Multiplification (totally not a made-up word) is a process in which you take two positive integers: a and b, and produce another integer which is equal to a repeated ("glued together") b times. For example, multiplifying 3 by 7 gives 3333333. Similarly, 103 multiplified by 5 is 103103103103103.

In this challenge, given two positive integers a and b, output a multiplified by b. The catch is, you can't use string operations to generate the number - it has to be done in a purely mathematical way. You may only use operators for addition (+), subtraction (-), multiplication (*), integer division (/, //, div), modulo operation (%, mod) and binary operations (&, ^, |, <<, >> etc.). It's not possible to do in every language, since it has to support arbitrary precision integers.

Sample inputs / outputs

10, 4   | 10101010
3, 9    | 333333333
3737, 2 | 37373737
993, 1  | 993
8888, 8 | 88888888888888888888888888888888
\$\endgroup\$
19
  • \$\begingroup\$ Can I convert to digit list, then concatenate, then convert back to number? \$\endgroup\$
    – Leaky Nun
    Aug 10, 2016 at 9:02
  • \$\begingroup\$ Yes, but you can't directly concatenate digits, like [3, 2] -> 32 unless you do it mathematically, that is for example 3*10 + 2. The point is not to use string operations. \$\endgroup\$
    – shooqie
    Aug 10, 2016 at 9:04
  • \$\begingroup\$ Is this your ideal solution? \$\endgroup\$
    – Leaky Nun
    Aug 10, 2016 at 9:07
  • 8
    \$\begingroup\$ This falls into one of the classic traps of Do X without Y: it's written assuming that all languages are C-like and so prohibits other languages unnecessarily. E.g. CJam is banned because it would require a duplication operator to have one copy of a to count its length and another to multiply by the corresponding g.p. \$\endgroup\$ Aug 10, 2016 at 10:40
  • 4
    \$\begingroup\$ Unfortunately, although the intentions of this challenge are good, I'd like to point out that in general "Do X without Y" challenges are hard to get right. Golfing often invites one to find loopholes in the rules, but in this case the line between what is and what isn't allowed can get a bit fuzzy. \$\endgroup\$
    – Sp3000
    Aug 10, 2016 at 11:23

11 Answers 11

3
\$\begingroup\$

Python 2, 48 bytes

c,n=input();a=1
while n/a:a*=10
print a**c/~-a*n

Arithmetic!

Take number n and repetition count c. First, computes a=10**num_digits(n) as the smallest power of 10 above a. Then, the floor division a**c/(a-1) gives a number of the form 1001001001001 with c ones, spaced apart by the digit-length of n. Multiplying by n then replaces each 1 with n, giving c concatenated copies of n.

A same-length recursive version:

f=lambda c,n,a=10:a**c/~-a*n*(a>n)or f(c,n,a*10)

This one has to start at a=10 because a=1 causes a division-by-zero error.

\$\endgroup\$
1
  • \$\begingroup\$ Nice, pretty much the same what I came up with, except I wasn't sure how to go about golfing log10(a) \$\endgroup\$
    – shooqie
    Aug 10, 2016 at 9:28
2
\$\begingroup\$

Brachylog, 9 bytes

jL,?h:.cL

Try it online!

Explanation

The j operator concatenates the first thing in an array to itself as many times as the second thing in the array.

In other words, [10:2] would produce 101010.

This operator uses integer in the implementation so is completely usable.

However, it is one concatenation too many.

Therefore, we use the ability of Brachylog to prove things to deal with this:

jL,?h:.cL
jL          input after being treated by the j operator yields L
  ,         and
   ?h:.cL   first element of input concatenated with output is L
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Why the downvotes? \$\endgroup\$ Aug 10, 2016 at 10:46
2
\$\begingroup\$

Java 8 lambda, 268 characters

Arbitrary precision ruins everything, here are the BigIntegers:

import static java.math.BigInteger.*;import java.math.BigInteger;(a,b)->{BigInteger r=ZERO;int d=(int)(Math.log(2)/Math.log(10)*a.bitLength()+1);if(TEN.pow(d-1).compareTo(a)>0)d--;while((b=b.subtract(ONE)).compareTo(ZERO)>=0)r=r.multiply(TEN.pow(d)).add(a);return r;}

And here the ungolfed version:

import java.math.BigInteger;

import static java.math.BigInteger.*;

public class Q89322 {

    static BigInteger expand(BigInteger a, BigInteger b) {
        BigInteger result = ZERO;

        int digitCount = (int) (Math.log(2) / Math.log(10) * a.bitLength() + 1);
        if (TEN.pow(digitCount - 1).compareTo(a) > 0) {
            digitCount--;
        }
        while ((b = b.subtract(ONE)).compareTo(ZERO) >= 0) {
            result = result.multiply(TEN.pow(digitCount)).add(a);
        }
        return result;
    }
}

I hope that logarithm is also counted as a valid mathematical operation :)

Getting the digits of the BigIntegers powered by this guy. With only int or long this could be way shorter :/

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

Haskell, 38 bytes

n%c|a<-until(>n)(*10)1=n*div(a^c)(a-1)

Everyone forgets about until!

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

PHP, 105 139 136 134 bytes

function m($a,$b){$s=$x=$a;for($f=10;$x>9;$x=bcdiv($x,10))$f=bcmul($f,10);for(;$b=bcsub($b,1);)$s=bcadd($s,$a=bcmul($a,$f));return$s;}

arbitrary precision needs some room in PHP, but I´ll look if I can shrink this a bit.

\$\endgroup\$
3
  • \$\begingroup\$ I'm quite sure log10 doesn't have arbitrary precision. \$\endgroup\$
    – Leaky Nun
    Aug 10, 2016 at 9:35
  • \$\begingroup\$ @LeakyNun: log10 does not, true. But a=1e+xx is sufficient to get an exact length of a unless xx is greater than INT_MAX. I assume that a does not have that many digits, so I spare the code to implement bclog10 or add a bcmul or bcdiv loop. \$\endgroup\$
    – Titus
    Aug 10, 2016 at 9:44
  • \$\begingroup\$ oh ... no log, no pow allowed ... back to the editor. \$\endgroup\$
    – Titus
    Aug 10, 2016 at 9:55
0
\$\begingroup\$

Python, 65 bytes

f=lambda x,n,p=1:p<=x and f(x,n,p*10)or n and f(x,n-1,p)*p+x or 0

Ideone it!

First recursion to find the power, second recursion to complete the "concatenation".

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

Pyth, 7 bytes

i*jQTET

Test suite.

Convert to digit list, repeat for that many times, then convert to number.

i*jQTET  Q: first input, E: second input
  jQT    convert Q to base T (10) as a digit list
 *   E   repeat for E many times
i     T  convert from digit list to number
\$\endgroup\$
2
  • \$\begingroup\$ Why the downvotes? \$\endgroup\$ Aug 10, 2016 at 10:46
  • \$\begingroup\$ @VTCAKAVSMoACE Salt-votes lol \$\endgroup\$
    – Leaky Nun
    Aug 10, 2016 at 10:46
0
\$\begingroup\$

JavaScript (ES7), 43 bytes

f=(a,b,c=1)=>c>a?(c**b-1)/~-c*a:f(a,b,c*10)

Works up to f(9000,4). (Looks like I rediscovered @xnor's formula.) 56-byte ES6 version or 52-byte ES6 version with an even smaller range:

f=(a,b,c=0,d=0)=>c<a?f(a,b,c*10+9,d*(b='1e'+b)+--b):d/c*a
f=(a,b,c=1,d=1)=>c>a?~-d/~-c*a:f(a,b,c*10,d*='1e'+b)
\$\endgroup\$
0
\$\begingroup\$

Jelly, 3 bytes

DẋḌ

Try it online!

DẋḌ  Main chain, argument: x,y
D    Convert x to list of digits
 ẋ   repeat y times
  Ḍ  Convert back to number
\$\endgroup\$
-1
\$\begingroup\$

Common Lisp, 73 bytes

(lambda(a b)(loop for x below b sum(*(expt 10(*(ceiling(log a 10))x))a)))
\$\endgroup\$
-1
\$\begingroup\$

k, 20 bytes

Same idea as Pyth solution.

Only supports up to 64 bit signed int range.

{10/:(y*#d)#d:10\:x}

Example

k){10/:(y*#d)#d:10\:x}[103;2]
103103
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.