数学教学武器


44

上一次,当我试图提出一些并非重复的简单尝试时,结果却变得太难了。所以希望这次,确实是新手也可以尝试的尝试。

输入:

具有整数/小数的数组/列表。(或一个表示整数/小数的数组的字符串。)

输出:

遍历数字并按以下顺序应用以下五个数学操作数:

  • 加法(+);
  • 减法();
  • 乘法(*×·);
  • 实数/计算器部(/÷);
  • 取幂(^**)。

(注意:括号中的符号只是为了说明而添加。如果您的编程语言对数学运算使用的符号与示例所使用的符号完全不同,那么这当然是完全可以接受的。)

继续进行操作,直到到达列表的末尾,然后给出总和的结果。

挑战规则:

  • 用0(n ^ 0)求幂应该得到1(这也适用于0 ^ 0 = 1)。
  • 没有用0(n / 0)除的测试用例,因此您不必担心这种边缘情况。
  • 如果数组仅包含一个数字,则将其作为结果返回。

通用规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能简短的答案。
  • 标准规则适用于您的答案,因此允许您使用STDIN / STDOUT,具有正确参数的函数/方法,完整程序。您的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接。

测试用例:

[1,2,3,4,5] -> 0
-> 1 + 2 = 3
  -> 3 - 3 = 0
    -> 0 * 4 = 0
      -> 0 / 5 = 0 

[5,12,23,2,4,4,2,6,7] -> 539
-> 5 + 12 = 17
  -> 17 - 23 = -6
    -> -6 * 2 = -12
      -> -12 / 4 = -3
        -> -3 ^ 4 = 81
          -> 81 + 2 = 83
            -> 83 - 6 = 77
              -> 77 * 7 -> 539

[-8,50,3,3,-123,4,17,99,13] -> -1055.356...
-> -8 + 50 = 42
  -> 42 - 3 = 39
    -> 39 * 3 = 117
      -> 117 / -123 = -0.9512...
        -> -0.9512... ^ 4 = 0.818...
          -> 0.818... + 17 = 17.818...
            -> 17.818... - 99 -> -81.181...
              -> -81.181... * 13 = -1055.356...

[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256
-> 2 + 2 = 4
  -> 4 - 2 = 2
    -> 2 * 2 = 4
      -> 4 / 2 = 2
        -> 2 ^ 2 = 4
          -> 4 + 2 = 6
            -> 6 - 2 = 4
              -> 4 * 2 = 8
                -> 8 / 2 = 4
                  -> 4 ^ 2 = 16
                    -> 16 + 2 = 18
                      -> 18 - 2 = 16
                        -> 16 * 2 = 32
                          -> 32 / 2 = 16
                            -> 16 ^ 2 = 256

[1,0,1,0,1,0] -> 1
-> 1 + 0 = 1
  -> 1 - 1 = 0
    -> 0 * 0 = 0
      -> 0 / 1 = 0
        -> 0 ^ 0 = 1

[-9,-8,-1] -> -16
  -> -9 + -8 = -17
    -> -17 - -1 = -16

[0,-3] -> -3
  -> 0 + -3 = -3

[-99] -> -99

不是整数除法?
Leaky Nun

@LeakyNun否。由于除法(以及测试用例3),也许我应该将输入更改为带有小数而不是整数的列表?
凯文·克鲁伊森

这是在沙盒中吗?
巴林特

9
在数学中,有两个相互冲突的“规则”:n ^ 0 = 1,但0 ^ n = 0。可以通过设置n != 0两个规则来解决冲突,但此后0 ^ 0未定义。但是,如果0 ^ 0定义为,则数学中有很多事情可以很好地解决1。有关更多详细信息,请参见Wikipedia
Mego

1
@Bálint规则规定,永远不会有被零除的有效输入。您不必担心这种情况。
Mego

Answers:


7

果冻,13 个字节

“+_×÷*”ṁṖ⁸żFV

在线尝试!验证所有测试用例

这个怎么运作

“+_×÷*”ṁṖ⁸żFV  Main link. Argument: A (list of integers)

“+_×÷*”        Yield the list of operations as a string.
        Ṗ      Yield A popped, i.e., with its last element removed.
       ṁ       Mold; reshape the string as popped A.
               This repeats the characters of the string until it contains
               length(A)-1 characters.
         ⁸ż    Zipwith; pairs the integers of A with the corresponding characters.
           F   Flatten the result.
            V  Eval the resulting Jelly code.
               Jelly always evaluates left-to-right (with blatant disregard towards
               the order of operations), so this returns the desired result.

很好,这比当前处于领先地位的Pyke少了 8个字节数。
凯文·克鲁伊森

3
没有人超越丹尼斯。决不。
2016年

1
只是一个问题:所有非ASCII字符真的算作13 个字节吗?
Xavier Dury

3
@XavierDury是的。标头中的字节链接指向Jelly自己的代码页,该页将Jelly理解为每个字节的256个字符编码。
丹尼斯

@Dennis谢谢您的精确!
Xavier Dury

19

Javascript ES7 49字节

a=>a.reduce((c,d,e)=>[c**d,c+d,c-d,c*d,c/d][e%5])

Dom Hastings节省了9个字节,Leaky Nun节省了6个字节

使用新的幂运算符。


@LeakyNun不会只是产生Infinity,不是错误?
Dom Hastings

尝试使用eval可能会更短
Downgoat

@Upgoat它使用的eval,再破修女给我看,这是更好,做这样的
巴林特

@Bálint,您喜欢使用很多逗号吗?
Rɪᴋᴇʀ

1
@EᴀsᴛᴇʀʟʏIʀᴋ非母语人士。巴林特经常这样做。最好的时候英语语法很愚蠢。
wizzwizz4 2016年

11

Haskell,76 65 64 62字节

感谢@Damien删除了另外两个字节=)

f(u:v)=foldl(\x(f,y)->f x y)u(zip(v>>[(+),(-),(*),(/),(**)])v)

这使用>>此处只是将列表添加[(+),...]到自身length v时间的。其余的仍然与旧版本相同。

旧版本:

这些解决方案利用无限列表,就像无限地cycle[...]重复给定列表一样。然后,它基本上得到zip了数字列表,然后我们通过lambda fold(用其他语言减少)压缩列表,该运算符将运算符应用于累加器/当前列表元素。

f(u:v)=foldl(\x(f,y)->f x y)u(zip(cycle[(+),(-),(*),(/),(**)])v)

f(u:v)=foldl(\x(y,f)->f x y)u(zip v(cycle[(+),(-),(*),(/),(**)]))

f l=foldl(\x(y,f)->f x y)(head l)(zip(drop 1l)(cycle[(+),(-),(*),(/),(**)]))

您可以将周期替换为:v >>
Damien

@Damien非常感谢!
瑕疵的

foldl(&)u$zipWith(&)v(flip<$>v>>[…])
Bergi

@Bergi,老实说,我现在无法看清它正在做什么=)无论如何,我们需要一个importfor &,这样会更长一些,但是无论如何都要感谢!
瑕疵的

@flawr:实际上,我的想法与Lazersmoke发布的答案完全相同,我只是没有读过。当我想用类似的东西简化你的那个lamda时,我明白了uncurry。没有解决问题,但是我注意到您应该可以使用$而不是括号来保存另一个字节。
Bergi

8

Pyke,22 21字节

lt5L%"+-*/^"L@\RJQ_XE

在这里尝试!

lt5L%                 -    map(len(input)-1, %5)
     "+-*/^"L@        -   map(^, "+-*/^"[<])
              \RJ     -  "R".join(^)
                    E - pyke_eval(^, V)
                 Q_X  -  splat(reversed(input))

7

Haskell,61字节

foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])

在列表中创建一系列转换,如[添加1,添加2,减去3,...]一样,从2个添加项开始,因为我们在折数中以0开始。接下来,我们执行所谓的List Application Fold(列表应用程序折叠)或foldl(翻页ID),它连续应用一系列同态列表。这从零开始,加上初始值,然后进行所有上述计算的转换以获得最终结果。

请注意,(flip id)与(\ x y-> yx)相同​​,只是更短。

用法示例:

f = foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])
f [1,2,3,4,5] -- Is 0.0

相反flip id,您可以简单地使用&。或者flip($)。哇,我没意识到($) = id
Bergi

1
@Bergi:&是在中定义的Data.Function,因此您也需要import。也许某些在线解释器默认情况下会导入它,但是随后您需要指定使用哪个解释器。
nimi

7

TSQL 116 115 88字节

感谢Ross Presser的建议,我能够打高尔夫球到88个字符

-- In Try-it code, this must be DECLARE @y TABLE 
CREATE TABLE T(a real, i int identity)
INSERT T values(5),(12),(23),(2),(4),(4),(2),(6),(7)

DECLARE @ REAL SELECT @=CHOOSE(i%5+1,@/a,ISNULL(POWER(@,a),a),@+a,@-a,@*a)FROM T
PRINT @

在线尝试


1
少1个字节:要求输入表命名为T而不是@y。PL / SQL解决方案具有此功能,所以为什么不使用TSQL。
Ross Presser 2016年

@RossPresser当然可以。我怎么想念的。在测试链接中是不可能的,没有创建表的权限,并且只能在第一次在数据库上正确运行。但是,当一个角色可以打高尔夫球时,那有什么关系呢?感谢您的提示,您的改进有所添加
t-clausen.dk 2016年

打出另外12个字节:使用CHOOSE而不是嵌套的IIF,在i = 1的情况下保留一个IIF。经您允许,我将编辑答案。
Ross Presser 2016年

答案已编辑。这是try-it链接-我是匿名用户,因此之后没有名字:data.stackexchange.com/stackoverflow/query/edit/499612
Ross Presser

1
@RossPresser我不知道选择。包括您的建议并进一步
推广

6

Pyth,27 26 25字节

.v+>tlQ*lQ"^c*-+":jdQ\-\_

测试套件。

Pyth使用前缀表示法:1+2写为+1 2(分隔数字所需的空格)。

因此,对于第一个测试用例,表达式将为(((1+2)-3)*4)/5,用前缀表示法将表示为/*-+ 1 2 3 4 5

在Pyth中,浮点除法c代替/,因此变为c*-+ 1 2 3 4 5

另外,在Pyth中-100也写成_100

因此,对于第三个测试用例((((((((-8+50)-3)*3)/-123)^4)+17)-99)*13),它变为:*-+^c*-+ _8 50 3 3 _123 4 17 99 13

.v+>tlQ*lQ"^c*-+":jdQ\-\_
                  jdQ       Join input by space.
                 :   \-\_   Replace "-" with "_".
   >tlQ*lQ"^c*-+"           Generate the string "...^c*-+" of suitable length.
  +                         Join the two strings above.
.v                          Evaluate as a Pyth expression.

历史


你很快!似乎我成功地提出了一个简单的挑战。或者,你就是那样的好。;)
Kevin Cruijssen



6

其实是23个位元组

;l"+-*/ⁿ"*@R':j':+'?o+ƒ

在线尝试!

实际上对数学使用了后缀表示法,并且仅使用两个自变量的运算符(例如加,减,乘,除和乘幂运算符)在堆栈上只有一个元素时不执行任何操作。因此,将输入转换为“实际”代码就像反转输入,将其格式化为数字并附加操作一样简单。然后,可以执行结果代码,以提供所需的输出。

说明:

;l"+-*/ⁿ"*@R':j':+'?o+ƒ
;l"+-*/ⁿ"*               repeat the operations a number of times equal to the length of the input
                            (since extraneous operations will be NOPs, there's no harm in overshooting)
          @R             reverse the input
            ':j          join on ":" (make a string, inserting ":" between every pair of elements in the list)
               ':+       prepend a ":" (for the first numeric literal)
                  '?o    append a "?"
                           (this keeps the poor numeric parsing from trying to gobble up the first + as part of the numeric literal, since ? isn't interpreted as part of the literal, and is a NOP)
                     +   append the operations string
                      ƒ  cast as a function and call it

输入的翻译代码示例1,2,3,4,5

:5:4:3:2:1?+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ

3
爱语言名称与字节数合并的方式
user6245072

3
s/Actually uses postfix notation/Actually actually uses postfix notation/
Leaky Nun


5

J,40个字节

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)

查找使用5个运算符的倍数所需的值数,而不是填充这些运算符的标识值。为了,+是0,-是0,*是1时,%是1,且^是1,它可以是一个比特的值00111,或7基座10而经由运营商循环该列表上。然后进行操作。

用法

   f =: ^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)
   f 1 2 3 4 5
0
   f 5 12 23 2 4 4 2 6 7
539
   f _8 50 3 3 _123 4 17 99 13
_1055.36
   f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
256
   f 1 0 1 0 1 0
1
   f _9 _8 _1
_16
   f 0 _3
_3
   f _99
_99

说明

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#) Input: A
                                      #  Get length of A
                                    4+   Add four to it
                                  5|     Take it mod 5
                                5-       Find 5 minus its value, call it x
                           #&2           Create x copies of 2
                       7#:~              Convert 7 to base 2 and take the last x digits
                      ,                  Append those x digits to the end of A
                   |.@                   Reverse it, call it A'
^~                                       Power, reversed operators
    %~                                   Division, reversed operators
       *                                 Multiplication
         -~                              Subtraction, reversed operators
            +                            Addition
             /@                          Insert the previous operations, separated by `,
                                         into A' in order and cycle until the end
                                         Then evaluate the equation from right-to-left
                                         and return

5

Python 2,81 67 64字节

i=10
for n in input():exec'r%s=n'%'*+-*/*'[i::5];i=-~i%5
print r

输入是一个浮点数数组。在Ideone上进行测试

这个怎么运作

'*+-*/*'[i::5]选择的字符串的每个第五个字符,从一个在索引,所以这个收率**,如果I = 0+如果I = 1-如果I = 2*如果I = 3/如果I = 4。由于字符串的长度为6,因此如果i> 5则表达式将生成一个空字符串。

我们将变量i初始化为10。对于每个数Ñ输入数组中,我们构建了串r<op>=n,其exec执行。

最初,I = 10,因此<op>是空字符串,并将其初始化řr+=n。每个步骤后,我们增加5i=-~i%5,所以下一步将检索正确的操作。

处理完所有输入数字后,我们打印r,其中保留了所需的输出。


5

Matlab- 95 91 85字节/八度-81字节

输入是这样的形式:a = ['1' '2' '3' '4' '5'];,我希望它被“用整数/小数表示的数组的字符串”覆盖,否则还需要2 num2str。

每个中间结果都会打印到控制台,因为这样可以节省一些分号。a(1)被执行,因此其值保存到ans。当然,ans在代码中使用也是不好的做法。

b='+-*/^'
a(1)
for i=2:length(a)
  ['(',ans,')',b(mod(i-2,5)+1),a(i)]
end
eval(ans)

在Octave中,'+-*/^'(mod(i+2,5)+1)也可以使用,另外节省了4个字节,这要感谢Adám和Luis Mendo:

a(1)
for i=2:length(a)
  strcat('(',ans,')','+-*/^'(mod(i-2,5)+1),a(i))
end
eval(ans)

变更日志:

  • 尽可能删除空间
  • 添加了倍频程解决方案
  • 用[]替换了strcat()

嗨,欢迎来到PPCG!这样的输入就很好了,因为仍然可以轻松区分输入是什么。嗯,我从来没有使用Matlab的,所以也许我在这里说愚蠢的事情,但不能b = '+-*/^'被golfed到b='+-*/^'for i = 2:length(a)for i=2:length(a)(删除空格)?另外,也许您对MATLAB中打高尔夫球的技巧感兴趣。:)
Kevin Cruijssen

是否'+-*/^'(mod(i+2,5)+1)有效?
亚当

@Adám不,但可能在八度
Luis

@Adám:它在Octave中有效,我添加了它。
Lukas K.

4

Mathematica,67 66 65字节

Fold[{+##,#-#2,#2#,#/#2,If[#2==0,1,#^#2]}[[i++~Mod~5+1]]&,i=0;#]&

简单Fold,变量i包含索引。


可以保存一个字节,+##而不是#+#2
LLlAMnYP

4

CJam,18个字节

q~{"+-*/#"W):W=~}*

输入是一个浮点数数组。在线尝试!

这个怎么运作

q~                  Read and evaluate all input.
  {             }*  Reduce:
   "+-*/#"            Push the string of operators.
          W           Push W (initially -1).
           ):W        Increment and save in W.
              =       Retrieve the character at that index.
               ~      Evaluate.


3

哈斯克尔-74

f(x:xs)=foldl(\x(o,y)->o x y)x(zip(cycle[(+),(-),(*),(/),flip(^).floor])xs)

测试用例:

λ> f[1,2,3,4,5] -> 0.0
λ> f[5,12,23,2,4,4,2,6,7] -> 539.0
λ> f[-8,50,3,3,-123,4,17,99,13] -> -1055.356943846277
λ> f [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256.0

它可能会更短;但是,Haskell对无限列表和高阶函数的支持使直接解决方案变得非常令人愉快。一个版本的^ :: Double -> Double -> Double高尔夫球会更好,但是我找不到。值得庆幸的是,我不需要完整的lambda,因此毫无意义的样式减少了几个字节。


2
您可以(+)在运算符列表前添加一个,然后以开始foldl0使其完全没有意义,并保存函数名称和参数:foldl(\x(o,y)->o x y)0.zip((+):cycle[(+),(-),(*),(/),(**)])
nimi

3

PowerShell v2 +,124个字节

param($n)$o=$n[0];if($y=$n.count-1){1..$y|%{$o=if(($x=$i++%5)-4){"$o"+'+-*/'[$x]+$n[$_]|iex}else{[math]::pow($o,$n[$_])}}}$o

很长一段时间,因为PowerShell没有^or **运算符,所以我们必须考虑一个单独的情况并使用.NET调用。

将输入$n作为数组,将输出$o设置为第一位。然后,我们检查.count数组的,只要它大于一个,就输入if。否则,我们跳过if

if数组内部循环1..$y|%{...},每次迭代时,我们将其重置$o为新值,即另一条if/else语句的结果。只要我们的计数器$i++的5模不等于4(即我们不在^运算符处),我们就可以简单地将$o其与适当的符号'+-*/'[$x]和输入数组中的下一个数字连接起来$n[$_]。我们将其通过管道输送到iex(别名Invoke-Expression并类似于eval),然后重新保存到$o。如果我们在^运算符上,那么我们在中else,因此我们执行一个[math]::Pow()调用,然后结果重新保存到中$o

无论哪种情况,我们都只输出$o到管道并退出,而输出是隐式的。


3

锈,123,117个字节

原始答案:

fn a(v:&[f32])->f32{v.iter().skip(1).enumerate().fold(v[0],|s,(i,&x)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

愚蠢的长方法名^^嗯好多了

fn f(v:&[f32])->f32{v[1..].iter().zip(0..).fold(v[0],|s,(&x,i)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

不打高尔夫球

fn f(values : &[f32]) -> f32 {
    values[1..].iter().zip(0..)
    .fold(values[0], |state,(&x,i)|
        match i%5 {
            0=>state+x,
            1=>state-x,
            2=>state*x,
            3=>state/x,
            _=>state.powf(x)
        }
    )
}

3

Perl 6的 70个68 65   62字节

{$/=[(|(&[+],&[-],&[*],&[/],&[**])xx*)];.reduce: {$/.shift.($^a,$^b)}}
{(@_ Z |(&[+],&[-],&[*],&[/],&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{(@_ Z |(*+*,*-*,&[*],*/*,&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],*/*,&[**])xx*}

说明:

-> *@_ {
  reduce
    -> $a, &b, $c { b($a,$c) },

    flat       # flatten list produced from zip
      zip
        @_,    # input

        slip(  # causes the list of operators to flatten into the xx list

          # list of 5 infix operators
          &infix:<+>, &infix:<->, &infix:<*>, &infix:</>, &infix:<**>

        ) xx * # repeat the list of operators infinitely
}

从技术上讲,它* + *是一个任意lambda,但实际上与处理infix数字加法的子例程集的&[+]缩写相同&infix:<+>
我没有使用乘法或幂的方式来写他们喜欢就是至少只要我有什么(*×** * ** ** *

测试:

ideone.com上进行测试
(在升级到Rakudo版本之后,该版本距离Perl 6 spectests的正式发布已经一年半了)

#! /usr/bin/env perl6

use v6.c;
use Test;

my @tests = (
  [1,2,3,4,5] => 0,
  [5,12,23,2,4,4,2,6,7] => 539,
  [-8,50,3,3,-123,4,17,99,13] => -1055.35694385, # -2982186493/2825761
  [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] => 256,
  [1,0,1,0,1,0] => 1,
  [-9,-8,-1] => -16,
  [0,-3] => -3,
  [-99] => -99,
);

plan +@tests;

my &code = {reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],&[/],&[**])xx*}

for @tests -> $_ ( :key(@input), :value($expected) ) {
  is code(@input), $expected, .gist
}
1..8
ok 1 - [1 2 3 4 5] => 0
ok 2 - [5 12 23 2 4 4 2 6 7] => 539
ok 3 - [-8 50 3 3 -123 4 17 99 13] => -1055.35694385
ok 4 - [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] => 256
ok 5 - [1 0 1 0 1 0] => 1
ok 6 - [-9 -8 -1] => -16
ok 7 - [0 -3] => -3
ok 8 - [-99] => -99


3

Python 3,88 93字节

f=lambda x:eval('('*(len(x)-1)+'){}'.join(map(str,x)).format(*['+','-','*','/','**']*len(x)))

它起初要短得多,但后来运算符优先级击败了我,我不得不加上很多括号...


3

Oracle PL / SQL,275254字节

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

数据必须插入T具有N类型列的表中NUMBER

用法:

drop table t;
create table t (n number);
insert into t values (-8);
insert into t values (50);
insert into t values (3);
insert into t values (3);
insert into t values (-123);
insert into t values (4);
insert into t values (17);
insert into t values (99);
insert into t values (13);

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

输出:

-1055,356943846277162152071601242992595623

275字节版本:

declare r number;cursor c is select n,mod(rownum,5) r from t;begin for x in c loop if r is null then r:=x.n;else case x.r when 2 then r:=r+x.n;when 3 then r:=r-x.n;when 4 then r:=r*x.n;when 0 then r:=r/x.n;else r:=r**x.n; end case;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

3

爪哇8,173个 172 167 138 137 118 113字节

a->{double r=a[0],t;for(int i=1;i<a.length;r=new double[]{Math.pow(r,t),r+t,r-t,r*t,r/t}[i++%5])t=a[i];return r;}

说明:

在这里尝试。

a->{                     // Method with double-array parameter and double return-type
  double r=a[0],         //  Result-double, starting at the first item of the input
         t;              //  Temp double
  for(int i=1;           //  Index-integer, starting at the second item
      i<a.length;        //  Loop over the input-array
      r=new double[]{    //    After every iteration, change `r` to:
         Math.pow(r,t),  //      If `i%5` is 0: `r^t`
         r+t,            //      Else-if `i%5` is 1: `r+t`
         r-t,            //      Else-if `i%5` is 2: `r-t`
         r*t,            //      Else-if `i%5` is 3: `r*t`
         r/t}[i++%5])    //      Else-if `i%5` is 4: `r/t`
                         //      And increase `i` by 1 afterwards with `i++`
    t=a[i];              //   Change `t` to the next item in the array
  return r;}             //  Return result-double

2
因为,你知道,java.1.5倍,比目前的最长的答案....至极是SQL更长
巴林特

1
您可以更改double r=a[0];double r=a[0],b;保存一些字节。
Leaky Nun

1
@LeakyNun最初我有float,但是没有Math.pow用于float的,因此double改为。谢谢你,b。并与i++<a.length我得到一个ArrayOutOfBoundsExceptionb=a[i];(除非我做的i++<a.length-1相反,这是一个字节,而不是更短长)。
凯文·克鲁伊森

1
您可以更改== 4> 3== 0< 1。我不确定,但我认为您可以通过为创建变量来节省一些时间i % 5
Frozn

1
我认为您可以将整个事情更改为三元级联。然后,在所有比较中,您都可以使用该<x技巧,将整个功能缩小到137个字符。
Frozn

3

一些技巧可以将@Willmore的方法减少23到174个字节(需要php 5.6或更高版本)。最节省的部分是删除不必要的括号(-10个字节)。

函数f($ a){while(count($ a)> 1){$ l = array_shift($ a); $ r = array_shift($ a); array_unshift($ a,($ j = $ i ++%5) ?($ j == 1?$ l- $ r:($ j == 2?$ l * $ r:($ j == 3?$ l / $ r:$ l ** $ r))): $ l + $ r);}返回结尾($ a);}

但是使用**运算符代替pow()允许eval与数组一起使用;还有一些技巧...

PHP> = 5.6,82字节

while(--$argc)eval('$x'.['/','**','+','-','*'][$i++?$i%5:2]."=$argv[$i];");echo$x;

从命令行参数获取列表。运行php -nr '<code>'在线尝试

旧版本,161157151145144140137117字节

function f($a){while(count($a)>1)eval('$a[0]=array_shift($a)'.['+','-','*','/','**'][$i++%5].'$a[0];');return$a[0];}

打高尔夫球最有效的方法是将中间结果直接写入第一个元素-将先前的结果从数组中移出之后。

分解

function f($a)
{
    while(count($a)>1)  // while array has more than one element ...
        eval('$a[0]='                           // future first element :=
            . 'array_shift($a)'                 // = old first element (removed)
            . ['+','-','*','/','**'][$i++%5]    // (operation)
            .'$a[0];'                           // new first element (after shift)
        );
    return$a[0];        // return last remaining element
}

测试套件

$cases = array (
    0=>[1,2,3,4,5],
    539=>[5,12,23,2,4,4,2,6,7],
    '-1055.356...' => [-8,50,3,3,-123,4,17,99,13],
    256 => [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
    1 => [1,0,1,0,1,0],
    -16 => [-9,-8,-1],
    -3 => [0, -3],
    -99 => [-99]
);
echo '<table border=1><tr><th>values</th><th>expected</th><th>actual result</th></tr>';
foreach ($cases as $expect=>$a)
{
    $result=f($a);
    echo "<tr><td>[", implode(',',$a),"]</td><td>$expect</td><td>$result</td></tr>";
}
echo '</table>';

做得很好。您可以通过将最后一个值作为数组返回(将'return $ a [0]'更改为'return $ a')来删除3个字节,我没有发现这是违反规则的。:)
640KB

@gwaugh Imo If the array contains just a single number, we return that as the result.很清楚。但是,感谢您让我重新审视此问题。
泰特斯

可以提出一个语义论点,即句子中的“那个”可以指代“数组”。无论如何,您的答案是迄今为止最短的PHP。做得非常好,再次感谢我较长时间提交的内容。
640KB

3

PHP135 130字节

感谢@ titus,-5个字节,外加0个大小写修复!

function f($z){return array_reduce($z,function($c,$x)use(&$i){eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');return$c;});};

在线尝试!

少打高尔夫球:

function f( $t ) {
    return array_reduce( $t,
        function( $c, $x ) use( &$i ) {
            eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');
            return $c;
        }
    );
};

确实为array_reduce()扎根可以工作,但是需要太多字符才能击败当前最低的PHP分数。

无论如何都要发布它,以防有人提出任何建议!


1
不错的方法;但是我认为每当$c碰到它都会失败0。使用匿名函数(而不是)保存两个字节weval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x');return$c;短6个字节,应该可以解决零问题。
泰特斯

谢谢@Titus!您对0的情况绝对正确。我必须加回; 在= $ x之后,因为没有它,eval就不会运行。如果我将它设为anon函数,则必须为其分配变量或在测试代码中运行它,对吗?不想让字节数成为问题。:D
640KB

2

Brachylog,68位元组

hI,?bL,1:+:-:*:/:^b:L:I{bhv?t.|[O:L:I]h$(P,LbM,OhA,Lh:Ir:A&:M:Pr&.}.

很长……但是它不使用评估谓词。

说明

  • 主谓词

    hI,                                  Unify I with the first element of the input
       ?bL,                              L is the input minus the first element
           1:+:-:*:/:^b                  Construct the list of predicates [+:-:*:/:^]
                       :L:I{...}.        Call predicate 1 with [[+:-:*:/:^]:L:I] as input
    
  • 谓词1

    bhv?t.                               If the second element of Input is empty (i.e. L),
                                         unify Output with the last element of Input
    |                                    Or
    [O:L:I]                              Input = [O:L:I]
           h$(P,                         P is O circularly permutated to the left
                LbM,                     M is L minus the first element
                    OhA,                 A is the first element of O
                        Lh:Ir:A&         Call predicate A on [I:First element of L]
                                :M:Pr&.  Call predicate 1 recursively with P:M:
    

用1个字节击败您2个字节;)
LegionMammal978 2016年

2

IBM PC 8087 FPU, 66 82字节

仅使用IBM PC的Intel 8087数学协处理器进行计算。

离线尝试!(在DOSBox或其他任何版本中)。给您旧PC上无聊的8087芯片做些什么,而不是您过去在80年代所做的所有那些Lotus 1-2-3电子表格。

9bdf 0783 c302 499b de07 83c3 0249 e342 9bde 2783 c302 49e3 399b de0f 83c3 0249 
e330 9bde 3783 c302 49e3 2751 8b0f 9bd9 e883 f900 7413 9c7f 02f7 d99b d8c9 e2fb 
9d7d 069b d9e8 9bd8 f159 83c3 0249 e302 ebb5 c3

未装货(未组装):

START: 
    ; RUN TESTS  
    MOV  BX, OFFSET TST     ; 5, 12, 23, 2, 4, 4, 2, 6, 7
    MOV  CX, CTST           ; input array length
    CALL WOMI               ; calculate sequence
    CALL PRINT_FLT          ; output to console

    MOV  BX, OFFSET TST1    ; 5, 12, 23, 2, 4, -4, 2, 6, 7
    MOV  CX, CTST1
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST2    ; -8, 50, 3, 3, -123, 4, 17, 99, 13
    MOV  CX, CTST2
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST3    ; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
    MOV  CX, CTST3
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST4    ; 1,0,1,0,1,0
    MOV  CX, CTST4
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST5    ; -9, -8, -1
    MOV  CX, CTST5
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST6    ; 0, -3
    MOV  CX, CTST6
    CALL WOMI
    CALL PRINT_FLT

    MOV  AX, 4C00H          ; exit to DOS
    INT  21H

;  TEST DATA

TST   DW  5, 12, 23, 2, 4, 4, 2, 6, 7
CTST  EQU ($-TST)/(SIZE TST)    ; count of items on list

TST1  DW  5, 12, 23, 2, 4, -4, 2, 6, 7
CTST1 EQU ($-TST1)/(SIZE TST1)  ; count of items on list

TST2  DW -8, 50, 3, 3, -123, 4, 17, 99, 13
CTST2 EQU ($-TST2)/(SIZE TST2)  ; count of items on list

TST3  DW 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
CTST3 EQU ($-TST3)/(SIZE TST3)  ; count of items on list

TST4  DW 1,0,1,0,1,0
CTST4 EQU ($-TST4)/(SIZE TST4)  ; count of items on list

TST5  DW -9, -8, -1
CTST5 EQU ($-TST5)/(SIZE TST5)  ; count of items on list

TST6  DW 0, -3
CTST6 EQU ($-TST6)/(SIZE TST6)  ; count of items on list

; 8087 exponent: ST(0) = ST(0) ^ EXP
FIEXP   MACRO   EXP
        LOCAL   REPEAT, DONE
        PUSH CX
        MOV  CX, EXP        ; Exponent is count for loop
        FLD1                ; load 1 into ST
        CMP  CX, 0          ; is exponent pos, neg or 0?
        JZ   DONE           ; exit (with value 1) if exponent is 0
        PUSHF               ; save result flags for later
        JG   REPEAT         ; if exp > 1 start calculation
        NEG  CX             ; make exponent positive for loop
REPEAT:
        FMUL ST(0), ST(1)   ; multiply ST0 = ST0 * ST1
        LOOP REPEAT
        POPF                ; retrieve flags from earlier
        JGE  DONE           ; if exponent was negative, divide 1 by result
        FLD1                ; push 1 into numerator
        FDIV ST(0), ST(1)   ; ST0 = 1 / ST1
DONE:
        POP  CX
        ENDM

; Function WOMI: (Weapons of Math Instruction)
; input: BX - address of start of input array
;       CX - length of input array
; output: ST - result on top of 8087 register stack
WOMI PROC
    FILD WORD PTR [BX]      ; load first item
    ADD  BX, 2              ; move to next
    DEC  CX
CALC:
    FIADD WORD PTR [BX]     ; add
    ADD  BX, 2              ; move to next
    DEC  CX                 ; decrement counter
    JCXZ OUTPUT             ; check if done

    FISUB WORD PTR [BX]     ; subtract
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIMUL WORD PTR [BX]     ; multiply
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIDIV WORD PTR [BX]     ; divide
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIEXP [BX]              ; exponent
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT
    JMP CALC                ; start again

OUTPUT:
    RET 
WOMI ENDP

PRINT_FLT PROC
; print top of 8087 stack
; scaling: 14 digits, 4 decimal places
; input: BX = address of a TBYTE (BCD) output buffer
;       ST = value to display on top of 8087 stack  
    LEA   BX, BUFF                  ; set BX to BCD output buffer
    MOV   AH, 2
    MOV   WORD  PTR[BX], 10000      ; ten thousand (scale factor)
    FIMUL WORD  PTR[BX]             ; scale up by 10000
    FBSTP TBYTE PTR[BX]             ; store as BCD
    FWAIT                           ; sync 8088 and 8087
    TEST  BYTE  PTR[BX+9], 80H      ; check sign bit
    JE    PF_1                      ; 0, goto PF_1
    MOV   DL, '-'                   ; output '-'
    INT   21H
PF_1:
    ADD   BX, 8                     ; point to high byte
    MOV   CH, 7                     ; 14 digits before decimal point
    MOV   CL, 4                     ; 4 shifts (8 bytes / 2 = 4 = 1 nibble)
    MOV   DH, 2                     ; 2 times (8 bytes / 4)
PF_LOOP:
    MOV   DL, [BX]                  ; get BCD digits
    SHR   DL, CL                    ; move high digit to low nibble
    OR    DL, 30H                   ; convert to ASCII
    INT   21H
    MOV   DL, [BX]                  ; get byte again
    AND   DL, 0FH                   ; mask out high digit
    OR    DL, 30H                   ; convert to ASCII
    INT   21H                       ; output
    DEC   BX                        ; next byte
    DEC   CH                        ; decrement byte
    JG    PF_LOOP                   ; repeat if more bytes
    DEC   DH                        ; second time?
    JE    PF_DONE                   ; yes, done
    MOV   DL, '.'                   ; no, output decimal point
    INT   21H
    MOV   CH, 2                     ; 4 more digits after decimal point
    JMP   PF_LOOP                   ; go print digits
PF_DONE:
    MOV  DL, 0DH                    ; display newline CRLF
    MOV  AH, 2
    INT  21H
    MOV  DL, 0AH
    INT  21H
    RET 
PRINT_FLT ENDP

BUFF DT 0   ; output buffer for floating point digit string

_TEXT ENDS
END START

输出:

A>WOMI.COM
00000000000539.0000
-00000000000027.9136
-00000000001055.3569
00000000000256.0000
00000000000001.0000
-00000000000016.0000
-00000000000003.0000

输入是通过PROC(x86最等效于一个函数)进行的,其中BX是指向内存中WORD数组的指针,而CX是其中的项数,并在ST中返回结果。

*注意:该函数的实际代码为 6682个字节 当然,仅用于向控制台写入浮点数的代码(食谱代码)为83个字节。测试程序和数据是183215字节,使.COM可执行 305 总共380个字节。


1
这很棒!我已经为x86-64(Linux)编写了类似的解决方案,但是我还没有做太多的事情,这可能会改变很多逻辑。对于您的指数计算,即使给定的测试未测试接收到负指数,我也认为这是程序逻辑的必要部分,尤其是因为它很简单,例如将1推入st0然后在st0和st1(至少在x86上这是两条指令)。
戴维

感谢@davey-非常好!我已经更新了代码以处理负指数,并为其添加了另一个测试用例。
640KB

2

APL(Dyalog Unicode)29 27 字节SBCS

匿名默认前缀功能。请注意,这*是APL中的幂运算。

≢{⍎3↓⍕⌽⍵,¨⍨⍺⍴'+-×÷*''⍨'}⊢

在线尝试!

因为APL从右到左执行,所以我们可以颠倒插入操作的参数顺序并颠倒整个表达式。后缀反转参数。在完成数字和运算的完美混合之后,我们只需要反转,展平和评估:

≢{}⊢ 调用以下函数,并将和的实际数量计为

'⍨' 这个角色

'+-×÷*',¨ 在这些字符之前加上每个字符; ["+⍨","-⍨","×⍨","÷⍨","*⍨"]

⍺⍴ 使用左参数(数字计数)周期性[R ESHAPE那

 相反

 格式为平字符串

3↓删除前3个字符(一个空格和一个符号和

 作为APL代码执行


2

Japt,16字节

r@[XY]r"p+-*/"gZ

在线尝试!

说明:

r@                  #Reduce the input list:
       "p+-*/"      # The list of functions to apply (offset by one due to the behavior of Z)
              gZ    # Choose the one at the current index, wrapping
  [  ]r             # Apply that function to:
   X                #  The result of the previous step
    Y               #  and the current number
                    #Implicitly return the result of the final step

啊,feck,我自己就是在做这件事,试图弄清楚为什么它给我不正确的结果-我错过了fecking的求幂运算!:\
毛茸茸的

1

c#,238、202字节

double d(double[]a){Array.Reverse(a);var s=new Stack<double>(a);int i=0,j;while(s.Count>1){double l=s.Pop(),r=s.Pop();j=i++%5;s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l,r));}return s.Peek();}

我没有看到任何C#解决方案,所以我给一个。这是我的第一个代码高尔夫。我“两个月前”开始用c#编写(尽管我在某种程度上了解Java)。

它使用堆栈

在线尝试!

取消测试案例

using System;
using System.Collections.Generic;

class M 
{
    double d(double[]a) {
        Array.Reverse(a);
        var s = new Stack<double>(a);
        int i=0,j;
        while (s.Count>1)
        {
            double l=s.Pop(),r=s.Pop();
            j=i++%5;
            s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l, r));
        }
        return s.Peek();
    }

    public static void Main()
    {
        int[][] a = new int[][]{
            new int[]{1,2,3,4,5},
            new int[]{5,12,23,2,4,4,2,6,7},
            new int[]{-8,50,3,3,-123,4,17,99,13},
            new int[]{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            new int[]{1,0,1,0,1,0},
            new int[]{-9,-8,-1},
            new int[]{0,-3},
            new int[]{-99}
        };

        for (int i = 0; i < a.Length; i++)
        {
            Console.WriteLine(new M().d(Array.ConvertAll(a[i], e => Convert.ToDouble(e))));
        }
        Console.ReadKey();
    }
}

输出:

0
539
-1055,35694384628
256
1
-16
-3
-99

嗨,欢迎来到PPCG!这可能是一个不错的话题:C#中的代码高尔夫球技巧。您可以在代码中找到一些东西:空格(a, Double.Parse-> a,Double.Parse; while (s.Count-> while(s.Count; Pow(l, r)--> Pow(l,r))。另外,您可以将移到int 的前面j=并将其放在的后面int i=0,j;。很好的第一个答案,再次欢迎。:)
Kevin Cruijssen

@KevinCruijssen嗨!!删除空格并按照您的建议移动j :)
display_name 2016年

1

PHP,206198,197个字节

function f($a){while(count($a)>1){$l=array_shift($a);$r=array_shift($a);array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));}return array_pop($a);}

在线尝试!

不打高尔夫球

<?php

function f($a)
{
    while(count($a)>1)
    {
        $l = array_shift($a); $r = array_shift($a);
        array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));
    }
    return array_pop($a);
}

echo f([1,2,3,4,5])."\n";
echo f([5,12,23,2,4,4,2,6,7])."\n";
echo f([-8,50,3,3,-123,4,17,99,13])."\n";
echo f([2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2])."\n";
echo f([1,0,1,0,1,0])."\n";
echo f([-9,-8,-1])."\n";
echo f([0,-3])."\n";
echo f([-99])."\n";

在PHP中,逻辑类似于我的c#答案202个字节):)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.