Code Golf: All +-*/ Combinations for 3 integers

落爺英雄遲暮 提交于 2019-11-27 11:03:54

问题


Write a program that takes 3 integers separated by spaces and perform every single combination of addition, subtraction, multiplication and division operations possible and display the result with the operation combination used.

Example:

$./solution 1 2 3

Results in the following output

1+2+3 = 6

1-2-3 = -4

1*2*3 = 6

1/2/3 = 0 (integer answers only, round up at .5)

1*2-3 = -1

3*1+2 = 5

etc...

Order of operation rules apply, assume there will be no parenthesis used i.e. (3-1)*2 = 4 is not a combination, although you could implement this for "extra credit"

For results where a divide by 0 occurs simply return NaN

Edit: Permuting the input is required, i.e., if the input is 1 2 3, then 3*1*2 is a valid combination.


回答1:


Perl 130 chars

So long as external libraries are permitted:

use Algorithm::Permute"permute";
permute{for$x(@a=qw(+ - / *)){for$y(@a){$_="@ARGV";s/ /$x/;s/ /$y/;printf"
$_ = %.0f",eval}}}@ARGV

2nd newline is significant.

Without a module, and assuming that all three inputs are distinct, here's another solution:

      @n=&             ARGV;
      @o=(            q[+],
      "-",           q{/},         '*'     );;
      for$          {a}(@           n){   for
 $b(@n){for$c(@    {n}){             for $x( 
 @o){for$y(@o){   ($a-$  b)*($a-$c)*  ($b-$
 c)||next;$_=$a  .$x.$   b."$y$c";$%   =42
      /84+      eval;    print"",$_,  "$S="
      ,$S,     $%,$/                 }}} }};
      ;sub    ARGV{                 $S=   $".
      "";@   ARGV}                 ;1+     2+3



回答2:


Java - 666 characters

Has also oneliners, luckily we have Eclipse and Netbeans automatic code-format! :-) Also implemented parenthesis (but also contains trivial ops)?

public class CodeGolf{static String[]o={"+","-","/","*"};static void p(N a,int b,N c,int d,N e,int i){System.out.printf("%s%s(%s%s%s) = %s\n",a,o[b],c,o[d],e,new N(a,b,new N(c,d,e)));}public static void main(String[]v){N[]n={new N(v[0]),new N(v[1]),new N(v[2])};for(int i=0,j=0,k=0,l=0,m=0;m<3;i++,j+=i==4?1:0,i%=4,k+=j==4?1:0,j%=4,l+=k==3?1:0,k%=3,m+=l==3?1:0,l%=3){p(n[k],i,n[l],j,n[m],0);}}static class N{Double v;N(String s){v=v.parseDouble(s);}N(N a,int o,N b){if(a.v==null||b.v==null)return;double x=b.v, y=a.v; switch(o){case 0:x=-x;case 1:v=y-x;return;case 3:v=y*x;x=0;case 2:if(x!=0)v=y/x;}}public String toString(){return v!=null?""+Math.round(v):"NaN";}}}

Expanded, formatted, version with comments:

public class CodeGolf {

// operators
static String[] o = {"+", "-", "/", "*"};

// print
static void p(N a, int b, N c, int d, N e, int i) {
    System.out.printf("%s%s(%s%s%s) = %s\n", a, o[b], c, o[d], e,
            new N(a, b, new N(c, d, e))); // calculate
}

public static void main(String[] v) {
    N[] n = {new N(v[0]), new N(v[1]), new N(v[2])};
    // Nested for-loops? Nah, too much code!
    // Conditional operator, modulus is way cooler.
    for (int i = 0, j = 0,
             k = 0, l = 0, m = 0; m < 3; i++,
                                    j += i == 4 ? 1 : 0,
                                         i %= 4,
                               k += j == 4 ? 1 : 0,
                                    j %= 4,
                          l += k == 3 ? 1 : 0,
                               k %= 3,
                     m += l == 3 ? 1 : 0,
                          l %= 3) {
        p(n[k], i, n[l], j, n[m], 0);
    }
}

// number wrapper
static class N {

    Double v;

    // parse input
    N(String s) {
        v = v.parseDouble(s);
    }

    // calculate input
    N(N a, int o, N b) {
        // NaN's should fall through
        if (a.v == null || b.v == null) {
            return;
        }
        double x = b.v, y = a.v;
        // operator execution
        switch (o) {
            case 0:
                x = -x;
                // fall through; y + x = y - (-x)
            case 1:
                v = y - x;
                return; // break would make it 665 characters, not as cool
            case 3:
                v = y * x;
                x = 0;
                // fall through; no return needed
            case 2:
                if (x != 0) {
                    v = y / x;
                }
                // will NaN because v = null if x = 0
        }
    }

    // rounding and NaN
    public String toString() {
        return v != null ? "" + Math.round(v) : "NaN";
    }
}

}

Iterate on both operators (4 * 4) and permute on operands, twice (3! * 2) makes (4 * 4 * 3 * 2 * 2 = 192 possiblities).

+/- 2.5 hours :-) Enjoy!




回答3:


Delphi - 838 747 characters

Single Line Version (Original)

program p;{$APPTYPE CONSOLE}uses SysUtils;type g=Integer;function a(b,c:g):g;begin a:=b+c;end;function s(b,c:g):g;begin s:=b-c;end;function m(b,c:g):g;begin m:=b*c;end;function d(b,c:g):g;begin d:=b div c;end;type t=function(b,c:g):g;r=record f:t;c:char;p:boolean;end;procedure q(l:Array of g;w,e:r);var b:String;x,y,z:g;begin for x:=0 to 2 do for y:=0 to 2 do for z:=0 to 2 do if not((x=y)or(x=z)or(y=z))then begin try if(w.p)or not(w.p xor e.p)then b:=IntToStr(e.f(w.f(l[x],l[y]),l[z]))else b:=IntToStr(w.f(l[x],e.f(l[y],l[z])));except b:='NaN';end;writeln(l[x],w.c,l[y],e.c,l[z],'=',b);end;end;const O:Array[0..3]of r=((f:a;c:'+';p:false),(f:s;c:'-';p:false),(f:m;c:'*';p :true),(f:d;c:'/';p:true));var L:Array[0..2] of g;I,J:g; begin for I:=0 to 2 do L[I]:=StrToInt(ParamStr(I+1));for I:=0 to 3 do for J:=0 to 3 do q(l,o[I],o[J]);end.

Single Line Version (Shortened to 747 Characters)

program p;{$APPTYPE CONSOLE}uses SysUtils,Math;type g=integer;t=function(b,c:g):g;r=record f:t;p:boolean;end;function a(b,c:g):g;begin a:=b+c end;function s(b,c:g):g;begin s:=b-c end;function m(b,c:g):g;begin m:=b*c end;function d(b,c:g):g;begin d:=b div c end;const f=true;u=false;n=[1..4];b=[1..3];c='+-*/';O:Array[1..4]of r=((f:a;p:f),(f:s;p:f),(f:m;p:u),(f:d;p:u));var l: Array[1..3]of g;I,J,x,y,z:g;w,e:r;begin for I in b do l[I]:=StrToInt(ParamStr(I));for I in n do for J in n do for x in b do for y in b do for z in b do if not((x=y)or(x=z)or(y=z))then begin w:=O[I];e:=O[J];write(l[x],c[I],l[y],c[J],l[z],'=');try writeLn(ifthen(w.p or not(w.p xor e.p),e.f(w.f(l[x],l[y]),l[z]),w.f(l[x],e.f(l[y],l[z]))))except writeln('NaN')end;end;end.

Formated:

program p;
{$APPTYPE CONSOLE}
uses SysUtils;

type
  g = Integer;

function a(b, c: g): g;
begin
  a := b + c;
end;

function s(b, c: g): g;
begin
  s := b - c;
end;

function m(b, c: g): g;
begin
  m := b * c;
end;

function d(b, c: g): g;
begin
  d := b div c;
end;

type
  t = function(b, c: g): g;

  r = record
    f: t;
    c: char;
    p: boolean;
  end;

procedure q(l: Array of g; w, e: r);
var
  b: String;
  x, y, z: g;
begin
  for x := 0 to 2 do
    for y := 0 to 2 do
      for z := 0 to 2 do
        if not((x = y) or (x = z) or (y = z)) then
        begin
          try
            if (w.p) or not(w.p xor e.p) then
              b := IntToStr(e.f(w.f(l[x], l[y]), l[z]))
            else
              b := IntToStr(w.f(l[x], e.f(l[y], l[z])));
          except
            b := 'NaN';
          end;
          writeln(l[x], w.c, l[y], e.c, l[z], '=', b);
        end;
end;

const
  O: Array [0..3] of r = ((f: a; c: '+'; p: false), (f: s; c: '-'; p: false),
                            (f: m; c: '*'; p: true), (f: d; c: '/'; p: true));

var
  l: Array [0..2] of g;
  I, J: g;
begin

  for I := 0 to 2 do
    l[I] := StrToInt(ParamStr(I + 1));
  for I := 0 to 3 do
    for J := 0 to 3 do
      q(l, O[I], O[J]);

end.

This is by far the ugliest code I have ever written.




回答4:


J, 75 55 characters.

Outputs rational numbers, not integers.

(],"1'=',"1 ":@x:@".)((' ',>@{.),@,.":"0@>@{:)"1>{(,{;~'+-*%');<<"1(i.!3)A.

Old version which didn't permute the input (was 55 characters)

(],"1'=',"1 ":@x:@".)(>,{;~'+-*%')(' 'I.@:E.s)}"1 s=:":

Example (note that J's order of operations is right-to-left):

   (],"1'=',"1 ":@x:@".)((' ',>@{.),@,.":"0@>@{:)"1>{(,{;~'+-*%');<<"1(i.!3)A.1 2 3
 1+2+3=6   
 1+3+2=6   
 2+1+3=6   
 2+3+1=6   
 3+1+2=6   
 3+2+1=6   

 1+2-3=0   
 1+3-2=2   
 2+1-3=0   
 2+3-1=4   
 3+1-2=2   
 3+2-1=4   

 1+2*3=7   
 1+3*2=7   
 2+1*3=5   
 2+3*1=5   
 3+1*2=5   
 3+2*1=5   

 1+2%3=5r3 
 1+3%2=5r2 
 2+1%3=7r3 
 2+3%1=5   
 3+1%2=7r2 
 3+2%1=5   

 1-2+3=_4  
 1-3+2=_4  
 2-1+3=_2  
 2-3+1=_2  
 3-1+2=0   
 3-2+1=0   

 1-2-3=2   
 1-3-2=0   
 2-1-3=4   
 2-3-1=0   
 3-1-2=4   
 3-2-1=2   

 1-2*3=_5  
 1-3*2=_5  
 2-1*3=_1  
 2-3*1=_1  
 3-1*2=1   
 3-2*1=1   

 1-2%3=1r3 
 1-3%2=_1r2
 2-1%3=5r3 
 2-3%1=_1  
 3-1%2=5r2 
 3-2%1=1   

 1*2+3=5   
 1*3+2=5   
 2*1+3=8   
 2*3+1=8   
 3*1+2=9   
 3*2+1=9   

 1*2-3=_1  
 1*3-2=1   
 2*1-3=_4  
 2*3-1=4   
 3*1-2=_3  
 3*2-1=3   

 1*2*3=6   
 1*3*2=6   
 2*1*3=6   
 2*3*1=6   
 3*1*2=6   
 3*2*1=6   

 1*2%3=2r3 
 1*3%2=3r2 
 2*1%3=2r3 
 2*3%1=6   
 3*1%2=3r2 
 3*2%1=6   

 1%2+3=1r5 
 1%3+2=1r5 
 2%1+3=1r2 
 2%3+1=1r2 
 3%1+2=1   
 3%2+1=1   

 1%2-3=_1  
 1%3-2=1   
 2%1-3=_1  
 2%3-1=1   
 3%1-2=_3  
 3%2-1=3   

 1%2*3=1r6 
 1%3*2=1r6 
 2%1*3=2r3 
 2%3*1=2r3 
 3%1*2=3r2 
 3%2*1=3r2 

 1%2%3=3r2 
 1%3%2=2r3 
 2%1%3=6   
 2%3%1=2r3 
 3%1%2=6   
 3%2%1=3r2 



回答5:


C

600 bytes on disk with DOS line endings.

#define C B a,B b
#define D(N,O)B N(C){return a O b;}
#define E(A,B,C)i=A;j=B;k=C;X(m,p)X(m,m)X(t,t)X(d,t)X(t,d)X(d,d)Y(m,p)Y(p,p)Y(p,t)Y(p,d)Y(m,t)Y(m,d)
#define U"%.0f"
#define P(S,T)printf(U Z(S)U Z(T)U"="U"\n",v[i],v[j],v[k],
#define p +
#define m -
#define t *
#define d /
#define X(S,T)P(S,T)f##S(f##T(v[i],v[j]),v[k]));
#define Y(S,T)P(S,T)f##S(v[i],f##T(v[j],v[k])));
#define Z(A)#A
typedef double B;D(fp,+)D(fm,-)D(ft,*)B fd(C){return b?(int)(a/b+.5):-0.0;}main(int i,char*b[]){int j,k;B v[3]={atoi(b[1]),atoi(b[2]),atoi(b[3])};E(0,1,2)E(0,2,1)E(1,0,2)E(1,2,0)E(2,0,1)E(2,1,0)}

C doesn't seem to have NaN literals, so you get -0 if there's anything wrong rather than that.

However I think it fits the bill otherwise. (Note that the data type is double so that if it DID have a NaN in there, it will get printed out as such by printf.)




回答6:


Javascript, 169 characters

(not counting unnecessary line breaks and indentation)

Edit: Now with input permutation

o=" ";i=i.split(o);z="+-*/";for(y=0;y<27;y++)for(x=0;x<16;x++){a=y/9|0;b=(y/3|0)%3;c=y%3;if(a!=b&&a!=c&&b!=c){s=i[a]+z[x/4|0]+i[b]+z[x%4]+i[c];o+=s+"="+~~(eval(s)+.5);}}

With indentation:

o=" ";
i=i.split(o);
z="+-*/";
for(y=0;y<27;y++)
for(x=0;x<16;x++)
{
    a=y/9|0;
    b=(y/3|0)%3;
    c=y%3;
    if(a!=b&&a!=c&&b!=c)
    {
        s=i[a]+z[x/4|0]+i[b]+z[x%4]+i[c];
        o+=s+"="+~~(eval(s)+.5);
    }
}



回答7:


Python - 125 175 177 characters:

(not now counting indentation)
Added command-line input, no more single-digit/non-zero restriction, works with zero (NaN)

import sys
from itertools import permutations as p
for i,j,k in p(sys.argv[1:4],3):
    for x,y in p('+-*/'*2,2):
        s=i+x+j+'.'+y+k
        try:e=eval(s)
        except:e='NaN'
        print s,'=',e

Still No more truncates instead of rounding up at 0.5




回答8:


Haskell, 221 chars

Argh!!, imports takes 50 chars.

import Data.List
import System
import Text.Printf
o=zip[(+),(-),(*),(/)]"+-*/"
main=do v<-getArgs;sequence[printf"%.0g%c(%.0g%c%.0g)=%.0g\n"x h y i z$f x$g y z|(f,h)<-o,(g,i)<-o,[x,y,z]<-permutations(map read v::[Float])]

getArgs needs System, printf needs Text.Printf, permutations needs Data.List, the [[Float]] is needed because / needs an instance of Fractional. We can't use div because it will throw when divide by zero.

Basically this just iterates over all possible combinations of operators and permutations of input arguments and print the result.

The three %.0g can be replaced by %g to remove 6 chars, but the result will look like 1.0/(2.0*3.0)=0 which is ugly.


~$ ./a.out 0 4 9
0+(4+9)=13
4+(0+9)=13
9+(4+0)=13
4+(9+0)=13
9+(0+4)=13
0+(9+4)=13
0+(4-9)=-5
4+(0-9)=-5
9+(4-0)=13
4+(9-0)=13
9+(0-4)=5
0+(9-4)=5
0+(4*9)=36
4+(0*9)=4
9+(4*0)=9
4+(9*0)=4
9+(0*4)=9
0+(9*4)=36
0+(4/9)=0
4+(0/9)=4
9+(4/0)=Infinity
4+(9/0)=Infinity
9+(0/4)=9
0+(9/4)=2
0-(4+9)=-13
4-(0+9)=-5
9-(4+0)=5
4-(9+0)=-5
9-(0+4)=5
0-(9+4)=-13
0-(4-9)=5
4-(0-9)=13
9-(4-0)=5
4-(9-0)=-5
9-(0-4)=13
0-(9-4)=-5
0-(4*9)=-36
4-(0*9)=4
9-(4*0)=9
4-(9*0)=4
9-(0*4)=9
0-(9*4)=-36
0-(4/9)=-0
4-(0/9)=4
9-(4/0)=-Infinity
4-(9/0)=-Infinity
9-(0/4)=9
0-(9/4)=-2
0*(4+9)=0
4*(0+9)=36
9*(4+0)=36
4*(9+0)=36
9*(0+4)=36
0*(9+4)=0
0*(4-9)=-0
4*(0-9)=-36
9*(4-0)=36
4*(9-0)=36
9*(0-4)=-36
0*(9-4)=0
0*(4*9)=0
4*(0*9)=0
9*(4*0)=0
4*(9*0)=0
9*(0*4)=0
0*(9*4)=0
0*(4/9)=0
4*(0/9)=0
9*(4/0)=Infinity
4*(9/0)=Infinity
9*(0/4)=0
0*(9/4)=0
0/(4+9)=0
4/(0+9)=0
9/(4+0)=2
4/(9+0)=0
9/(0+4)=2
0/(9+4)=0
0/(4-9)=-0
4/(0-9)=-0
9/(4-0)=2
4/(9-0)=0
9/(0-4)=-2
0/(9-4)=0
0/(4*9)=0
4/(0*9)=Infinity
9/(4*0)=Infinity
4/(9*0)=Infinity
9/(0*4)=Infinity
0/(9*4)=0
0/(4/9)=0
4/(0/9)=Infinity
9/(4/0)=0
4/(9/0)=0
9/(0/4)=Infinity
0/(9/4)=0



回答9:


Bash shell, 126 - 169 - 156 - 140 characters

Should work in any semi-modern Bash I think (tested with GNU bash, 3.2.48(1) x86_64-apple-build).

Handles division by zero (Nan case).

All suggestions and comments welcome!

for a in $@;do
s+={`echo $@|tr ' ' ,`}{+,-,*,/};done
for i in `eval echo ${s::${#s}-9}`;do
[[ $i == */0* ]]&&y=Nan||y=$[$i];echo $i=$y;done

Supply parameters via command line:

./combinate.sh 5 0 12




回答10:


Ruby, 105 110 142 114 characters

o=%w{+ - * /};[*ARGV.permutation].product(o.product o).map{|x,y|e=x.zip(y)*"";p"#{e}=#{eval(e)rescue:N}"}

Usage

ruby prog.rb 1 2 3

Explanation

# o = ["+", "-", "*", "/"]
o=%w{+ - * /};
# ARGV = array of numbers. Generate all permutations, and apply splat operator
[*ARGV.permutation]
# Generate cartesian product of all permuted numbers and operators 
# There will be 16 operator permutations, and 6 number permutations giving a 
# total of 96 elements
.product(o.product o)
# For each of the 96 pairs, merge the operators and numbers into 1 array.
# ex - [1,2,3].zip(["+", "-"]) gives [[1, '+'], [2, '-'], [3, nil]]
# then convert the array to string by multiplying with "" => "1+2-3"
.each{|x,y|e=x.zip(y)*"";
# print output and eval result. On exception return infinity - ∞
p"#{e}=#{eval(e)rescue:N}"}

Output

1+2+3=6
1+2-3=0
1+2*3=7
1+2/3=1
1-2+3=2
1-2-3=-4
1-2*3=-5
1-2/3=1
1*2+3=5
1*2-3=-1
1*2*3=6
1*2/3=0
1/2+3=3
1/2-3=-3
1/2*3=0
1/2/3=0
1+3+2=6
1+3-2=2
1+3*2=7
1+3/2=2
1-3+2=0
1-3-2=-4
1-3*2=-5
1-3/2=0
1*3+2=5
1*3-2=1
1*3*2=6
1*3/2=1
1/3+2=2
1/3-2=-2
1/3*2=0
1/3/2=0
2+1+3=6
2+1-3=0
2+1*3=5
2+1/3=2
2-1+3=4
2-1-3=-2
2-1*3=-1
2-1/3=2
2*1+3=5
2*1-3=-1
2*1*3=6
2*1/3=0
2/1+3=5
2/1-3=-1
2/1*3=6
2/1/3=0
2+3+1=6
2+3-1=4
2+3*1=5
2+3/1=5
2-3+1=0
2-3-1=-2
2-3*1=-1
2-3/1=-1
2*3+1=7
2*3-1=5
2*3*1=6
2*3/1=6
2/3+1=1
2/3-1=-1
2/3*1=0
2/3/1=0
3+1+2=6
3+1-2=2
3+1*2=5
3+1/2=3
3-1+2=4
3-1-2=0
3-1*2=1
3-1/2=3
3*1+2=5
3*1-2=1
3*1*2=6
3*1/2=1
3/1+2=5
3/1-2=1
3/1*2=6
3/1/2=1
3+2+1=6
3+2-1=4
3+2*1=5
3+2/1=5
3-2+1=2
3-2-1=0
3-2*1=1
3-2/1=1
3*2+1=7
3*2-1=5
3*2*1=6
3*2/1=6
3/2+1=2
3/2-1=0
3/2*1=1
3/2/1=1



回答11:


Perl - 76 characters

$a=1;$b=2;$c=3;
warn eval for map{$x=$_;map"$a$x$b$_$c",@a}@a=split//,'+-/*';



回答12:


Lua - 240 characters

Note: Prints 1.#INF and -1.#INF instead of NaN.

a,b,c=...o="+-*/"f=function(...)g=table.concat({...})loadstring('x='..g)()print(g..' = '..math.floor(x+.5))end for d in o:gmatch(".")do for e in o:gmatch(".")do f(a,d,b,e,c)f(a,d,c,e,b)f(b,d,a,e,c)f(b,d,c,e,a)f(c,d,a,e,b)f(c,d,b,e,a)end end

Output

5+0+13 = 18
5+13+0 = 18
0+5+13 = 18
0+13+5 = 18
13+5+0 = 18
13+0+5 = 18
5+0-13 = -8
5+13-0 = 18
0+5-13 = -8
0+13-5 = 8
13+5-0 = 18
13+0-5 = 8
5+0*13 = 5
5+13*0 = 5
0+5*13 = 65
0+13*5 = 65
13+5*0 = 13
13+0*5 = 13
5+0/13 = 5
5+13/0 = 1.#INF
0+5/13 = 0
0+13/5 = 3
13+5/0 = 1.#INF
13+0/5 = 13
5-0+13 = 18
5-13+0 = -8
0-5+13 = 8
0-13+5 = -8
13-5+0 = 8
13-0+5 = 18
5-0-13 = -8
5-13-0 = -8
0-5-13 = -18
0-13-5 = -18
13-5-0 = 8
13-0-5 = 8
5-0*13 = 5
5-13*0 = 5
0-5*13 = -65
0-13*5 = -65
13-5*0 = 13
13-0*5 = 13
5-0/13 = 5
5-13/0 = -1.#INF
0-5/13 = 0
0-13/5 = -3
13-5/0 = -1.#INF
13-0/5 = 13
5*0+13 = 13
5*13+0 = 65
0*5+13 = 13
0*13+5 = 5
13*5+0 = 65
13*0+5 = 5
5*0-13 = -13
5*13-0 = 65
0*5-13 = -13
0*13-5 = -5
13*5-0 = 65
13*0-5 = -5
5*0*13 = 0
5*13*0 = 0
0*5*13 = 0
0*13*5 = 0
13*5*0 = 0
13*0*5 = 0
5*0/13 = 0
5*13/0 = 1.#INF
0*5/13 = 0
0*13/5 = 0
13*5/0 = 1.#INF
13*0/5 = 0
5/0+13 = 1.#INF
5/13+0 = 0
0/5+13 = 13
0/13+5 = 5
13/5+0 = 3
13/0+5 = 1.#INF
5/0-13 = 1.#INF
5/13-0 = 0
0/5-13 = -13
0/13-5 = -5
13/5-0 = 3
13/0-5 = 1.#INF
5/0*13 = 1.#INF
5/13*0 = 0
0/5*13 = 0
0/13*5 = 0
13/5*0 = 0
13/0*5 = 1.#INF
5/0/13 = 1.#INF
5/13/0 = 1.#INF
0/5/13 = 0
0/13/5 = 0
13/5/0 = 1.#INF
13/0/5 = 1.#INF



回答13:


F#: 280 chars, incl. newlines

The unreadable version:

let q s=System.Data.DataTable().Compute(s,"")|>string|>float
let e(a,b,c)=let o=["+";"-";"*";"/"]in for x in o do for y in o do let s=a+x+b+y+c in printfn"%s=%.0f"s (q s)
[<EntryPoint>]let p(A:_[])=(for i=0 to 2 do let p,q,r=A.[i],A.[(i+1)%3],A.[(i+2)%3]in e(p,q,r);e(p,r,q));0

The tl;dr version:

//This program needs to be compiled as a console project
//It needs additional references to System.Data and System.Xml

//This function evaluates a string expression to a float
//It (ab)uses the Compute method of System.Data.DataTable which acts 
//as .Net's own little eval()
let q s =
    //the answer is an object
    System.Data.DataTable().Compute(s,"")
    //so convert it to a string and then parse it as a float
    |> string
    |> float

//This function first generates all 6 permutations of a 3-tuple of strings
//and then inserts all operator combination between the entries
//Finally it prints the expression and its evaluated result
let e (a,b,c) =
    let o = ["+";"-";"*";"/"] 
    //a double loop to get all operator combos
    for x in o 
        do for y in o do 
            let s=a+x+b+y+c //z is expression to evaluate
            //print the result as expression = result, 
            //the %.0f formatter takes care of rounding
            printfn "%s=%.0f" s (q s)

//This is the entry point definition. 
//A is the array of command line args as strings.
[<EntryPoint>]
let p(A:_[]) = 
    //Generate all permutations: 
    //for each index i: 
    //  put the i-th element at the front and add the two remaining elements
    //  once in original order and once swapped. Voila: 6 permutations.
    for i=0 to 2 do 
        let p,q,r = A.[i], A.[(i+1)%3], A.[(i+2)%3] 
        e(p,q,r) //evaluate and print "p + <op> + q + <another op> + r"
        e(p,r,q) //evaluate and print "p + <op> + r + <another op> + q"
    0 //the execution of the program apparently needs to return an integer

Example output:

> ConsoleApplication1 1 2 0
1+2+0=3
1+2-0=3
1+2*0=1
1+2/0=Infinity
1-2+0=-1
1-2-0=-1
1-2*0=1
1-2/0=-Infinity
1*2+0=2
1*2-0=2
1*2*0=0
1*2/0=Infinity
1/2+0=1
1/2-0=1
1/2*0=0
1/2/0=Infinity
1+0+2=3
1+0-2=-1
1+0*2=1
1+0/2=1
...



回答14:


OK, it's not really short, but I post it anyway, just for fun...

Note that unlike most other answers, this one doesn't use eval since it's not available in C# (it would be much shorter with it)

C#, 729 chars

using System;using System.Linq;using w=System.Double;class Op{public char c;public int p;public Func<w,w,w>f;}class Program{static void Main(string[]p){var nb=p.Select((n,i)=>new{n=w.Parse(n),i});var op=new[]{new Op{c='+',p=0,f=(a,b)=>a+b},new Op{c='-',p=0,f=(a,b)=>a-b},new Op{c='*',p=1,f=(a,b)=>a*b},new Op{c='/',p=1,f=(a,b)=>a/b},};Func<Op,Op,Func<w,w,w,w>>fg=(o1,o2)=>(x,y,z)=>o1.p>=o2.p?o2.f(o1.f(x,y),z):o1.f(x,o2.f(y,z));Func<w,w>nan=d=>w.IsInfinity(d)?w.NaN:d;var res=from o1 in op from o2 in op from x in nb from y in nb where x.i!=y.i from z in nb where z.i!=x.i&&z.i!=y.i let r=nan(fg(o1,o2)(x.n,y.n,z.n))select string.Format("{0}{1}{2}{3}{4}={5:F0}",x.n,o1.c,y.n,o2.c,z.n,r);res.ToList().ForEach(Console.WriteLine);}}

Expanded version

using System;
using System.Linq;
using w=System.Double;

// Operator class
// c = character
// p = priority
// f = function
class Op { public char c; public int p; public Func<w, w, w> f; }
class Program
{
    static void Main(string[] args)
    {
        // Parse the input and associate each number with its index
        var nb = args.Select((n, i) => new { n = w.Parse(n), i });

        // Operators definition
        var op = new[]
        {
            new Op { c = '+', p = 0, f = (a, b) => a + b },
            new Op { c = '-', p = 0, f = (a, b) => a - b },
            new Op { c = '*', p = 1, f = (a, b) => a * b },
            new Op { c = '/', p = 1, f = (a, b) => a / b },
        };

        // Function generator to compute the result ; handles operator priority
        Func<Op, Op, Func<w, w, w, w>> fg =
            (o1, o2) =>
                (x, y, z) =>
                    o1.p >= o2.p
                        ? o2.f(o1.f(x, y), z)
                        : o1.f(x, o2.f(y, z));

        // Converts +/- Infinity to NaN
        Func<w, w> nan = d => w.IsInfinity(d) ? w.NaN : d;

        // Results
        var res =
            // Combinations of 2 operators
            from o1 in op
            from o2 in op
            // Permutations of numbers
            from x in nb
            from y in nb
            where x.i != y.i
            from z in nb
            where z.i != x.i && z.i != y.i
            // Compute result
            let r = nan(fg(o1, o2)(x.n, y.n, z.n))
            // Format output
            select string.Format("{0} {1} {2} {3} {4} = {5:F0}", x.n, o1.c, y.n, o2.c, z.n, r);

        res.ToList().ForEach(Console.WriteLine);
    }
}

Who said you can't do functional programming in C# ? ;)


EDIT : fixed to make it work with duplicate numbers




回答15:


Ruby

(reads from argument list and returns NaN if not divisible)

(would be only the last line if ruby had a permutation library)

class Array
  def perm(n = size)
    if size < n or n < 0
    elsif n == 0
      yield([])
    else
      self[1..-1].perm(n - 1) do |x|
        (0...n).each do |i|
          yield(x[0...i] + [first] + x[i..-1])
        end
      end
      self[1..-1].perm(n) do |x|
        yield(x)
      end
    end
  end
end

ARGV.perm(3){|a,b,c| "++//**--".split(//).perm(2){ |d,e| x=a+d+b+e+c;puts "#{x} = #{eval(x)}" rescue puts "#{x} = NaN"} }



回答16:


Python (171 characters)

This avoids shortfalls of previous python solution (hard-coded 1-digit numbers only, dependency on newer libraries). Reads from stdin - if you want cmdline, replace "raw_input().split()" with "sys.argv[1:4]"

x=raw_input().split()
for e in[x[i/3]+p+x[i%3]+'.'+q+x[3-i/3-i%3]for i in range(9)if i%4for p in'+-*/'for q in'+-*/']:
    try:r=round(eval(e))
    except:r='NaN'
    print e,'=',r

ps. decreased to 147->138
pps. changed calculations from int to float w/rounding, 138->153
ppps. added support for /0=NaN, 153->179
pppps. decreased 179->177 ppppps. sacrificed beauty for brevity, 177->171




回答17:


F#, 584 bytes

(includes necessary indentation and LFs)

let d a b=if b=0.0 then nan else a/b
let o=["*",((*),1);"+",((+),0);"/",(d,1);"-",((-),0)]
let b=double
let rec z=function|[x]->[x,[]]|x::s->(x,s)::List.map(fun(y,l)->y,x::l)(z s)
let rec p=function|[]->[[]]|l->z l|>List.collect(fun(x,r)->p r|>List.map(fun l->x::l))
let f=fst
let e o p x y z=if snd o<snd p then (f o)x ((f p) y z) else (f p)((f o) x y)z
[<EntryPoint>]let m a=
for i in p(Seq.toList a)do
 let x,y,z=b i.[0],b i.[1],b i.[2]
 for j in[for j in o do for k in o do yield[j;k]]do
  printfn "%.0f%s%.0f%s%.0f = %.0f" x (f j.[0])y (f j.[1])z (e(snd j.[0])(snd j.[1])x y z)
0

Kudos to kvb for his/her permutations function.

It wound up being quite similar in structure to Thomas' C# solution (maybe because his solution is already quite functional)



来源:https://stackoverflow.com/questions/2960242/code-golf-all-combinations-for-3-integers

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!