Sum to 100: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|REXX}}: moved the complete solution for "9" to the discussion page.)
Line 35: Line 35:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang Haskell>import Control.Monad (replicateM)
<lang Haskell>import Data.Function (on)
import Control.Arrow ((&&&))
import Control.Arrow ((&&&))
import Data.Function (on)
import Data.List (nub, group, sort, sortBy, find, intercalate)
import Data.Char (intToDigit)
import Data.Char (intToDigit)
import Control.Monad (replicateM)
import Data.List (nub, group, sort, sortBy, find, intercalate)


data Sign
data Sign
Line 97: Line 97:
, "\n\nFirst positive integer not expressible as a sum of this kind:\n"
, "\n\nFirst positive integer not expressible as a sum of this kind:\n"
, maybeReport (find (uncurry (/=)) (zip [0 ..] (nub allNonNegativeSums)))
, maybeReport (find (uncurry (/=)) (zip [0 ..] (nub allNonNegativeSums)))
, ""
]
]
where
where
Line 103: Line 104:
=> Maybe (a, b) -> String
=> Maybe (a, b) -> String
maybeReport (Just (x, _)) = show x
maybeReport (Just (x, _)) = show x
maybeReport _ = "No gaps found"
maybeReport _ = "No gaps found"</lang>
</lang>


{{Out}}
{{Out}}
Line 132: Line 132:
211
211


[Finished in 1.284s]</pre>
[Finished in 1.232s]</pre>


=={{header|JavaScript}}==
=={{header|JavaScript}}==

Revision as of 00:17, 5 January 2017

Sum to 100 is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Find solutions to the   sum to one hundred   puzzle.


Add (insert) the mathematical operators     +   or       (plus or minus)   before any of the digits in the
decimal numeric string   123456789   such that the resulting mathematical expression adds up to a
particular sum   (in this iconic case,   100).


Example:

           123 + 4 - 5 + 67 - 89   =   100   

Show all output here.


  •   Show all solutions that sum to   100
  •   Show the sum that has the maximum   number   of solutions   (from zero to infinity*)
  •   Show the lowest positive sum that   can't   be expressed   (has no solutions), using the rules for this task


An example of a sum that can't be expressed (within the rules of this task) is:   5074
which, of course, is not the lowest positive sum that can't be expressed.


*   (where   infinity   would be a relatively small   123,456,789)


Haskell

<lang Haskell>import Data.Function (on) import Control.Arrow ((&&&)) import Data.Char (intToDigit) import Control.Monad (replicateM) import Data.List (nub, group, sort, sortBy, find, intercalate)

data Sign

 = Unsigned
 | Plus
 | Minus
 deriving (Eq, Show)

universe :: (Int, Sign) universe =

 zip [1 .. 9] <$>
 filter ((/= Plus) . head) (replicateM 9 [Unsigned, Plus, Minus])

allNonNegativeSums :: [Int] allNonNegativeSums = sort $ filter (>= 0) (asSum <$> universe)

asSum :: [(Int, Sign)] -> Int asSum xs =

 n +
 (if null s
    then 0
    else read s :: Int)
 where
   (n, s) = foldr readSign (0, []) xs
   readSign :: (Int, Sign) -> (Int, String) -> (Int, String)
   readSign (i, x) (n, s)
     | x == Unsigned = (n, intToDigit i : s)
     | otherwise =
       ( (if x == Plus
            then (+)
            else (-))
           n
           (read (show i ++ s) :: Int)
       , [])

asString :: [(Int, Sign)] -> String asString = foldr signedDigit []

 where
   signedDigit (i, x) s
     | x == Unsigned = intToDigit i : s
     | otherwise =
       (if x == Plus
          then " +"
          else " -") ++
       [intToDigit i] ++ s

main :: IO () main =

 mapM_
   putStrLn
   [ "Sums to 100:\n"
   , unlines $ asString <$> filter ((== 100) . asSum) universe
   , "\n10 commonest sums [sum, number of routes to it]:\n"
   , show
       ((head &&& length) <$>
        take 10 (sortBy (on (flip compare) length) (group allNonNegativeSums)))
   , "\n\nFirst positive integer not expressible as a sum of this kind:\n"
   , maybeReport (find (uncurry (/=)) (zip [0 ..] (nub allNonNegativeSums)))
   , ""
   ]
 where
   maybeReport
     :: Show a
     => Maybe (a, b) -> String
   maybeReport (Just (x, _)) = show x
   maybeReport _ = "No gaps found"</lang>
Output:

(Run in Atom editor, through Script package)

Sums to 100:

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

10 commonest sums [sum, number of routes to it]:

[(9,46),(27,44),(1,43),(15,43),(21,43),(45,42),(3,41),(5,40),(7,39),(17,39)]


First positive integer not expressible as a sum of this kind:

211

[Finished in 1.232s]

JavaScript

ES5

Translation of: Haskell

<lang JavaScript>(function () {

   'use strict';
   // GENERIC FUNCTIONS ----------------------------------------------------
   // permutationsWithRepetition :: Int -> [a] -> a
   var permutationsWithRepetition = function (n, as) {
       return as.length > 0 ? (
           foldl1(curry(cartesianProduct)(as), replicate(n, as))
       ) : [];
   };
   // cartesianProduct :: [a] -> [b] -> a, b
   var cartesianProduct = function (xs, ys) {
       return [].concat.apply([], xs.map(function (x) {
           return [].concat.apply([], ys.map(function (y) {
               return [
                   [x].concat(y)
               ];
           }));
       }));
   };
   // curry :: ((a, b) -> c) -> a -> b -> c
   var curry = function (f) {
       return function (a) {
           return function (b) {
               return f(a, b);
           };
       };
   };
   // foldl1 :: (a -> a -> a) -> [a] -> a
   var foldl1 = function (f, xs) {
       return xs.length > 0 ? xs.slice(1)
           .reduce(f, xs[0]) : [];
   };
   // replicate :: Int -> a -> [a]
   var replicate = function (n, a) {
       var v = [a],
           o = [];
       if (n < 1) return o;
       while (n > 1) {
           if (n & 1) o = o.concat(v);
           n >>= 1;
           v = v.concat(v);
       }
       return o.concat(v);
   };
   // group :: Eq a => [a] -> a
   var group = function (xs) {
       return groupBy(function (a, b) {
           return a === b;
       }, xs);
   };
   // groupBy :: (a -> a -> Bool) -> [a] -> a
   var groupBy = function (f, xs) {
       var dct = xs.slice(1)
           .reduce(function (a, x) {
               var h = a.active.length > 0 ? a.active[0] : undefined,
                   blnGroup = h !== undefined && f(h, x);
               return {
                   active: blnGroup ? a.active.concat(x) : [x],
                   sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])
               };
           }, {
               active: xs.length > 0 ? [xs[0]] : [],
               sofar: []
           });
       return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);
   };
   // sort :: Ord a => [a] -> [a]
   var sort = function (xs) {
       return xs.sort();
   };
   // sortBy :: (a -> a -> Ordering) -> [a] -> [a]
   var sortBy = function (f, xs) {
       return xs.sort(f);
   };
   // nub :: [a] -> [a]
   var nub = function (xs) {
       return nubBy(function (a, b) {
           return a === b;
       }, xs);
   };
   // nubBy :: (a -> a -> Bool) -> [a] -> [a]
   var nubBy = function (p, xs) {
       var x = xs.length ? xs[0] : undefined;
       return x !== undefined ? [x].concat(nubBy(p, xs.slice(1)
           .filter(function (y) {
               return !p(x, y);
           }))) : [];
   };
   // find :: (a -> Bool) -> [a] -> Maybe a
   var find = function (f, xs) {
       for (var i = 0, lng = xs.length; i < lng; i++) {
           if (f(xs[i], i)) return xs[i];
       }
       return undefined;
   };
   // unlines :: [String] -> String
   var unlines = function (xs) {
       return xs.join('\n');
   };
   // show :: a -> String
   var show = function (x) {
       return JSON.stringify(x);
   }; //, null, 2);
   // head :: [a] -> a
   var head = function (xs) {
       return xs.length ? xs[0] : undefined;
   };


   // SIGNED DIGIT SEQUENCES  (mapped to sums and to strings)
   // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
   // asSum :: [Sign] -> Int
   var asSum = function (xs) {
       var dct = xs.reduceRight(function (a, sign, i) {
           var d = i + 1; //  zero-based index to [1-9] positions
           if (sign !== 0) {
               // Sum increased, digits cleared
               return {
                   digits: [],
                   n: a.n + sign * parseInt([d].concat(a.digits)
                       .join(), 10)
               };
           } else return { // Digits extended, sum unchanged
               digits: [d].concat(a.digits),
               n: a.n
           };
       }, {
           digits: [],
           n: 0
       });
       return dct.n + (dct.digits.length > 0 ? (
           parseInt(dct.digits.join(), 10)
       ) : 0);
   };
   // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
   // asString :: [Sign] -> String
   var asString = function (xs) {
       var ns = xs.reduce(function (a, sign, i) {
           var d = (i + 1)
               .toString();
           return sign === 0 ? a + d : a + (sign > 0 ? ' +' : ' -') + d;
       }, );
       return ns[0] === '+' ? ns.slice(1) : ns;
   };


   // SUM T0 100 ------------------------------------------------------------
   // universe :: Sign
   var universe = permutationsWithRepetition(9, [0, 1, -1])
       .filter(function (x) {
           return x[0] !== 1;
       });
   // allNonNegativeSums :: [Int]
   var allNonNegativeSums = sort(universe.map(asSum)
       .filter(function (x) {
           return x >= 0;
       }));
   return [
       "Sums to 100:\n", unlines(universe.filter(function (x) {
               return asSum(x) === 100;
           })
           .map(asString)),
       "\n\n10 commonest sums (sum, followed by number of routes to it):\n",
       show(sortBy(function (a, b) {
               var lngA = a.length,
                   lngB = b.length;
               if (lngA > lngB) return -1;
               return lngA < lngB ? 1 : 0;
           }, group(allNonNegativeSums))
           .slice(0, 10)
           .map(function (xs) {
               return [xs[0], xs.length];
           })),
       "\n\nFirst positive integer not expressible as a sum of this kind:\n",
       show(find(function (x, i) {
           return x !== i;
       }, sortBy(function (a, b) {
           if (a < b) return -1;
           return a > b ? 1 : 0;
       }, nub(allNonNegativeSums))) - 1) // i is the the zero-based Array index
   ].join('\n') + '\n';

})();</lang>

Output:

(Run in Atom editor, through Script package)

Sums to 100:

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


10 commonest sums (sum, followed by number of routes to it):

[[9,46],[27,44],[1,43],[15,43],[21,43],[45,42],[3,41],[5,40],[17,39],[7,39]]


First positive integer not expressible as a sum of this kind:

211

[Finished in 0.355s]

ES6

Translation of: Haskell

<lang JavaScript>(() => {

   'use strict';
   // GENERIC FUNCTIONS ----------------------------------------------------
   // permutationsWithRepetition :: Int -> [a] -> a
   const permutationsWithRepetition = (n, as) =>
       as.length > 0 ? (
           foldl1(curry(cartesianProduct)(as), replicate(n, as))
       ) : [];
   // cartesianProduct :: [a] -> [b] -> a, b
   const cartesianProduct = (xs, ys) =>
       [].concat.apply([], xs.map(x =>
       [].concat.apply([], ys.map(y => [[x].concat(y)]))));
   // curry :: ((a, b) -> c) -> a -> b -> c
   const curry = f => a => b => f(a, b);
   // foldl1 :: (a -> a -> a) -> [a] -> a
   const foldl1 = (f, xs) =>
       xs.length > 0 ? xs.slice(1)
       .reduce(f, xs[0]) : [];
   // replicate :: Int -> a -> [a]
   const replicate = (n, a) => {
       let v = [a],
           o = [];
       if (n < 1) return o;
       while (n > 1) {
           if (n & 1) o = o.concat(v);
           n >>= 1;
           v = v.concat(v);
       }
       return o.concat(v);
   };
   // group :: Eq a => [a] -> a
   const group = xs => groupBy((a, b) => a === b, xs);
   // groupBy :: (a -> a -> Bool) -> [a] -> a
   const groupBy = (f, xs) => {
       const dct = xs.slice(1)
           .reduce((a, x) => {
               const
                   h = a.active.length > 0 ? a.active[0] : undefined,
                   blnGroup = h !== undefined && f(h, x);
               return {
                   active: blnGroup ? a.active.concat(x) : [x],
                   sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])
               };
           }, {
               active: xs.length > 0 ? [xs[0]] : [],
               sofar: []
           });
       return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);
   };
   // sort :: Ord a => [a] -> [a]
   const sort = xs => xs.sort();
   // sortBy :: (a -> a -> Ordering) -> [a] -> [a]
   const sortBy = (f, xs) => xs.sort(f);
   // nub :: [a] -> [a]
   const nub = xs => nubBy((a, b) => a === b, xs);
   // nubBy :: (a -> a -> Bool) -> [a] -> [a]
   const nubBy = (p, xs) => {
       const x = xs.length ? xs[0] : undefined;
       return x !== undefined ? [x].concat(
           nubBy(p, xs.slice(1)
               .filter(y => !p(x, y)))
       ) : [];
   };
   // find :: (a -> Bool) -> [a] -> Maybe a
   const find = (f, xs) => {
       for (var i = 0, lng = xs.length; i < lng; i++) {
           if (f(xs[i], i)) return xs[i];
       }
       return undefined;
   }
   // unlines :: [String] -> String
   const unlines = xs => xs.join('\n');
   // show :: a -> String
   const show = x => JSON.stringify(x); //, null, 2);
   // head :: [a] -> a
   const head = xs => xs.length ? xs[0] : undefined;


   // SIGNED DIGIT SEQUENCES  (mapped to sums and to strings)
   // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
   // asSum :: [Sign] -> Int
   const asSum = xs => {
       const dct = xs.reduceRight((a, sign, i) => {
           const d = i + 1; //  zero-based index to [1-9] positions
           if (sign !== 0) { // Sum increased, digits cleared
               return {
                   digits: [],
                   n: a.n + (sign * parseInt([d].concat(a.digits)
                       .join(), 10))
               };
           } else return { // Digits extended, sum unchanged
               digits: [d].concat(a.digits),
               n: a.n
           };
       }, {
           digits: [],
           n: 0
       });
       return dct.n + (dct.digits.length > 0 ? (
           parseInt(dct.digits.join(), 10)
       ) : 0);
   };
   // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
   // asString :: [Sign] -> String
   const asString = xs => {
       const ns = xs.reduce((a, sign, i) => {
           const d = (i + 1)
               .toString();
           return (sign === 0 ? (
               a + d
           ) : (a + (sign > 0 ? ' +' : ' -') + d));
       }, );
       return ns[0] === '+' ? ns.slice(1) : ns;
   };


   // SUM T0 100 ------------------------------------------------------------
   // universe :: Sign
   const universe = permutationsWithRepetition(9, [0, 1, -1])
       .filter(x => x[0] !== 1);
   // allNonNegativeSums :: [Int]
   const allNonNegativeSums = sort(universe.map(asSum)
       .filter(x => x >= 0));
   return [
       "Sums to 100:\n",
       unlines(universe.filter(x => asSum(x) === 100)
           .map(asString)),
       "\n\n10 commonest sums (sum, followed by number of routes to it):\n",
       show(sortBy((a, b) => {
               const
                   lngA = a.length,
                   lngB = b.length;
               if (lngA > lngB) return -1;
               return lngA < lngB ? 1 : 0;
           }, group(allNonNegativeSums))
           .slice(0, 10)
           .map(xs => [xs[0], xs.length])),
       "\n\nFirst positive integer not expressible as a sum of this kind:\n",
       show(find(
           (x, i) => x !== i,
           sortBy((a, b) => {
               if (a < b) return -1;
               return a > b ? 1 : 0;
           }, nub(allNonNegativeSums))
       ) - 1) // i is the the zero-based Array index.
   ].join('\n') + '\n';

})();</lang>

Output:

(Run in Atom editor, through Script package)

Sums to 100:

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


10 commonest sums (sum, followed by number of routes to it):

[[9,46],[27,44],[1,43],[15,43],[21,43],[45,42],[3,41],[5,40],[17,39],[7,39]]


First positive integer not expressible as a sum of this kind:

211

[Finished in 0.361s]

Perl 6

Works with: Rakudo version 2016.12

<lang perl6>my @ops = ['-', ], |( [' + ', ' - ', ] xx 8 ); my @str = [X~] map { .Slip }, ( @ops Z 1..9 ); my %sol = @str.classify: *.subst( ' - ', ' -', :g )\

                         .subst( ' + ',  ' ', :g ).words.sum;

my %count.push: %sol.map({ .value.elems => .key });

my $max_solutions = %count.max( + *.key ); my $first_unsolvable = first { %sol{$_} :!exists }, 1..*; my @two_largest_sums = %sol.keys.sort(-*)[^2];

given %sol{100}:p {

   say "{.value.elems} solutions for sum {.key}:";
   say "    $_" for .value.list;

}

say .perl for :$max_solutions, :$first_unsolvable, :@two_largest_sums;</lang>

Output:
12 solutions for sum 100:
    -1 + 2 - 3 + 4 + 5 + 6 + 78 + 9
    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
:max_solutions("46" => $["9", "-9"])
:first_unsolvable(211)
:two_largest_sums(["123456789", "23456790"])

REXX

<lang rexx>/*REXX pgm solves a puzzle: using the string 123456789, insert - or + to sum to 100*/ parse arg LO HI . /*obtain optional arguments from the CL*/ if LO== | LO=="," then LO=100 /*Not specified? Then use the default.*/ if HI== | HI=="," then HI=LO /* " " " " " " */ if LO==00 then HI=123456789 /*LOW specified as zero with leading 0s*/ ops= '+-'; L=length(ops) + 1 /*define operators (and their length). */ @.=; do i=1 to L-1; @.i=substr(ops,i,1) /* " some handy-dandy REXX literals*/

           end   /*i*/                          /*   "   individual operators for speed*/

mx=0; mn=999999 /*initialize the minimums and maximums.*/ mxL=; mnL=; do j=LO to HI until LO==00 & mn==0 /*solve with a range of sums*/

                  z=solve(j)                               /*find # solutionson for  J.*/
                  if z> mx  then mxL=                      /*see if this is a new max. */
                  if z>=mx  then do; mxL=mxL j; mx=z; end  /*remember this new maximum.*/
                  if z< mn  then mnL=                      /*see if this is a new min. */
                  if z<=mn  then do; mnL=mnL j; mn=z; end  /*remember this new minimum.*/
                  end   /*j*/

if LO==HI then exit /*don't display max & min ? */ @@= 'number of solutions: '; say _=words(mxL); say 'sum's(_) "of" mxL ' 's(_,"have",'has') 'the maximum' @@ mx _=words(mnL); say 'sum's(_) "of" mnL ' 's(_,"have",'has') 'the minimum' @@ mn exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ s: if arg(1)==1 then return arg(3); return word(arg(2) "s",1) /*simple pluralizer*/ /*──────────────────────────────────────────────────────────────────────────────────────*/ solve: parse arg answer; #=0 /*obtain the answer (sum) to the puzzle*/

         do a=L-1  to L;        aa=      @.a'1' /*choose one  of  ─       or  nothing. */
          do b=1  for L;        bb=aa || @.b'2' /*   "    "    "  ─   +,  or  abutment.*/
           do c=1  for L;       cc=bb || @.c'3' /*   "    "    "  "   "    "      "    */
            do d=1  for L;      dd=cc || @.d'4' /*   "    "    "  "   "    "      "    */
             do e=1  for L;     ee=dd || @.e'5' /*   "    "    "  "   "    "      "    */
              do f=1  for L;    ff=ee || @.f'6' /*   "    "    "  "   "    "      "    */
               do g=1  for L;   gg=ff || @.g'7' /*   "    "    "  "   "    "      "    */
                do h=1  for L;  hh=gg || @.h'8' /*   "    "    "  "   "    "      "    */
                 do i=1  for L; ii=hh || @.i'9' /*   "    "    "  "   "    "      "    */
                 interpret '$=' ii              /*calculate the sum of modified string.*/
                 if $\==answer  then iterate    /*Is sum not equal to answer? Then skip*/
                 #=#+1;         if LO==HI  then say 'solution: '    $    " ◄───► "     ii
                 end   /*i*/
                end    /*h*/
               end     /*g*/
              end      /*f*/
             end       /*e*/
            end        /*d*/
           end         /*c*/
          end          /*b*/
         end           /*a*/
      y=#
      if y==0  then y='no'                      /*maybe adjust the number of solutions.*/
      if LO\==00  then say right(y, 9)  'solution's(y)  'found for'  right(j, length(HI))
      return #                                  /*return the number of solutions found.*/</lang>

output   when the default input is used:

solution:  100  ◄───►  -1+2-3+4+5+6+78+9
solution:  100  ◄───►  1+2+3-4+5+6+78+9
solution:  100  ◄───►  1+2+34-5+67-8+9
solution:  100  ◄───►  1+23-4+5+6+78-9
solution:  100  ◄───►  1+23-4+56+7+8+9
solution:  100  ◄───►  12+3+4+5-6-7+89
solution:  100  ◄───►  12+3-4+5+67+8+9
solution:  100  ◄───►  12-3-4+5-6+7+89
solution:  100  ◄───►  123+4-5+67-89
solution:  100  ◄───►  123+45-67+8-9
solution:  100  ◄───►  123-4-5-6-7+8-9
solution:  100  ◄───►  123-45-67+89
       12 solutions found for 100

output   when the following input is used:   00

sum of  9  has the maximum number of solutions:  46
sum of  211  has the minimum number of solutions:  0

zkl

Taking a big clue from Haskell and just calculate the world. <lang zkl>var all = // ( (1,12,123...-1,-12,...), (2,23,...) ...)

  (9).pump(List,fcn(n){ split("123456789"[n,*]) })       // 45
  .apply(fcn(ns){ ns.extend(ns.copy().apply('*(-1))) }); // 90

fcn calcAllSums{ // calculate all 6572 sums (1715 unique)

  fcn(n,sum,soFar,r){
     if(n==9) return();
     foreach b in (all[n]){

if(sum+b>=0 and b.abs()%10==9) r.appendV(sum+b,"%s%+d".fmt(soFar,b)); self.fcn(b.abs()%10,sum + b,"%s%+d".fmt(soFar,b),r);

     }
  }(0,0,"",r:=Dictionary());
  r

}

   // "123" --> (1,12,123)

fcn split(nstr){ (1).pump(nstr.len(),List,nstr.get.fp(0),"toInt") }</lang> <lang zkl>fcn showSums(allSums,N=100,printSolutions=2){

  slns:=allSums.find(N,T);
  if(printSolutions)    println("%d solutions for N=%d".fmt(slns.len(),N));
  if(printSolutions==2) println(slns.concat("\n"));
  println();

}

allSums:=calcAllSums(); showSums(allSums); showSums(allSums,0,1);

println("Smallest postive integer with no solution: ",

  [1..].filter1('wrap(n){ Void==allSums.find(n) }));

println("5 commonest sums (sum, number of ways to calculate to it):"); ms:=allSums.values.apply("len").sort()[-5,*]; // 5 mostest sums allSums.pump(List, // get those pairs

  'wrap([(k,v)]){ v=v.len(); ms.holds(v) and T(k.toInt(),v) or Void.Skip })

.sort(fcn(kv1,kv2){ kv1[1]>kv2[1] }) // and sort .println();</lang>

Output:
12 solutions for N=100
+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
-1+2-3+4+5+6+78+9

22 solutions for N=0

Smallest postive integer with no solution: 211

5 commonest sums (sum, number of ways to calculate to it):
L(L(9,46),L(27,44),L(15,43),L(1,43),L(21,43))