Stewie的顺序:+ *-/ + *-/


29

让我们使用四个基本运算,加法+,乘法*,减法-和除法/(浮点数,而不是整数)。

Stewie的顺序定义如下:

x = [x(1), x(2)]    // Two initial numbers (one indexed)
x(3) = x(1) + x(2)
x(4) = x(2) * x(3)
x(5) = x(3) - x(4)
x(6) = x(4) / x(5)
x(7) = x(5) + x(6)
... and so on.

挑战:

取两个非负整数(x(1), x(2))和一个正整数N作为输入。

x(1)并且x(2)将是序列的前两个数字,并且N将是您必须输出的序列的长度。(您可以选择使列表从0开始,在这种情况下N,长度将比长度小1)。

  • 您不能假设x(2) >= x(1)
  • N>2如果从1开始,则始终为(>1如果从0开始)。
  • 您不必处理零错误。
    • 注意第二个测试用例。您不会得到0, 1N=6作为输入,因为这将导致被零除,但是您必须支持0, 1N=5
  • 假设仅给出有效输入。
  • 输入和输出可以采用任何方便的格式,但是如果输出为非整数,则必须支持小数点后至少3位数字。

测试用例:

1 3
8
1, 3, 4, 12, -8, -1.5, -9.5, 14.25

0 1
5
0, 1, 1, 1, 0     // N=6 would give division by zero error. You don't need to handle that case.

1 0
9
1, 0, 1, 0, 1, 0, 1, 0, 1

6 3
25
6, 3, 9, 27, -18, -1.5, -19.5, 29.25, -48.75, -0.6, -49.35, 29.61, -78.96, -0.375, -79.335, 29.7506, -109.086, -0.272727, -109.358, 29.825, -139.183, -0.214286, -139.398, 29.8709, -169.269

函数可以将x(1)和x(2)作为列表吗?还是单独的论点?
FlipTack

不管什么对您来说方便:)
Stewie Griffin

可以N从零开始?因此,将输入比示例中显示的N小1。我猜想参加N-2
Luis Mendo

当您将输出写成任何方便的格式时,它是否包括一个列表,该列表的开头是final元素,而结尾是start-elements(一个反向列表)?
Emigna '16

1
@Emigna,不,我认为这是一个有点夸张......这些数字应该是正确的顺序
Stewie新

Answers:


3

MATL19 18 17字节

q:"y'+*-/'@)hyhUV

输入的格式为:(从N0开始)x(1),,x(2)(作为字符串);全部以换行符分隔。

在线尝试!验证所有测试用例(稍作修改的代码;输出序列用空白行分隔)。

说明

MATL没有适当的eval功能,但是Ustr2num)可以使用中缀运算符计算数值表达式。

计算每个新项并将其推入堆栈,并保留先前的项。整个纸叠都打印在最后。

q          % Implicitly input N (0-based). Subtract 1
:"         % Repeat that many times
  y        %   Duplicate x(n-1), where n is the number of already computed terms
           %   In the first iteration, which corresponds to n=2, this implicitly 
           %   inputs x(1) and x(2) as strings (and then duplicates x(1))
  '+*-/'   %   Push this string
  @)       %   Push iteration number and apply as modular index into the string. 
           %   So this gives '+' in the first iteration, '*' in the second etc
  h        %   Concatenate horizontally. This gives a string of the form
           %   '*x(n-1)+', where '+' is the appropriate operator 
  &y       %   Duplicate x(n)
  hh       %   Concatenate horizontally. This gives a string of the form
           %   'x(n-1)+x(n)'
  U        %   Convert to number. This evaluates the string
  V        %   Convert back to string. This is the new term, x(n+1)
           % Implicitly end loop and display stack

7

Haskell,69 68 64字节

x#n=take n$x++zipWith3 id(cycle[(+),(*),(-),(/)])(x#n)(tail$x#n)

x1x2作为列表。用法示例:[1,3] # 8-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25]

懒惰使我们可以定义一个无限递归列表,其中我们采用了前n个元素。

Haskell,66个字节

(h%g)y x=x:g(h x y)y
a=(+)%b
b=(*)%c
c=(-)%d
d=(/)%a
(.a).(.).take 

不同的方法,稍长一些。参数顺序为Nx2x1。用法示例:( (.a).(.).take ) 8 3 1-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25]

定义4个功能abcd这两个参数yx 并通过将列个清单x中的下一个函数调用的前面与y作为第二个参数,并x op y为第一。例如a是:a y x = x : (b (x+y) y)b做乘法:b y x = x : (c (x*y) y),等等。

编辑:@Michael Klein在第一个变体(#)中保存了一个字节。幸运的是,我还为第二个变体找到了一个字节,因此两者的长度再次相同。

编辑II:@Zgarb在第二个版本中发现有2个字节要保存,而在第一个版本中我找到了4个字节,因此它们的长度不再相同。


接受参数作为一个字节的列表(允许)
Michael Klein

如果(.)与其他功能组合在一起,我总是会感到困惑:p
tomsmeding

g x=(`take`f)where不保存字节:-/
Bergi

在替代方法中节省2个字节:(h%g)y x=x:g(h x y)y
Zgarb

@Zgarb:哦,太好了。谢谢!顺便说一句,在编辑您的建议时,我发现在第一个版本中要保存4个字节。
nimi

6

ES6(JavaScript), 7967,65字节

更新

  • 减去2个字节,以@ETHProductions的建议从i = 2开始
  • 由于@Neil的出色建议,节省了3个字节!

打高尔夫球

S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"-/+*"[i%4]+a[i-1]))):a

测试

S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"-/+*"[i%4]+a[i-1]))):a

>S(8,[1,3])
Array [ 1, 3, 4, 12, -8, -1.5, -9.5, 14.25 ]

>S(5,[0,1])
Array [ 0, 1, 1, 1, 0 ]

>S(9,[1,0])
Array [ 1, 0, 1, 0, 1, 0, 1, 0, 1 ]

>S(25,[6,3])
Array [ 6, 3, 9, 27, -18, -1.5, -19.5, 29.25, -48.75, -0.6, ...]

1
您是否++i可以避免避免将1加i两次?
尼尔

1
或者,写?S(n,a,i+1,a.push(...)):a可能会为您节省一些字节。
尼尔

1
或者,也许您可​​以使用a.push返回新长度的事实,S=(n,a,i=2)=>i<n?S(n,a,a.push(...)):a
Neil

1
我仍然认为您可以从i=2虽然开始节省更多字节。
尼尔

1
根据Neil的建议,我认为您可以S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"+*-/"[i%4]+a[i-1]))):a节省2个字节。
ETHproductions 2016年

5

Python 3,90 80 74字节

xnor可能会来破坏这个解决方案...

def F(s,n,i=2):
 while i<n:s+=eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])),;i+=1

该函数修改传递给它的列表。像这样使用:

s = [1,3] 
F(s,8)

尝试repl.it!

-6字节归功于Copper


由于您只使用O一次,因此可以通过'-/+*'[i%4]删除和声明来节省一些字节O。另外,您可以str执行类似的操作来解决重复调用的问题eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1]))

哦,是的,s+=[...]可以替换为s+=...,(请注意结尾的逗号)。

xnor并不是唯一可以破坏您的解决方案的解决方案。还有一个人:丹尼斯(mod)。
暴民埃里克

您可以确保获得i输入,因此不需要默认值(i=2可以只是i)。关闭两个字节。
ArtOfCode

1
如果允许它返回n序列中的第th个项,则递归将其缩短1个字节:f=lambda x,n:n<2and x[n-1]or eval('%s'*3%(f(x,n-2),'*-/+'[n%4],f(x,n-1)))
mbomb007'December

5

Perl 6的 75个71  61字节

->\a,\b,\c{$_=[|(&[+],&[*],&[-],&[/])xx*];(a,b,{.shift.($^a,$^b)}...*)[^c]}

测试一下

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

测试一下

{($^a,$^b,{(&[+],&[*],&[-],&[/])[$++%4]($^a,$^b)}...*)[^$^c]}

测试一下

展开:

{ # bare block lambda with placeholder parameters 「$a」 「$b」 「$c」

  # generate sequence
  (
    # initialize sequence
    $^a, # declare and use first argument
    $^b, # second argument

    {  # bare block lambda with two placeholder parameters 「$a」 「$b」

      (

        &[+], &[*], &[-], &[/] # the four operators

      )[             # index into the list of operators

         $++        # increment (++) an anonymous state variable ($)
         % 4        # modulo 4

      ]( $^a, $^b ) # and use it on the previous two values in sequence

    }

    ...  # repeat that until

    *    # indefinitely

  )[     # take only

    ^    # upto and excluding:     ( Range object )
    $^c  # third argument

  ]
}

4

Mathematica,68个字节

(±1=#;±2=#2;±n_:=1##[#-#2,#/#2,+##][[n~Mod~4]]&[±(n-2),±(n-1)];±#3)&

勉强潜入第三名!三个参数的未命名函数,使用辅助一元运算符±,使得±n它恰好是Stewie序列的第n个元素x(n)。前两个参数是x(1)和x(2),第三个参数是N,表示我们输出哪个x(N)。

直接实现,使用mod-4计算选择要应用于前两项的二进制函数。选择正确的二进制函数(会有所1##[#-#2,#/#2,+##]帮助)会使用以下一些有趣的Mathematica高尔夫技巧


3

05AB1E21 19 18字节

输入顺序为N(从0开始),x(2)x(1)
由于使用了carusocomputing,因此节省了1个字节。

GUDXsX"/+*-"Nè.V})

在线尝试!

说明

 G                   # for N in [0 ... n-1] do:
  U                  # save top element of stack in X
   D                 # duplicate top of stack
    X                # push X
     s               # swap top 2 elements on stack
      X              # push X
       "/+*-"Nè      # index into the string with the current iteration number
               .V    # evaluate
                 }   # end loop
                  )  # wrap stack in list

我们迭代构建堆栈,该堆栈的顶部是序列中的最新元素,同时使所有先前元素保持顺序。
然后,我们将堆栈包装在最后的列表中,以一次显示所有值。


1
我无法弄清楚,但使用XYUV可以节省您的字节。
魔术章鱼缸

1
@carusocomputing:不错!使用UX:) 保存了我从寄存器丢失的字节,无法使用隐式输入:)
Emigna

2

普通Lisp 158

(lambda(x y n)(loop repeat n for a = x then b for b = y then r for o in '#1=(+ * - / . #1#)for r =(ignore-errors(funcall o a b))collect(coerce a'long-float)))

竞争并不真正,但是我很自然地表达它:

(lambda (x y n)
  (loop 
    repeat n
    for a = x then b
    for b = y then r
    for o in '#1=(+ * - / . #1#)
    for r = (ignore-errors (funcall o a b))
    collect (coerce a 'long-float)))

我们在计算R时忽略了错误,这使得R(然后是B)可能取NIL值。即使下一个值未定义,也可以输出当前结果。然后,最终循环将失败,但这在规则之内。

测验

我们命名该函数,F并验证期望值大约等于测试值。

(loop
  for (args expected)
    in
  '(((1 3 8)
     (1 3 4 12 -8 -1.5 -9.5 14.25))

    ((0 1 5)
     (0 1 1 1 0))

    ((1 0 9)
     (1 0 1 0 1 0 1 0 1))

    ((6 3 25)
     (6 3 9 27 -18 -1.5 -19.5 29.25 -48.75 -0.6 -49.35 29.61 -78.96 -0.375 -79.335 29.7506 -109.086 -0.272727 -109.358 29.825 -139.183 -0.214286 -139.398 29.8709 -169.269)))

  for result = (apply #'f args)
  always (every (lambda (u v) (< (abs (- u v)) 0.001)) result expected))

=> T

进行近似测试的原因是因为计算出的值比要求的要精确一些。在这里,用于(f 6 3 25)

(6.0d0 3.0d0 9.0d0 27.0d0 -18.0d0 -1.5d0 -19.5d0 29.25d0 -48.75d0 -0.6d0
 -49.35d0 29.61d0 -78.96d0 -0.375d0 -79.335d0 29.750625d0 -109.085625d0
 -0.2727272727272727d0 -109.35835227272727d0 29.825005165289255d0
 -139.18335743801654d0 -0.21428571428571427d0 -139.39764315230224d0
 29.870923532636194d0 -169.26856668493843d0)

2

直流,112 110 108个字节

5k?sarfsmsn[pSnla1-Sa]sh[lmlndSm]sv[lvx/lhx]sb[lvx+lhx]sc[lvx*lhx]sd[lvx-lhx]se[lcx2la>d2la>e2la>b2la>j]dsjx

有时dc答案可能会很长,有时答案可能会很短。就像许多其他语言一样,这都取决于即将面临的挑战。无论如何,这会提示输入以空格分隔的3个整数的单索引命令行输入,x(1), x(2), N在调用时,并在单独的行上输出序列的每个元素,并在小数点后的非整数输出中包含5位数字。

例如,输入6 3 25产生以下输出:

6
3
9
27
-18
-1.50000
-19.50000
29.25000
-48.75000
-.60000
-49.35000
29.61000
-78.96000
-.37500
-79.33500
29.75062
-109.08562
-.27272
-109.35834
29.82420
-139.18254
-.21428
-139.39682
29.86995
-169.26677

2

Perl,62 + 3(-pla标志)= 65个字节

push@F,eval$F[-2].qw(* - / +)[$_%4].$F[-1]for 3..pop@F;$_="@F"

使用:

perl -plae 'push@F,eval$F[-2].qw(* - / +)[$_%4].$F[-1]for 3..pop@F;$_="@F"' <<< '1 3 8'

1

Ruby,79个字节

->(b,c,d){a=[b,c];(d-2).times{|i|a<<a[i].send(%i{+ * - /}[i%4],a[i+1]).to_f};a}

我怀疑这离最佳状态还差得很远(而且我还没有看其他答案),但这仍然很有趣。

我想找点乐子Enumerable#cycle,可悲的是,它只使用了四个字符%4


1

C ++ 14,118字节

[](auto&v,int N){for(int i=0;++i<N-1;){auto p=v.rbegin(),q=p+1;v.push_back(i%4?i%4<2?*q+*p:i%4<3?*q**p:*q-*p:*q/ *p);}

如未命名的lambda修改其输入。要求vvector<double>vector<float>

脱胶和用法:

#include<iostream>
#include<vector>

auto f=
[](auto&v,int N){
  for(int i=0; ++i<N-1;){
    auto p=v.rbegin(),q=p+1;
    v.push_back(
      i%4 ?
        i%4<2 ? *q+*p : 
          i%4<3 ? *q**p : *q-*p
      : *q/ *p
    );
  }
};

int main(){
  std::vector<double> v={1,3};
  f(v,8);
  for (auto x:v) std::cout << x << ", ";
  std::cout << "\n";
}

1

x86-64机器码,34个字节

调用约定= x86-64 System V x32 ABI(在长模式下使用32位指针注册args)。

功能签名为void stewie_x87_1reg(float *seq_buf, unsigned Nterms);。该函数在数组的前两个元素中接收x0和x1种子值,并将序列扩展到至少N个以上的元素。缓冲区必须填充为2 + N舍入到下一个4的倍数。(即2 + ((N+3)&~3) N + 5)。

高性能或SIMD向量化功能在组装时通常需要填充缓冲区,并且展开的循环类似,因此我认为规则不会过分弯曲。调用方可以轻松(并且应该)忽略所有填充元素。

将x0和x1作为函数arg传递到缓冲区中尚未存在的函数,只会花费3个字节(对于a movlps [rdi], xmm0movups [rdi], xmm0),尽管由于System V通过,这将是非标准的调用约定struct{ float x,y; };两个单独的XMM寄存器。

这是objdump -drw -Mintel一个有点格式化添加注释的输出

0000000000000100 <stewie_x87_1reg>:
       ;; load inside the loop to match FSTP at the end of every iteration
       ;; x[i-1] is always in ST0
       ;; x[i-2] is re-loaded from memory
 100:   d9 47 04                fld    DWORD PTR [rdi+0x4]
 103:   d8 07                   fadd   DWORD PTR [rdi]
 105:   d9 57 08                fst    DWORD PTR [rdi+0x8]
 108:   83 c7 10                add    edi,0x10            ; 32-bit pointers save a REX prefix here

 10b:   d8 4f f4                fmul   DWORD PTR [rdi-0xc]
 10e:   d9 57 fc                fst    DWORD PTR [rdi-0x4]

 111:   d8 6f f8                fsubr  DWORD PTR [rdi-0x8]
 114:   d9 17                   fst    DWORD PTR [rdi]

 116:   d8 7f fc                fdivr  DWORD PTR [rdi-0x4]
 119:   d9 5f 04                fstp   DWORD PTR [rdi+0x4]

 11c:   83 ee 04                sub    esi,0x4
 11f:   7f df                   jg     100 <stewie_x87_1reg>
 121:   c3                      ret    

0000000000000122 <stewie_x87_1reg.end>:
## 0x22 = 34 bytes

此C参考实现将(使用gcc -Os)编译为稍微相似的代码。gcc选择了与我相同的策略,即只在寄存器中保留一个先前的值。

void stewie_ref(float *seq, unsigned Nterms)
{
    for(unsigned i = 2 ; i<Nterms ; ) {
        seq[i] = seq[i-2] + seq[i-1];       i++;
        seq[i] = seq[i-2] * seq[i-1];       i++;
        seq[i] = seq[i-2] - seq[i-1];       i++;
        seq[i] = seq[i-2] / seq[i-1];       i++;
    }
}

我做了其他方法的实验,包括两个寄存器的x87版本,其代码如下:

; part of loop body from untested 2-register version.  faster but slightly larger :/
; x87 FPU register stack    ;       x1, x2   (1-based notation)
fadd    st0, st1            ; x87 = x3, x2
fst     dword [rdi+8 - 16]  ; x87 = x3, x2

fmul    st1, st0            ; x87 = x3, x4
fld     st1                 ; x87 = x4, x3, x4
fstp    dword [rdi+12 - 16] ; x87 = x3, x4
; and similar for the fsubr and fdivr, needing one fld st1

如果您要提高速度,则可以这样做(并且SSE不可用)

将内存中的负载放入循环中而不是一次输入可能会有所帮助,因为我们可以只按顺序存储sub和div结果,但是仍然需要两条FLD指令才能在进入时设置堆栈。

我还尝试使用SSE / AVX标量数学(从xmm0和xmm1中的值开始),但是较大的指令大小却是致命的。使用addps(因为比短1B addss),会有所帮助。我将AVX VEX前缀用于非交换指令,因为VSUBSS仅比SUBPS长一字节(且长度与SUBSS相同)。

; untested.  Bigger than x87 version, and can spuriously raise FP exceptions from garbage in high elements
addps   xmm0, xmm1      ; x3
movups  [rdi+8 - 16], xmm0
mulps   xmm1, xmm0      ; xmm1 = x4,  xmm0 = x3
movups  [rdi+12 - 16], xmm1
vsubss  xmm0, xmm1, xmm0      ; not commutative.  Could use a value from memory
movups  [rdi+16 - 16], xmm0
vdivss  xmm1, xmm0, xmm1      ; not commutative
movups  [rdi+20 - 16], xmm1

使用以下测试工具进行测试:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int main(int argc, char**argv)
{
    unsigned seqlen = 100;
    if (argc>1)
        seqlen = atoi(argv[1]);
    float first = 1.0f, second = 2.1f;
    if (argc>2)
        first = atof(argv[2]);
    if (argc>3)
        second = atof(argv[3]);

    float *seqbuf = malloc(seqlen+8);  // not on the stack, needs to be in the low32
    seqbuf[0] = first;
    seqbuf[1] = second;

    for(unsigned i=seqlen ; i<seqlen+8; ++i)
        seqbuf[i] = NAN;

    stewie_x87_1reg(seqbuf, seqlen);
//  stewie_ref(seqbuf, seqlen);
    for (unsigned i=0 ; i< (2 + ((seqlen+3)&~3) + 4) ; i++) {
        printf("%4d: %g\n", i, seqbuf[i]);
    }

    return 0;
}

编译 nasm -felfx32 -Worphan-labels -gdwarf2 golf-stewie-sequence.asm &&
gcc -mx32 -o stewie -Og -g golf-stewie-sequence.c golf-stewie-sequence.o

运行第一个测试用例 ./stewie 8 1 3

如果您没有安装x32库,nasm -felf64请使用default并保留gcc -m64。我用malloc代替float seqbuf[seqlen+8](在堆栈上)来获取低地址,而不必实际构建为x32。


有趣的事实:YASM有一个错误:当分支目标的地址与全局符号的地址相同时,它将rel32 jcc用于循环分支。

global stewie_x87_1reg
stewie_x87_1reg:
   ;; ended up moving all prologue code into the loop, so there's nothing here
.loop:

...
sub    esi, 4
jg     .loop

组装到... 11f: 0f 8f db ff ff ff jg 100 <stewie_x87_1reg>




0

Bash,224个字节(无比赛)

BASH中的一个巨大的实现。

完全按字面意思执行任务,并且在一个连续的管道中完成所有任务,而无需任何有害的控制流结构或递归。

输入项

$ 1,$ 2-初始元素

$ 3-目标序列大小

打高尔夫球

{ echo "a[0]=$1;a[1]=$2;a[0];a[1]";paste <() <(seq 2 $[$3-1]) <(seq 0 $[$3-3]) <(printf '%.0s+*-/' `seq $[$3/4]`|fold -1|head -$[$3-2]) <(seq 1 $[$3-2]);}|sed -r '1 ! s/(.+)\s(.+)\s(.+)\s(.)/a[\1]=a[\2]\3a[\4];a[\1];/'|bc -l

少打高尔夫球

{ 
 echo "a[0]=$1;a[1]=$2;a[0];a[1]";
 paste <() <(seq 2 $[$3-1]) <(seq 0 $[$3-3]) <(printf '%.0s+*-/' `seq $[$3/4]`|fold -1|head -$[$3-2]) <(seq 1 $[$3-2]);
}\
|sed -r '1 ! s/(.+)\s(.+)\s(.+)\s(.)/a[\1]=a[\2]\3a[\4];a[\1];/' \
|bc -l

测试

>./stewie.sh 1 3 8
1
3
4
12
-8
-1.50000000000000000000
-9.50000000000000000000
14.25000000000000000000

管道阶段

为每个输出序列元素(每行一个)生成元素索引表+ op:

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

使用sed将其转换为线性bc程序:

...
a[2]=a[0]+a[1];a[2];
a[3]=a[1]*a[2];a[3];
a[4]=a[2]-a[3];a[4];
a[5]=a[3]/a[4];a[5];
a[6]=a[4]+a[5];a[6];
a[7]=a[5]*a[6];a[7];
...

把它喂给公元前,让它完成所有工作


0

Pyth-20个字节

输出所有东西都花了n我。

u+Gvj@"+*-/"H>2GttEQ

无法在线评估eval。


0

锡兰,195字节

Float[]s(Integer a,Integer b,Integer n)=>loop([a.float,b.float,[Float.divided,Float.plus,Float.times,Float.minus].cycled.rest])(([x,y,o])=>[y,(o.first else nothing)(x)(y),o.rest]).take(n)*.first;

格式和评论:

// Print the first n entries of the Stewies sequence with given starting entries.
//
// Question:  http://codegolf.stackexchange.com/q/101145/2338
// My answer: http://codegolf.stackexchange.com/a/101251/2338

// Declare a function `s` which takes three integers, and returns a tuple
// of floats. (The more common syntax for the return value is [Float*],
// but Float[] is shorter.)
Float[] s(Integer a, Integer b, Integer n)
       // it is implemented by evaluating the following expression for each call.
         =>
        // start a loop with ...
        loop([
              // ... float versions of the integers, and ...
              a.float, b.float,
              // ... an infinite sequence of the four operators, ever repeating.
              // I needed the `.rest` here so the whole thing gets a {...*} type
              // instead of {...+}, which doesn't fit to what o.rest returns.
              // Each operator has the type Float(Float)(Float), i.e. you apply
              // it twice to one float each to get a Float result.
              [Float.divided, Float.plus, Float.times, Float.minus].cycled.rest])
               // in each iteration of the loop, map the triple of two numbers
               // and a sequence of operators to a triple of ... 
            (([x, y, o]) => [
               // the second number, 
                y,
               //the result of the first operator with both numbers
               // (using this "else nothing" here to convince the
               //  compiler that o.first is not null),
                   (o.first else nothing)(x)(y),
               // and the sequence of operators without its first element.
               // (that one unfortunately has a {...*} type, i.e. a possibly
               //  empty sequence.)
                                                 o.rest])
            // now we got an infinite sequence of those triples.
            // We just want the first n of them ...
                .take(n)
            // and of each triple just the first element.
            // (The *. syntax produces a tuple, non-lazily.
            //  We could also have used .map((z) => z.first)
            //  or .map(Iterable.first) or .map((z) => z[0]), each of
            //  which would return a (lazy) sequence, but they all would be
            //  longer.)
                *.first;

用法示例:

shared void run() {
    print(s(1, 3, 8));
    print(s(0,1,11));
    print(s(1,0,9));
    print(s(6, 3, 29));
}

输出示例:

[1.0, 3.0, 4.0, 12.0, -8.0, -1.5, -9.5, 14.25]
[0.0, 1.0, 1.0, 1.0, 0.0, Infinity, Infinity, Infinity, NaN, NaN, NaN]
[1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]
[6.0, 3.0, 9.0, 27.0, -18.0, -1.5, -19.5, 29.25, -48.75, -0.6, -49.35, 29.61, -78.96000000000001, -0.37499999999999994, -79.33500000000001, 29.750625, -109.08562500000001, -0.2727272727272727, -109.35835227272727, 29.825005165289255, -139.18335743801651, -0.2142857142857143, -139.39764315230224, 29.870923532636194, -169.26856668493843, -0.17647058823529413, -169.44503727317374, 29.90206540114831, -199.34710267432206]

第二个示例显示了如何处理零除。最后一个例子表明结果取决于使用的是哪种算术(和舍入)……我认为锡兰的64位浮点算术比问题中所发布的内容更接近应有的值。 。


0

Clojure,99个字节

#(let[ops[+ * - /]](take %3(map first(iterate(fn[[a b i]][b((ops i)a b)(mod(inc i)4)])[%1 %2 0]))))

此版本在实践中更适合使用,但具有110个字节:

(defn f[a b n](let[ops[+ * - /]](take n(map first(iterate(fn[[a b i]][b((ops i)a b)(mod(inc i)4)])[a b 0])))))

我在融合迭代函数和操作的周期性序列时遇到了麻烦,因此我不得不使用计数器。还尝试使用FSM过渡表,例如{+ * * - - / / +}但我无法将其压缩为更少的代码。

可以表示为匿名函数

未打高尔夫球:

(defn f [a b n]
  (let [ops [+ * - /]]
    (->> [a b 0]
         (iterate (fn [[a b i]]
                    [b
                     ((ops i) a b)
                     (mod (inc i) 4)]))
         (map first)
         (take n))))

必须使用浮点数进行调用,(f 6.0 3.0 25)否则您将得到有理数。替代地,可以开始迭代,[a (float b) 0]由此带来一些额外的字符。


0

八度,91字节

@(x,n)eval 'for i=3:n,x(i)=eval([(n=@num2str)(x(i-2)),"*-/+"(mod(i,4)+1),n(x(i-1))]);end,x'

在线尝试!

一些高尔夫:

  • 第一个没有括号 eval通话
  • 第一个没有串联 eval通话
  • 内联分配 *-/+(在MATLAB中是不可能的)
  • 合并'"避免转义撇号(在MATLAB中是不可能的)
  • n=@num2str由于已使用两次而进行存储(在MATLAB中是不可能的)
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.