29
\$\begingroup\$

There have been many "Do __ without __" challenges before, but I hope that this is one of the most challenging.

The Challenge

You are to write a program that takes two natural numbers (whole numbers > 0) from STDIN, and prints the sum of the two numbers to STDOUT. The challenge is that you must use as few + and - signs as possible. You are not allowed to use any sum-like or negation functions.

Examples

input

123
468

output

591

input

702
720

output

1422

Tie Breaker: If two programs have the same number of + and - characters, the winner is the person with fewer / * ( ) = . , and 0-9 characters.

Not Allowed: Languages in which the standard addition/subtraction and increment/decrement operators are symbols other than + or - are not allowed. This means that Whitespace the language is not allowed.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Perhaps this challenge was a lot easier than I thought it would be, especially in other languages, where there are sum() functions. I have to fix this. \$\endgroup\$
    – PhiNotPi
    Dec 1, 2011 at 0:45
  • 3
    \$\begingroup\$ Just to clarify, this challenge does not care about code length right? Only the number of +,- and tie breaker characters? ...or do you need to change the rules again :-) \$\endgroup\$
    – Tommy
    Dec 1, 2011 at 19:39
  • \$\begingroup\$ @Tommy No, it does not. \$\endgroup\$
    – PhiNotPi
    Dec 1, 2011 at 21:58
  • 2
    \$\begingroup\$ Are languages allowed that don't have arithmetic operators at all? I think that last sentence permits them, but it's not completely clear. \$\endgroup\$ Aug 1, 2018 at 15:39
  • 2
    \$\begingroup\$ Next challenge would be "Comparing two numbers without any of ><+-*/%&|" \$\endgroup\$
    – Naruyoko
    Sep 19, 2019 at 23:41

75 Answers 75

2
\$\begingroup\$

Python 3

import numpy as n;i=lambda:n.e**int(input());print(int(n.log(i()*i())))

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I was trying to remove the log and e but forgot about the original restrictions... :( Reverted now. \$\endgroup\$
    – Hunaphu
    Sep 20, 2019 at 15:12
  • \$\begingroup\$ Okay it's working now. You should probably include the link in your answer: Try it online! \$\endgroup\$
    – Grimmy
    Sep 20, 2019 at 15:13
  • \$\begingroup\$ Welcome! Please consider adding an explanation or a link to an online interpreter. Code-only answers tend to be automatically flagged as low-quality. \$\endgroup\$
    – mbomb007
    Sep 20, 2019 at 15:43
2
\$\begingroup\$

Gol><>, 8 bytes

IRmIRmlh

Minus one byte!, I figured out that I didn't need to take both inputs first

Try it online!

Previous answer, 9 bytes

IIRfrRflh

Explanation below

II        take both inputs
  Rm      Pop and repeat that number of times, pushing -1
    r     Reverse stack (to get the first num on top)
     Rm   Pop and repeat that number of times, pushing -1
       lh Push length of stack, and output as a number halting

Basically what I did was count it all out in unary, it would only take a few more bytes to expand it to be able to handle more than two numbers

Try it online!

\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 48 bytes, 12 tie-breakers

a=>b=>"0".repeat(a).concat("0".repeat(b)).length
\$\endgroup\$
2
\$\begingroup\$

Zsh, 26 25 bytes, 7 5 tiebreakers

-1 byte, -2 tiebreakers thanks to @Nahuel Fouilleul.

set {1..$1} {1..$2}
<<<$#

Try it online!


Zsh, 62 60 bytes, 0 tiebreakers

-2 bytes because repeat foo evaluates foo in arithmetic mode.

read a b
{repeat a;printf x;repeat b;printf x}|read x
<<<$#x

Try it online!

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

JavaScript, 26 bytes

Tiebreakers: 11?

a=>b=>Math.log2(2**a*2**b)

Takes input as (a)(b). Uses the power index rule \$a^{x+y}=a^{x}a^{y}\$ and returns the \$log_2(2^{a}2^{b})\$ which is basically \$log_2(2^{a+b}) = a+b\$.

\$\endgroup\$
2
\$\begingroup\$

Pip, 0 +/-, 0 tiebreakers (5 bytes)

#JoXg

Try it online!

Explanation

A string-concatenation approach:

    g  List containing the command-line args
  oX   For each arg, make a string of that many 1s (o is a variable preinitialized to 1)
 J     Join the list into a single string
#      Get its length
\$\endgroup\$
2
\$\begingroup\$

Python 2, 0 +/-, 2 tie-breaker (144 bytes)

exec`["%c"%[ord(i)^True<<True<<True<<True][False]for i in"""xzaf| :""afx}| !":""afx}| !'':!&ja|Wdmfo|` !"""]`[True<<True::True<<True<<True|True]

Try it online!

How it works :

The general idea is to remove tie-breaker character of a non cheaty working solution. To do that I converted a solution by changing the 5th bit of each character.

Some tricks are used to avoid using tiebreaker character during the translation :

  • True and False are evaluated by python as 1 and 0. Using that I can easyly create some usefull integers like 2, 5 and 8 in my solution without using [0-9]
  • Parenthesis are bad (for this challenge at least). To replace them I used [expression][False] which return the first element of an 1-element array, using the []-priority over other operators.
  • To join an array of char, the common technique is to use "".join(my_array) but it uses 3 tie-breakers. I instead uses `my_array`[2::5] which take the representation of the array and select only the wanted character by concatenating them.
  • To get the ascii character from its interger representation, intead of using the built-in chr(i) (which uses 2 tie-breaker), I used "%c"%i wich does the same

In better understandable python, here is my solution :

exec`["%c"%(ord(i)^8)for i in""" CODED_SOLUTION """]`[2::5]

with CODED_SOLUTION once decoded :

print(2*input()*2**input()//2).bit_length()

which looks like my older solution (and which doesn't use any form of addition :p)

Older Solution (7 tiebreaker, 50 bytes)

print int.bit_length(True<<input()<<input()>>True)

Try it online!

The idea is to shift a True interpreted as 1 by python Xtimes and Ytimes then shift once the other way and take the len of the binary representation

Cheated solution (45 bytes, 6 Tie-breaker)

I also have a cheated solution in 45 bytes:

print eval("\x2binput()"*[True<<True][False])

Try it online!

which evaluates the string +input()+input() but convert the char + by its hexadecimal representation.

the [True<<True][False] is equal to 2

Other Ideas:

I had the idea to use a=abs(~a) to increment a by 1 but I didn't totaly managed to produce a working solution with that.

\$\endgroup\$
2
\$\begingroup\$

Python 3, 0 +/-, 2 Tie-breaker, (68 bytes)

lambda x,y:A[f"{True<<x<<y:b}"[True:]]
class A:__class_getitem__=len

Try it online!

class A:__class_getitem__=len allows me to replace len(x) by A[x]

Old, 3 Tie-breaker, (40 bytes)

lambda x,y:len(f"{True<<x<<y:b}"[True:])

Try it online!

Explanation :

  • Truein python is evaluated as 1 => 1
  • shift x times then y times => 4 => 32 (for x=2 and y=3)
  • convert it to its string binary representation => "100000"
  • remove the first char of the string => "00000"
  • get the length => 5
\$\endgroup\$
1
\$\begingroup\$

Clojure (44 chars)

(pr(#(count(concat(%)(%)))#(repeat(read)0)))

Edit: fixed to print on STDOUT instead of just returning sum.

\$\endgroup\$
1
  • \$\begingroup\$ +/- and above mentioned tie-breakers are interesting, not characters. \$\endgroup\$ May 30, 2012 at 3:39
1
\$\begingroup\$

D

main(){
    int a,b;
    readf("%d %d",&a,&b);
    write((new int[a]~new int[b]).length);
}

this time using array lengths

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

Scala

  • score:
    • +- : 0
    • (). : 5+5+3=13

Code:

(List.fill (readInt) (1) ::: List.fill (readInt) (2)).size
  • List.fill (4)(7) produces List (7, 7, 7, 7)
  • a ::: b concatenates 2 Lists into one
  • The rest should be obvious
\$\endgroup\$
1
\$\begingroup\$

K, 11

{#,[!x;!y]}

Same concatenation trick as the R solution. Reading right to left: Enumerate the two input variables, concatenate and then count.

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

PowerShell, 27 42 bytes, 0 +-, 4 1 secondary

Thanks to mazzy for saving a + and 4 secondaries

$args|%{[int[]]$_*$_}|measure|select count

Try it online! or Pretty Table for an extra 3 bytes

-Or- adding four secondaries to save 19 bytes:

32 23 bytes, 1 0 +-, 12 5 secondaries

-9 bytes thanks to mazzy

($args|%{,$_*$_}).count

Try it online!

For each argument, we push n array elements (consisting of [n] but that's not important) to the pipeline which are grouped by the parens and then counted.

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

Ruby -na0, no +/-, no tiebreakers, 60 bytes

$F<<?a until~%r[
]&&$F::join[%r[a{#$`}a{#$'}]]
p$F::count ?a

Try it online!

Actually harder than I thought, I'm almost certainly missing a trick.

Reads in the input, then adds a characters to the argument array until the array, when joined into a string, matches a regular expression that uses the two input numbers as quantifiers, then counts how many it added.

Syntax tricks include using %r[] instead of // for a regexp, and :: instead . for a method call.

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

Keg (SBCS on Keg wiki)

Basically a port of the R answer.

¿¿Ï_"Ï_!.

Explanation

¿¿#        Take 2 integer inputs
  Ï_"Ï_#   Generate 2 arrays the length of the integer inputs
       !.# Output the length of the stack
\$\endgroup\$
1
\$\begingroup\$

Ruby, 0 +/-, 0 tie-breakers, 39 bytes

And fairly unreadable.

p"#{"%#{"%ss%%%ss"%$F}"%%w[o o]}"::size

Try it online!

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

MathGolf, 3 bytes, 0 +-, 1 tiebreaker

~{)

Input as a list. If taking the two inputs separated is mandatory, a trailing ê should be added (read entire STDIN input as integer-array).

Try it online.

Explanation:

~    # Push the value of the (implicit) input-list to the stack
 {   # Loop the top value amount of times
  )  #  And increase the other value once every iteration
     # (after which the entire stack joined together is output implicitly as result)
\$\endgroup\$
1
\$\begingroup\$

Lua, 46 bytes

print(load'return io.read"n"\x2Bio.read"n"'())

Try it online!

How It Works

load loads a string and returns a function, we pass a hexadecimal to it and call the function.

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

brainfuck, 11 bytes, 2 +-, 3 tie breaker

,>,[-<+>]<.

Sadly i can’t think up anyway of manipulating number without +-

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ If + and - are used, it is simply invalid. \$\endgroup\$
    – Razetime
    May 11, 2021 at 2:35
  • \$\begingroup\$ @Razetime It's mentioned in question that use as few +- a possible \$\endgroup\$
    – okie
    May 11, 2021 at 6:07
  • \$\begingroup\$ ah, it isn't too clear or exact about what's banned. I suppose it's ok \$\endgroup\$
    – Razetime
    May 11, 2021 at 6:09
  • \$\begingroup\$ @Razetime This answer is bad anyway, I just can't think up anyway to use 1 +- only. \$\endgroup\$
    – okie
    May 11, 2021 at 6:11
1
\$\begingroup\$

JavaScript, 2 tie-breakers

alert(`${``[`repeat`][`call`]`${prompt``}`}${``[`repeat`][`call`]`${prompt``}`}`[`length`])

Could I have made it shorter? Yes. But I find this version especially amusing.

Peculiarities:

  • Only uses lowercase letters and the symbols $ [ ] ` { }
  • Uses no mathematical operators.
  • Relies heavily on especially cryptic JavaScript features

Tricks used:

  • obj['prop'] instead of obj.prop to avoid using .
  • tagged template literals to avoid using ( ) to call functions
    • func`string` evaluates to func(['string'])
    • func`${ expression }` evaluates to func(['', ''], expression)
  • ['', ''].toString() produces ','
  • ''.repeat.call(',', value) is equivalent to ','.repeat(value). This hack is used to turn the repeat function into one which takes the number of repeats as its second argument, so that we can use that function as a tag.

Edit: oops, forgot to alert the result. Uh, I'll just wrap that in an alert for now, feel free to suggest an improvement 😅

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

Desmos, 22 bytes, 0 +/-, 2 tiebreakers

lne^{\ans_0}e^{\ans_1}

Input numbers in the first two lines. I have to admit, I spent an embarrassing amount of time trying to go from the obvious 4 tiebreakers solution [\ans_0,\ans_1].total to a 2 tiebreakers solution. I considered many other interesting ideas to go from 3 to 2 (integrals, percent of, {} evaluates to 1, etc.), but at the end, it turned out to be very simple...

I'm pretty sure 2 tiebreakers is optimal for Desmos because a 0 and 1 are required to obtain input. Defining a function is even worse: You need (, ) and =, which is 3 tiebreakers.

Try It On Desmos!

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

Python

i=input
print eval('%d\x2b%d'%(i(),i()))

37 chars with a little bit of cheating :p

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

A very yucky C version

Has no +, -, / or any digits. One use of * for a pointer type. The others (()=,) are needed a lot in the language itself.

#include <malloc.h>
#include <string.h>
#include <stdio.h>
typedef unsigned char *ptr;

char
  y;

const size_t
  one = sizeof y;

unsigned char
  zero='a'^'a',
  a [] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  z [] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  x [] = "xxxxxxxxxxxxxxxxx";

size_t plus_one (size_t i)
{
  ptr b=&a[one];
  memset (a,'x',sizeof a);
  b[i]=zero;
  return strlen(a);
}

size_t minus_one (size_t i)
{
  ptr b=&a[one];
  memset (a,'x',sizeof a);
  a[i]=zero;
  return strlen(b);
}

size_t minus_zero (size_t i)
{
  size_t p;
  for (p = zero ; z[p] ; p = plus_one (p))
  {
    i = minus_one(i);
  }
  return i;
}

unsigned char to_zero (unsigned char i)
{
  size_t p;
  for (p = one>>one ; x[p] ; p = plus_one (p))
  {
    i = (unsigned char) minus_one(i);
  }
  return i;
}

main (int argc, ptr argv [])
{
  ptr
    a = argv [argc>>one],
    b = argv [argc>>one<<one];

  size_t
    len_a = strlen (a),
    len_b = strlen (b),
    len = len_a > len_b ? len_a : len_b,
    o = plus_one(len),
    i,
    c=one>>one;

  ptr
    res=(ptr)malloc(plus_one(o));

  res[o]=zero;

  for (i = zero ; i < len ; i=plus_one(i))
  {
    size_t va;
    unsigned char r;

    va = (len_a > zero ? minus_zero (a[minus_one(len_a)]) <<one<<one<<one<<one : zero) | (len_b > zero ? minus_zero (b[minus_one (len_b)]) : zero);
    r = (c?"bcdefghijAuhjsadcdefghijABsadlkfdefghijABCvsxwerefghijABCDDNIWjsfghijABCDEOQJdccghijABCDEFIndDjlhijABCDEFGCnjndwijABCDEFGHsadXSkjABCDEFGHICSjshdABCDEFGHIJcbaCBA":"abcdefghijaswhHDbcdefghijAQWuciucdefghijABCOasdpdefghijABCCnjaskefghijABCDCIUdasfghijABCDEuoiDSAghijABCDEFCsalkjhijABCDEFGcapCPcijABCDEFGHCWEoerjABCDEFGHIkjIjIj") [va];
    c=r<'a';
    r&=~(one<<one<<one<<one<<one<<one);
    o=minus_one(o);
    res[o]=to_zero(r);

    if (len_a) len_a = minus_one (len_a);
    if (len_b) len_b = minus_one (len_b);
  }
  if(c) 
  {
    o=minus_one(o);
    res[o]=to_zero('B');
  }
  printf("%s\n",&res[o]);
  free (res);
}
\$\endgroup\$
0
\$\begingroup\$

C #, 26 tiebreakers

+/- : 0
=   : 2
.   : 6 
()  : 18
using System;
using System.Linq;
class P
{
    static void Main()
    {
        Func<int[]> f=()=>new int[int.Parse(Console.ReadLine())];
        Console.Write(f().Concat(f()).Count());
    }
}
\$\endgroup\$
0
\$\begingroup\$

VBA - No +/-, 7 tie-breakers

+,-,/,*,,,.,0-9 = 0
( = 3 (3 total pairs)
) = 3
= = 1

Function a(b)
    For Each c In b
        a = a & Space(c)
    Next
    MsgBox Len(a)
End Function

Takes an array of natural numbers as an argument. This will actually add more than just 2 values, if provided, as well as return the value of a single argument.

Older versions


+,-,/,*,=,.,0-9 = 0
( = 4 (4 total pairs)
) = 4
, = 1

Function a(b, c)
MsgBox Len(Space(b) & Space(c))
End Function

+,-,/,*,=,.,0-9 = 0
( = 4 (4 total pairs)
) = 4
, = 3

Sub a(b,c)
MsgBox Len(String(b," ") & String(c," "))
End Sub

+,-,/,*,. = 0
= = 4
( = 2 (2 total pairs)
) = 2
0-9 = 2
, = 1

Sub d(e,f)
For g=1 To e:h=h & " ":Next
For g=1 To f:h=h & " ":Next
MsgBox Len(h)
End Sub
\$\endgroup\$
3
  • \$\begingroup\$ Character count technically doesn't matter in this challenge. You have no -+, and you have 11 tie breakers. This puts you above any solution that has a -+ character, and below any solution with no -+ with fewer tie breakers. \$\endgroup\$
    – PhiNotPi
    Apr 12, 2012 at 15:43
  • \$\begingroup\$ So, I am tied with (as one example) Uri Goren's answer, correct? He has no +/-, but 11 tie-breakers. \$\endgroup\$
    – Gaffi
    Apr 12, 2012 at 15:45
  • \$\begingroup\$ Yes, you are tied with him. \$\endgroup\$
    – PhiNotPi
    Apr 12, 2012 at 15:50
0
\$\begingroup\$

PHP, 22 chars

echo array_sum($argv);

Documentation: array_sum() and $argv
Usage: php -r 'echo array_sum($argv);' 5 6 will output 11.

\$\endgroup\$
1
  • \$\begingroup\$ +/- and above mentioned tiebreakers are interesting, not chars. \$\endgroup\$ May 30, 2012 at 3:35
0
\$\begingroup\$

APL (10, 3 tie-breakers)

⎕←⍴(⍳⎕),⍳⎕
\$\endgroup\$
1
  • \$\begingroup\$ 10x +/-? Chars arn't interesting, just +/- and the tie-breakers. \$\endgroup\$ May 30, 2012 at 3:34
0
\$\begingroup\$

Common Lisp

Always surprising for such a verbose language.

((lambda(n m)(princ(length(append(make-list n)(make-list m)))))(read)(read))
\$\endgroup\$
0
0
\$\begingroup\$

Python 3 - 159 characters | ().,*/= count: 39

A little long, but I felt like doing it HDL-style.

a,b,c,d=int(input()),int(input()),0,0;l=max(a,b,key=int.bit_length)
for i in range(len(bin(l<<1)[2:])):
 e=a>>i&1;f=b>>i&1;c|=(e^f^d)<<i;d=e&f|d&(e^f)
print(c)
\$\endgroup\$
4
  • \$\begingroup\$ +/- tiebreakers are interesting, not characters. \$\endgroup\$ May 30, 2012 at 3:33
  • \$\begingroup\$ @userunknown: What's wrong with characters? \$\endgroup\$
    – JAB
    May 30, 2012 at 16:55
  • \$\begingroup\$ Characters are counted in CodeGolf tagged questions. If a reader doesn't read the question again, he will get the impression that character count is important and probably make a misguided vote based on that assumption. So the rules say: No (+|-). In Tiebreak digits, ().,*/= are important. You should include that number in your answer, so that not every visitor has to count them himself. \$\endgroup\$ May 30, 2012 at 20:41
  • \$\begingroup\$ @userunknown: Oh, right. \$\endgroup\$
    – JAB
    May 30, 2012 at 20:46
0
\$\begingroup\$

C# 141 characters 27 tiebreakers

+/- : 0
=   : 0
.   : 9 
()  : 18


Console.WriteLine(Enumerable.Range(1,int.Parse(Console.ReadLine()))
.Concat(Enumerable.Range(1,int.Parse(Console.ReadLine())))
.Count());
\$\endgroup\$

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