Ways to arrange the integers 1 to 9 with operators so that the result is 100

7

1

Prelude:

This task is taken from Five Problems Every Software Engineer Should Be Able to Solve in Less Than an Hour, which I really recommend.

The task:

Write a program that outputs all possibilities to put + or - or nothing between the numbers 1, 2, ..., 9 (in this order) such that the result is always 100.

Winning Criteria:

Shortest code in bytes wins.

James Williams

Posted 2015-05-10T15:26:38.070

Reputation: 1 735

Are spaces allowed between the numbers, like 1 2 3+4+5 rather than 123+4+5? – Tim – 2015-05-10T16:27:08.233

1

Pretty similar to http://codegolf.stackexchange.com/questions/3019/getting-an-answer-from-a-string-of-digits (this link allows for * & / and does not specify the target 100)

– Kyle Kanos – 2015-05-10T17:44:37.223

Answers

13

Perl 5.10.0 - 50 46 45B

say for grep{eval==100}glob join'{,+,-}',1..9

Usage: perl -M5.10.0 scratch.pl (I think I get the version for free)

alexander-brett

Posted 2015-05-10T15:26:38.070

Reputation: 1 485

A very nice solution; both concise and fairly readable even without much knowledge of Perl. – JohnE – 2015-05-10T18:15:14.390

4

CJam, 43 40 bytes

"-"SL]8m*{A,2>.+1\+s}%{~]:+100=},N*S/'+*

Here is how it works:

"-"SL]                     e# This is an array containing -, space and empty character
                           e# This represents -, + and joints correspondingly
      8m*                  e# Get all cartesian products of these 3 strings of length 8
                           e# For instance, all cartesian products of length 2 are:
                           e# [["-" " "] ["-" "-"] ["-" ""] [" " " "] [" " "-"] [" " ""]
                           e# ["" " "] ["" "-"] ["" ""]]
         {          }%     e# Map these cartesian products over this loop
          A,2>             e# Get array [2, 3, 4, 5, 6, 7, 8, 9]
              .+           e# In-order concatenation of the above two arrays
                1\+s       e# Prepend 1 to the result from above and convert it to string
{        },                e# Now we have all possible strings of 1 to 9 with all possible
                           e# operators as well as joins (things like 567). Its time to
                           e# filter out what add up to 100
 ~                         e# Evaluate the string. This leaves some numbers on stack.
  ]:+                      e# Wrap those numbers in an array and take their sum
     100=                  e# Check if the sum is equal to 100
           N*              e# Join all filtered strings by newline
             S/'+*         e# We used space instead of +. So now we replace space with +

Try it online here

Optimizer

Posted 2015-05-10T15:26:38.070

Reputation: 25 836

3

My shot at this:

Python 2, 93 bytes

def a(e,i):
 if i<=9:[a(e+x+`i`,i+1)for x in("+","-","")]
 elif eval(e)==100:print e
a("1",2)

James Williams

Posted 2015-05-10T15:26:38.070

Reputation: 1 735

1You can use single space indents and also str(i) -> \i``. Also, you might want to mention that this is Python 2 specific :) – Sp3000 – 2015-05-10T16:52:34.710

@Sp3000 Thanks! I'm trying to improve my code golf skills and I'd never heard of the backtick thing. – James Williams – 2015-05-10T17:44:48.227

One of the best code I have ever seen... – Arun Joshla – 2019-04-01T11:32:15.770

2

Mathematica, 93 92 bytes

Print/@Select[""<>ToString/@Range@9~Riffle~#&/@{"+","-",""}~Tuples~{8},ToExpression@#==100&]

Fairly straightforward: generates all possible strings using Tuples and then filters them.

For reference, I get:

1+2+3-4+5+6+78+9
1+2+34-5+67-8+9
1+23-4+5+6+78-9
1+23-4+56+7+8+9
12+3+4+5-6-7+89
12+3-4+5+67+8+9
12-3-4+5-6+7+89
123+4-5+67-89
123+45-67+8-9
123-4-5-6-7+8-9
123-45-67+89

Martin Ender

Posted 2015-05-10T15:26:38.070

Reputation: 184 808

2

Pyth, 26 bytes

fqvT100m+ssC,r1Td9^c3"+-"8

First, we generate all 8 element combinations of ["+", "-", ""]. c3"+-" chops "+-" into 3 rougly equal sied pieces, giving the appropriate list. ^c3"+-"8 gives the 8 element combinations.

Then, we greate the arithmetic sequences. C,r1Td zips together the operators with the numbers 1 through 8, which are then summed twice to give the string, and + ... 9 puts a 9 at the end.

Finally, fqvT100 filters for those expressions which evaluate to 100.


The update to the interpreter which allowed this code to work was this one, which was made about a day before this question was asked, so this code would have only worked on the command line compiler, not the online one, when the question was asked.

Demonstration.

isaacg

Posted 2015-05-10T15:26:38.070

Reputation: 39 268

1

JavaScript, 86 92

Head to head with the best. That must be an anomalous problem.

Edit -6 thx @nderscore

for(i=6562;k=--i;eval(o)-100||alert(o))for(j=o=1;j++<9;k=k/3|0)o+=k%3?' +-'[k%3]+j:[j]

Test in any browser console, it pops up just 11 times.

Or this snippet:

function out(x) { OUT.innerHTML = OUT.innerHTML + '\n' + x; }

// 6562 is 3 powered to 8 +1
for(i=6562;k=--i;eval(o)-100||out(o))
  for(j=o=1;j++<9;k=k/3|0)
    o+=k%3?' +-'[k%3]+j:[j]
    
<pre id=OUT></pre>

edc65

Posted 2015-05-10T15:26:38.070

Reputation: 31 086

Here's -6: for(i=6562;k=--i;eval(o)^100||alert(o))for(j=o=1;9>j++;k=k/3|0)o+=k%3?' +-'[k%3]+j:[j] – nderscore – 2015-05-11T01:56:11.690

@nderscore thanks, some obvious changes against my sloppy golfing, but the last trick with the ternary is very clever – edc65 – 2015-05-11T03:58:00.730

0

Python (176)

39 minutes and counting (for all problems that is)

from itertools import*
for i in product(('+','-',''),repeat=8):
 s=''.join(''.join(j)for j in chain(izip_longest(map(str,range(1,10)),i,fillvalue='')))
 if eval(s)==100:print s

This could probably be shorter, but this was my actual solution for this problem, just golfed down a bit.

ɐɔıʇǝɥʇuʎs

Posted 2015-05-10T15:26:38.070

Reputation: 4 449

0

K, 61 50 bytes

t@&100=.:'t:{:[x>9;,y;,/_f[x+1]'(y,"+";y,"-";y),\:$x]}[2;"1"]

Tested with Kona.

The general approach is to recursively generate all the expressions and then filter out those which eval (.) to 100. This is reasonably competitive as written, but I think there's still room for improvement.

edit:

t@&100=.:'t:(,"1"){,/x,/:\:("+";"-";""),\:$y}/2+!8

Altering my approach a bit to be iterative rather than recursive, which removes the need for explicit base cases as well as saving me some brackets.

JohnE

Posted 2015-05-10T15:26:38.070

Reputation: 4 632