Operator that combines sum, product and difference between two numbers

28

4

Challenge:

There's a silly puzzle circulating on social networks that reads:

8 + 2 = 16106
5 + 4 = 2091
9 + 6 = ?

Implement a function or operator that, when given two positive integer numbers x and y such that x > y > 0, yields the correct answer as an integer, where the answer's digits are the digits of x * y followed by the digits of x + y followed by the digits of x - y. Very simple.

Rules:

  • Standard loopholes are disallowed.
  • This is so shortest code in bytes wins.
  • Input data validation is not required. This program may crash or return garbage when given invalid input.
  • You're allowed to use numeric functions and operators (including integer and floating point, math library functions, and other functions that accept and return numbers).
  • You're allowed to use a function that returns the number of digits of a number, if applicable.
  • You're not allowed to use strings or any kind of concatenation anywhere in your code.
  • The result may be returned or pushed to the stack, whichever applies in the language. The result must be an integer number, not a string.

Sample code:

Dyalog APL:

The following code creates a dyadic operator named X.

X←{(⍺-⍵)+((⍺+⍵)×10*1+⌊10⍟⍺-⍵)+⍺×⍵×10*(2+⌊10⍟⍺+⍵)+⌊10⍟⍺-⍵}

Explanation:

  • In APL, you evaluate from right to left.

  • ⍺ and ⍵ are the left and right operand, respectively

  • ⌊10⍟⍺-⍵ reads: floor of log10(⍺-⍵). First performs substraction then logarithm then floor. From right to left. log10 is done in order to count the digits of ⍺-⍵ (you must sum 1 afterwards).

  • ⍺×⍵×10*(...) reads: 10 to the (...)th power, multiplied by ⍵, multiplied by ⍺

  • Hence, ⍺×⍵×10*(2+⌊10⍟⍺+⍵)+⌊10⍟⍺-⍵ is the product, shifted to the left by the sum of the number of digits of the sum and the difference. Multiplying by a power of 10 will shift an integer to the left.

  • ((⍺+⍵)×10*1+⌊10⍟⍺-⍵) is the sum, shifted to the left by the number of digits of the difference.

  • (⍺-⍵) is the difference. No shifting is necessary here.

  • X←{...} is how you define an operator in APL.

Examples:

      8 X 2
16106
      5 X 4
2091
      9 X 6
54153

GNU dc:

The following code creates a macro named a:

[sysx10lxly-dseZdsclxly+dsd+Z1+^lxly**10lc^ld*+le+]sa

Explanation:

  • sx and sy pop an element from the stack and save it on the registers x and y, respectively.

  • lx and ly load an element from registers x and y respectively and push it to the stack.

  • d duplicates the last element in the stack.

  • ^ computes the power of two numbers.

  • Z pops a number and returns its number of digits. This is done because dc has no logarithm function.

  • [...]sa stores a macro in register a. la loads it. x executes the macro at the top of the stack.

Examples:

8 2 laxn
16106
5 4 laxn
2091
9 6 laxn
54153

Locoluis

Posted 2017-04-05T22:22:26.353

Reputation: 741

I assume conversion from integer to string is invalid? – Anthony Pham – 2017-04-05T23:56:47.807

2I think we've had a challenge much like this but don't know what terms would find the dupe. – xnor – 2017-04-05T23:58:51.577

2@AnthonyPham "You're not allowed to use strings or any kind of concatenation anywhere in your code." – ASCII-only – 2017-04-06T02:01:32.173

1Can we take a pair of integers as input? – Conor O'Brien – 2017-04-06T02:58:21.367

1Can I make a full program instead of a function? – Erik the Outgolfer – 2017-04-06T14:08:04.987

@Locoluis - Does appending integer arrays violate your rule against "any kind of concatenation"? What I'm effectively doing is taking one integer array 2 4 8 and appending another 3 5 to create 2 4 8 3 5 in my answer. – Dane – 2017-04-13T21:24:19.727

'No strings or concatenation' is a non-observable rule, as such, it's highly discouraged in a challenge. – ATaco – 2017-04-20T04:37:28.557

Does strlen qualify as "a function that returns the number of digits of a number"? There´s an implicit typecast which I cannot avoid; and I doubt that there is any language who has an explicit count_digits function. Also, printing a result implies a typecast to string ... So if strlen should be banned, printing is at least questionable. – Titus – 2017-04-20T13:11:13.987

Answers

10

JavaScript (ES7), 63 61 59 bytes

Saved 4 bytes thanks to Neil.

(a,b)=>[a*b,a+b,a-b].reduce((p,c)=>p*10**-~Math.log10(c)+c)

<input id=a type=number oninput="c.innerText=((a,b)=>[a*b,a+b,a-b].reduce((p,c)=>p*10**-~Math.log10(c)+c))(+a.value,+b.value)">
<input id=b type=number oninput="c.innerText=((a,b)=>[a*b,a+b,a-b].reduce((p,c)=>p*10**-!Math.log10(c)+c))(+a.value,+b.value)">
<p id=c>

ASCII-only

Posted 2017-04-05T22:22:26.353

Reputation: 4 687

Save a few bytes using 10**-~Math.log10(c). (But +1 for using reduce, of course.) – Neil – 2017-04-06T09:11:33.737

"ES7" Oh, for the love of coding... They're making another one? – Feathercrown – 2017-04-07T14:12:28.587

@Feathercrown Yeah, but is it really worse than hearing "Java 9"? Plus it has useful things like async/await and the exponentiation operator ** – ASCII-only – 2017-04-07T14:13:54.990

@ASCII-only ** is really useful, I agree. That should've been in ES6. – Feathercrown – 2017-04-07T14:17:06.017

8

C, 79 75 bytes

Thanks to @G B for saving 4 bytes!

#define X for(c=1;(c*=10)<=a
c,d;f(a,b){X+b;);d=c*a*b+a+b;X-b;);a=d*c+a-b;}

Try it online!

Steadybox

Posted 2017-04-05T22:22:26.353

Reputation: 15 798

6

Bash, 66

  • 2 bytes saved thanks to @chepner.
f()(s=$[$1+$2]
d=$[$1-$2]
echo $[($1*$2*10**${#s}+s)*10**${#d}+d])

Try it online.

Digital Trauma

Posted 2017-04-05T22:22:26.353

Reputation: 64 644

It is possible to make this almost two times shorter if you place your variables(s, d and the other one for multiplication that you didn't define) next to each other and evaluate that as an arithmetic expression. – Maxim Mikhaylov – 2017-04-06T02:22:17.930

3@MaxLawnboy Yes, though that sounds a lot like the banned string concatenation to me. – Digital Trauma – 2017-04-06T02:28:44.153

1Identifier names inside $[...] are subject to parameter expansion without the explicit $ (e.g., d instead of $d), saving two characters. – chepner – 2017-04-07T01:12:14.687

@chepner yep - thanks - I'd missed those. – Digital Trauma – 2017-04-07T01:20:52.873

Found another two; use ((s=$1+$2,d=$1-$2)) to intialize the two variables. – chepner – 2017-04-07T01:23:03.777

5

EXCEL, 61 Bytes

=A1-B1+(A1+B1)*10^LEN(A1-B1)+A1*B1*10^(LEN(A1-B1)+LEN(A1+B1))

Excel, 18 Bytes not valid

=A1*B1&A1+B1&A1-B1

Jörg Hülsermann

Posted 2017-04-05T22:22:26.353

Reputation: 13 026

5

Stacked, 36 bytes

,@A$(*+-){!A...n!}"!{%y#'10\^x*y+}#\

Try it online!

Previously: ,@A$(-+*){!A...n!}"!:inits$#'"!$summap:pop@.10\^1\,\*sum

I'm going to try to squeeze out a byte or two before writing an explanation. (#' = size of, and " is "do on each", no strings attached here.)

Noncompeting at 26 bytes: $(*+-)#!!:{%y#'10\^x*y+}#\.

Conor O'Brien

Posted 2017-04-05T22:22:26.353

Reputation: 36 228

5

TI-Basic, 34 33 bytes

Prompt A,B
A-B+(A+B)10^(1+int(log(A-B
Ans+AB10^(1+int(log(Ans

pizzapants184

Posted 2017-04-05T22:22:26.353

Reputation: 3 174

I think Prompt A,B should also work – Conor O'Brien – 2017-04-06T02:56:09.790

@ConorO'Brien You're right! – pizzapants184 – 2017-04-06T04:46:32.053

4

GNU dc, 36

Defines a macro m that takes the top two members of the stack, applies the macro and leaves the result on the stack (as per the example in the question):

[sadsbla-dZAr^lalb+*+dZAr^lalb**+]sm

Try it online.

Digital Trauma

Posted 2017-04-05T22:22:26.353

Reputation: 64 644

3

Perl 6,  81 61  58 bytes

->\x,\y{($/=($/=x- y)+(x+y)*({10**$++}...*>$/).tail)+x*y*({10**$++}...*>$/).tail}

Try it

->\x,\y{(x*y,x+y,x- y).reduce:{$^a*10**Int(1+log10($^b))+$b}}

Try it

->\x,\y{[[&({$^a*10**Int(1+$^b.log10)+$b})]] x*y,x+y,x- y}

Try it

Brad Gilbert b2gills

Posted 2017-04-05T22:22:26.353

Reputation: 12 713

Not knowing Perl 6, I was slightly surprised to discover that x-y is a valid identifier. – Neil – 2017-04-06T09:18:45.550

3

Jelly, 27 bytes

+,ạ,.1Fl⁵Ḟ‘€Ṛ+\⁵*
ạ,+,×Fæ.ç

Defines a dyadic link / function, callable with ç. Takes two integers as input and returns an integer. It has the added bonus of being able to take x<y or x>y by using absolute difference.

Try it online!

Explanation:

+,ạ,.1Fl⁵Ḟ‘€Ṛ+\⁵* -- Create link which computes what order of magnitude
                        to multiply the difference, sum, and product by
ạ,+,×Fæ.ç         -- Main link, applies this using dot product

Details:

+,ạ,.1Fl⁵Ḟ‘€Ṛ+\⁵* -- Create dyadic like which does the following:
       l⁵Ḟ‘       -- Create operation which computes number of digits
                       (log base 10 (⁵ is the literal 10), floored, incremented)
           €      -- Apply this to each element in
+,ạ,.1F           -- ... the list [sum,difference,.1]
            R     -- Reverse the list
             +\   -- Add up first n elements to get list.
               ⁵* -- Raise 10 (⁵ is literal 10) to the power of each element

ạ,+,×Fæ.ç         -- Main link, applies above link
ạ,+,×F            -- The list [difference, sum, product]
      æ.          -- Dot product (multiply corresponding elements) with
        ç         -- The above link.

fireflame241

Posted 2017-04-05T22:22:26.353

Reputation: 7 021

2

PHP, 79 75 bytes

two versions:

[,$a,$b]=$argv;echo(10**strlen($s=$a+$b)*$a*$b+$s)*10**strlen($d=$a-$b)+$d;
[,$a,$b]=$argv;echo(10**strlen($a+$b)*$a*$b+$a+$b)*10**strlen($a-$b)+$a-$b;

takes input from command line arguments; run with -r.

I guess strlen qualifies as "function that returns the number of digits",
although it uses the number as a string. Let me know if not.

Titus

Posted 2017-04-05T22:22:26.353

Reputation: 13 814

'You're not allowed to use strings or any kind of concatenation anywhere in your code.', so I don't think strlen is valid. – numbermaniac – 2017-04-20T07:45:52.693

@numbermaniac Let the OP decide. Imo the restriction was to force the solutions to create one result instead of just printing three results after each other. Everything beyond that is nitpicking. – Titus – 2017-04-20T13:17:47.167

2

C (gcc), 70 bytes

#define _ for(c=1;a+b>=(c*=10););d=c*d+a-(b=-b);
c,d;f(a,b){d=a*b;_ _}

Try it online!

based on Steadybox answer, putting everything in a macro to golf it a little more.

(Note: assigning the result to d instead of a works, unexpectedly. I had a look at the generated assembly code and it seems to be ok.)

G B

Posted 2017-04-05T22:22:26.353

Reputation: 11 099

2

Haskell, 54 bytes

a%0=a
a%b=10*a%div b 10+mod b 10
a#b=(a*b)%(a+b)%(a-b)

The puzzle is implemented via an infix function #, e.g. 8#2 = 16106. The other function, %, defines base-10 concatenation (assuming the RHS is greater than 0).

nitrous

Posted 2017-04-05T22:22:26.353

Reputation: 81

2

Dyalog APL, 31 bytes

{a⊥⍨10*1+⌊10⍟a←(⍺×⍵)(⍺+⍵)(⍺-⍵)}

based on the sample APL code from the problem statement

ngn

Posted 2017-04-05T22:22:26.353

Reputation: 11 449

1

PHP, 87 Bytes

[,$a,$b]=$argv;echo($s=$a-$b)+($t=$a+$b)*10**($l=strlen($s))+$a*$b*10**($l+strlen($t));

and a not valid solution for 37 Bytes

[,$a,$b]=$argv;echo$a*$b,$a+$b,$a-$b;

Jörg Hülsermann

Posted 2017-04-05T22:22:26.353

Reputation: 13 026

1

Ruby, 61 bytes

->a,b{[a*b,a+b,a-b].reduce{|x,y|z=y;x*=10while(z>z/=10);x+y}}

Which suspiciously looks a lot like this Javascript answer, but without using a logarithm.

G B

Posted 2017-04-05T22:22:26.353

Reputation: 11 099

1

R (3.3.1), 104 bytes

function(x,y)Reduce(function(p,q)p*10^(floor(log10(q)+1))+q,lapply(c(`*`,`+`,`-`),function(z)z(x,y)),0)

returns an anonymous function.

This is my first golfing attempt, so any feedback is appreciated.

Giuseppe

Posted 2017-04-05T22:22:26.353

Reputation: 21 077

1I'd say to try to avoid defining functions via the reserved word 'function' if at all possible, it uses up a lot of bytes. Just do the computation. – user11599 – 2017-04-21T05:18:12.710

1

Python, 92 91 Chars

def g(x,y):
    l=lambda x,i=0:l(x/10,i+1)if x else 10**i
    a=x-y
    a+=(x+y)*l(a)
    return x*y*l(a)+a

Thanks to Wizards suggestion;)

Hermen

Posted 2017-04-05T22:22:26.353

Reputation: 31

Welcome to the site! You don't need the space between ) and if. – Post Rock Garf Hunter – 2017-04-06T17:40:36.467

0

REXX, 70 bytes

f:arg a b
c=a-b
c=(a+b)*10**length(c)+c
c=a*b*10**length(c)+c
return c

Of course, the native way would be much shorter:

f:arg a b
return a*b||a+b||a-b

idrougge

Posted 2017-04-05T22:22:26.353

Reputation: 641

0

Python 2.7, 109 96 bytes

import math
a=lambda n:10**int(math.log10(10*n))
b,c=input()
d=b-c+(b+c)*a(b-c)
print d+b*c*a(d)

Corrected after following rules of contest. Credits to mbomb007 for bringing down the code from 109 bytes to 96 bytes

Koishore Roy

Posted 2017-04-05T22:22:26.353

Reputation: 1 144

1From the rules of this challenge -- •You're not allowed to use strings or any kind of concatenation anywhere in your code. – AdmBorkBork – 2017-04-06T12:56:41.460

You can save some bytes by making a a lambda. a=lambda n:10**int(.... You can also do b,c=input(), giving your two inputs separated by a comma. – mbomb007 – 2017-04-06T14:34:44.793

@mbomb007 b,c=input() gives TypeError: 'int' object is not iterable. I've tried it. And the lambda function won't save bytes because I'm calling the function twice in the code. tried that too. :( – Koishore Roy – 2017-04-06T14:53:12.117

@KoishoreRoy I don't think you get what I mean. 96 bytes

– mbomb007 – 2017-04-06T15:20:53.673

0

PowerShell, 88 Bytes

param($x,$y)$l=2;if(($a=$x+$y)-gt9){$l++};($x*$y)*[math]::Pow(10,$l)+$a*10+$x-$y

PowerShell does not have a to the power operator which does not help. Also can't count the length of an integer unless you count it as a string, which we can not do, so I check to see if it is -gt 9 to get know the length. Likely could be more terse but I have to get back to work.

Matt

Posted 2017-04-05T22:22:26.353

Reputation: 1 075

0

J, 25 bytes

X=.10#.[:;10#.inv&.>*;+;-
  1. *;+;- Box the results of each operation.
  2. 10#.inv&.> Convert each result into an array of base-10 digits. (inv is ^:_1)
  3. [:; Unbox and join the arrays.
  4. 10#. Convert array of base-10 digits into an integer.
  5. X=. define the above as the operator X.

Results:

   8 X 2
16106
   5 X 4
2091
   9 X 6
54153

Dane

Posted 2017-04-05T22:22:26.353

Reputation: 291

You don't need X=. – Cyoce – 2017-04-07T18:28:02.543

@Cyoce - the sample APL code in the challenge defines an operator. I'm pretty sure we're supposed to define a reusable operator for this challenge. – Dane – 2017-04-07T18:54:02.893

"3. [:; Unbox and join the arrays." - "You're not allowed to use strings or any kind of concatenation anywhere in your code." – ngn – 2017-04-13T07:15:41.333

@ngn - Please expand on your comment. At no point are strings used. – Dane – 2017-04-13T16:57:44.417

I just wanted to point out that "join" ("link"?) might constitute a "kind of concatenation", though I'm not very familiar with J, and I'm not sure how to interpret the problem statement in this case. My own solution raises similar questions - I use stranding (juxtaposition of nouns in APL forms a vector) which might be the same as J's "link" but without a glyph to represent it. – ngn – 2017-04-13T19:36:33.330

Ahh. Interesting read of "any kind of concatenation." I suppose we should ask the challenge creator. What I'm effectively doing is taking one integer array 2 4 8 and appending another 3 5 to create 2 4 8 3 5. – Dane – 2017-04-13T21:22:33.903

Any reason you use^:_1 in your solution butinv in your explanation? – Cyoce – 2017-04-19T07:27:15.837

Typo. I messed up somewhere in my edits. 25 bytes is a count with inv. – Dane – 2017-04-20T01:38:08.313

0

Mathematica, 67 bytes

c=Ceiling;l=Log10;#-#2+(#+#2)10^(c@l[#-#2]/. 0->1)+10^c@l[2#]10#2#&

Takes x-y, then takes the log10 of x-y, rounds it up, calculates 10 to the power of that and then multiplies it by x+y. But we also need to consider log10(x-y) being 0, so we replace 0 with 1. Then we take the log10 of 2x, rounded up, plus 1, and find 10 to the power of that. Multiply that by xy, and add that on.

numbermaniac

Posted 2017-04-05T22:22:26.353

Reputation: 639

0

05AB1E, 23 22 16 bytes

-Dg°¹²+*Dg°¹²**O

Try it online!

We could have saved a few bytes if we'd been allowed to use strings in the program (but not in calculations) by looping over a string containing the operations "-+*", as the code performed for each operation is the same.
Of course, if we'd been allowed to use concatenation we'd saved a lot more.

Emigna

Posted 2017-04-05T22:22:26.353

Reputation: 50 798

0

R, 64 bytes

x=scan();(b=(a=diff(-x))+10^nchar(a)*sum(x))+10^nchar(b)*prod(x)

Usage:

> x=scan();(b=(a=diff(-x))+10^nchar(a)*sum(x))+10^nchar(b)*prod(x)
1: 8 2
3: 
Read 2 items
[1] 16106

user11599

Posted 2017-04-05T22:22:26.353

Reputation: 191