问题
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