任意の長さのカレー


53

機能、書くf正の整数に取り、関数を返します、。

返される新しい関数はと同一である必要がありますf。ただし、「終了呼び出し」が発生した場合、f代わりに渡されたすべての整数の合計を返す必要があります。

たとえば、g=f(4)f最初の関数の場合)g別の関数に設定する必要があります。h=g(3)同じことをします。ただし、h引数なしで呼び出した場合(詳細については以下を参照)、7を出力する必要があります。これは前の関数引数の合計であるためです。別の言い方をすればf(3)(4)() == 7

これはと同じではないことに注意してくださいf(3,4)()

「終了コール」は、次のオプションのいずれかです(選択)。

  • 引数なしで呼び出す
  • 引数としてnull
  • 非正の値

任意の量の関数呼び出しをサポートする必要があります。事前に定義された制限はありません。

合計が1'000を超えないことが保証されています。

「終了呼び出し」の前に少なくとも1つの呼び出しが行われていると想定できます。

コードでは静的なプログラムごとの変数を使用しないでください。そのため、同じランタイムで実験を複数回実行し、まったく同じ動作を観察できるようにする必要があります。

例:

f(1)() == 1
f(4)(2)(7)() == 13
f(4)(2)(7)(5)(2)() == 20

4
@LuisMendo一般に、それf(4)は新しい関数を返すことを意味します。その新しい関数が引数なしで呼び出され4た場合、を返しますが、別の引数で呼び出された場合は、同じセマンティクスで新しい引数が追加されたなどの新しい関数を再び返し4ます。
マーティンエンダー

6
@LuisMendo確かにユージーン次第ですが、興味深い部分はステートフル関数を作成することではなく、高階関数を作成することなので、繰り返し呼び出しを許可することは、チャレンジから大きく奪われると思います。
マーティンエンダー

6
@MartinEnderそれはとても理にかなっています。ユージン、もしそれが意図なら、チャレンジの言葉遣いを変えてください。無限に呼び出すことができる機能書く関数は関数を返すshoudことは全く示唆していない
ルイスMendo

4
コールチェーンのインスタンスは一度に1つだけであると想定できますか?例えばませんかq = f(2)(3); b = f(1)(2)(3); q(); b()
コナーオブライエン

3
最近Haskellを取り上げたので、Haskellでこれが可能かどうかに興味があります。強力な型システムにより、そうではないと思うようになります。
CAD97

回答:


49

JavaScript(ES6)、18バイト

f=n=>m=>m?f(m+n):n

偽の値を渡して合計を取得します。ゼロは2バイトのコストで許可されます。

オンラインで試す

ゴルフをしていない:

f = function(n) {
    return function(m) {
        if (m) {
            return f(m+n);
        } else {
            return n;
        }
    }
}

素晴らしい投稿!
ユージンD.グベンコフ

21

Haskell(GHC)、118バイト

これは、コードの場合は98バイト、GHCコンパイラフラグの-XFlexibleInstances場合は20バイトです。これにより、型システムの拡張が可能になります。

class F a where f::Int->a
instance F(()->Int)where f n()=n
instance F a=>F(Int->a)where f=(f.).(+)

これは、「関数」を定義します。これは、f任意の数の整数の後にunitを付けて呼び出すことができ()、その後整数を返します。型注釈が必要です。 オンラインでお試しください!

説明

Haskellの厳密な型システムにこれを許可するには、いくつかの魔法が必要です。つまり、柔軟な型クラスインスタンスのGHC拡張を有効にします。これがどのようにf機能するかは、型クラス制約によって制限されたパラメトリック多相関数ですF a => Int -> a。その型はです。これは、typeclassに属するすべての型についてf、整数を受け取り、typeの値を返すことを意味します。 関数を提供するタイプクラスの名前です; 最初の行で宣言されています。aaFFf

次の2行はF、異なるタイプの2つのインスタンスですa。2行目は、()から整数までの関数のタイプが属しているF(ここ()で、唯一のメンバーが値であるユニットタイプ())ことを示し、実装はf n () = n; 関数は最初の引数を返します。最後の行は、もしa属するならF、整数から次の関数の型もそうであると述べていますa:関数からf :: Int -> a別の関数を生成できますf :: Int -> Int -> a。実装はf m n = f (m+n)(コードはコンビネータを使用して短くします)、f左側が新しいものでf、右側が古いものです。これは本質的にf新しい整数引数。次の引数に追加されます。複数の引数は、次のようにまとめられます。

  f  a1   a2   a3   a4   a5  ()
= f (a1 + a2)  a3   a4   a5  ()
= f (a1 + a2 + a3)  a4   a5  ()
= f (a1 + a2 + a3 + a4)  a5  ()
= f (a1 + a2 + a3 + a4 + a5) ()
=    a1 + a2 + a3 + a4 + a5

f各ライン上では、さまざまな種類があります。

Haskell関数は自動的にカリー化されるため、f整数のみを指定すると、関数が取得されます。


1
たぶん私はピッキングをしていますが、それは挑戦が求めるものではありません。両方とも呼ばれる2つの関数(!)を定義しfています。ジョブを実行する単一の関数ではありません。ただし、これはHaskellで取得できる範囲内です。型システムが厳密であるため、1つの関数でタスクを解決することは不可能だと思います。
nimi

3
@nimiこれはf、呼び出される2つの関数ではなく、呼び出される無限に多くの関数を定義しますf。(可能な引数の数ごとに1つ。)これらの関数(この無限のファミリーから)には、2種類の定義があります。1つは引数の数がゼロの場合、もう1つはそうでない場合です。
-ShreevatsaR

@ShreevatsaR:私は2つの定義を参照してください、f n()=nf=(f.).(+)私は2つの機能を定義し、それを呼び出すと思いますので、。
-nimi

7
@nimi 2つの定義がありますが、2つの関数はありません。定義の数は、関数の数である必要はありません。たとえば、2つの定義g 0 = 1とを使用して階乗関数を定義できますg n = g (n-1) * n。2つの定義がありますが、関数は1つだけです。ここには2つの定義がありますが、無限に多くの関数があります。(異なるタイプのそれぞれ。)
ShreevatsaR

1
@nimi BTWでghci上記をロードして試してみてください:t f- f :: F a => Int -> a(if aがclassのインスタンスである場合f、それfが関数であることを意味しますInt -> a)。したがって、これを1つの関数または無限に多くあるとみなすことができますが、2種類の定義(階乗関数と同様)がありますが、2つの関数であるとみなす根拠はありません。
ShreevatsaR

15

パイソン2、42の 41 36バイト

Pythonは任意精度の整数をサポートしているため、このソリューションではオーバーフローは発生しません。ゼロは「特別な値」です。

f=lambda n:lambda m:m and f(m+n)or n

オンラインで試す

ゴルフをしていない:

def f(n):
    def g(m=''):
        return f(m+n)if m<''else n
    return g

14

C、62 58バイト、競合する境界線

Kevinのおかげで4バイト節約できました!(typedefは呼び出されるために必要なものなので、まだtypedefを削除していません。)

typedef(*(*B)(_))(_);q;f(x,o,_){x=x?(q+=x,f):(x=q,q=0,x);}

呼び出す関数はf;です。呼び出しを停止し、などの非正数で呼び出すことで結果を取得し0ます。オンラインでテストハーネスをお試しください!

したがって、私が知る限り、複数の戻り値型を持つ関数を「カリー」にする唯一の方法は、次のいずれかを実行することです。

  1. 結果を関数にキャストして、結果を再度呼び出すことをコンパイラに伝えます。
  2. またはおよびfunction / self-referentialサブタイプを持つunion/ structタイプを作成しますint

私はやってみました(2)が、質問の精神に少し反しているように見え、率直に言って、やり直しはできません。したがって、挑戦の精神に沿って、オプション(1)を選択しました。これには、返される各関数を関数にキャストして、使用できるようにする必要があります。

この「カリー化」構文は少し奇妙に見えますが、非常に似ています。エミュレートするf(21)(1)には、書く必要があります((B)((B)f(21))(1))(0)B型を、整数を受け取り、整数を受け取る関数へのポインターを返す関数として定義しました。展開すると、次のようになります。

   ( (B)( (B) f(21) )(1) )(0)
//            f(21)            - call f with 21
//        (B)                  - cast to B, a function pointer
//      (           )(1)       - call with 1
//   (B)                       - cast to a function pointer
// (                     )(0)  - call with 0

0でのみ終了すると言うと、キャストが必要になります(Cはそれ自体を返す関数を適切に定義できないため、Cで行います)、そして呼び出し間の実行間のグローバルをクリアのままにします(これは、私は完全に合理的だと思います)、あなたは全体を単純化することができますq;f(x){return x?(q+=x,f):q;}
ケビン


1
@Kevinは、サイトのルールに従って、関数は再利用可能でなければなりません。q各実行後にゼロを設定しなかった場合、関数は使用できなくなります
コナーオブライエン

多分関数ポインタ?あなたはデリファレンスにすべての時間を持っていると思いますが、価値をチェックアウトかもしれない
Downgoat

1
@ ConorO'Brien ユニオンアプローチを実装しました。これよりも長いですが、そう遠くない。
ヤコブ

13

Mathematica、25バイト

f[x_]@y_=f[x+y]
f[x_][]=x

オンラインでお試しください!(数学を使用。)

JavaScriptの回答を移植することで、3バイト少なくすることができますが、より慣用的なMathematicaソリューションを提示したかったのです。これ@はほんの少しの構文上の砂糖であり、これによりソリューションは次と同等になります。

f[x_][y_]=f[x+y]
f[x_][]=x

だから、アイデアはMathematicaでは関数を定義するだけではなく、たとえば、別の引数を渡さf[x_]れるなど、より複雑な式に値を直接付加できるということです。このために2つの定義を設定することにより、目的の動作を取得できます。ff[x_]

  • 最初の定義では、1つのf[x][y]呼び出しをにまとめf[x+y]、それにより1つの「呼び出し」を消費し、内部の引数を加算します。このルールは、が残るまで適用されますf[sum][]
  • 2番目の定義は、評価するもの全体を定義することにより、この最後のケースをアンパックしsumます。

1
<3シンボリックプログラミング
ジュリアンウルフ

8

C ++、72バイト

#define O(P)operator()(P){return{P+a};}int
struct F{F O(int(m))O()a;}f;

これはF、要求された関数として機能fするタイプと、呼び出すタイプの変数を定義します。C ++ 11の時点で有効であり、GCC、clang、icc、VC ++のオンラインバージョンで動作します。

使用法:

int main() {
  return f(1)(2)(3)(); // returns 6
}

説明:

前処理と再フォーマット後、次のようになります。

struct F {
  F operator()(int(m)) { return{int(m)+a}; }
  int operator()() { return {+a}; }
  int a;
} f;

通常、これは次のように記述されます。

struct F {
  F operator()(int m) { return {m+a}; }
  int operator()() { return a; }
  int a;
} f;

return a;return {+a};単項+は値を変更せず、戻り値を囲む冗長な中括弧が許可されるため、同じことを行います。関数パラメーターを含む変数名の周りの冗長な括弧が許可されているため、同じことint mint(m)行います。return {m+a};そして、return {int(m)+a};のキャストとして、同じことを行うmintintその値を変更しません。これらの変更により、2つのoperator()オーバーロードの構文がより近くなり、1つのマクロ定義を2回呼び出すことができます。3つのメンバーの正しい順序を選択すると、次の行の最初の単語(int)もマクロ定義に含めることができます。


1
綺麗な。ゴルフだけでなく、operator()この作業を行うためのオーバーロードは特にクールでした。
レイトール



4

Math.JS、38バイト

f(x)=i(x,0)
i(x,y)=x<0?y:j(z)=i(z,y+x)

で呼び出す f(number_a)(number_b)(...)(negative_number)

最初の呼び出しを指定できる場合は、12バイト(f(x)=i(x,0)\n)をドロップして、次のように呼び出すことができますi(number_one,0)(number_two)(...)(negative_number)

それを試してみてください!

説明

ラテックス!

上記のLaTexに示されているように、f(x)単にを呼び出してi(x,0)、if i(x,y)の値が0より小さいか、関数が1つの引数を取り、ループします。の値に追加します。yxj(z)=i(z,x+y)y


4

C、232206バイト

#include<string.h>
#include<stdlib.h>
#define f(X)s(""#X)?0:g
#define g(X)u(""#X)?0:h
#define h(X)u(""#X)?0:g
g=0,h=0;s(char*s){g=h=atoi(s);return 0;}u(char*s){char*a=strlen(s)?s:"0";g=h+=atoi(a);return 0;}

これはおそらく大幅にゴルフすることができますが、魔法の値ではなく引数なしで呼び出すことでこの問題を解決するために、言語拡張なしでCを使用できるという概念実証として役立つはずです。

* @hvdは、これはgccを使用してすぐに機能しますが、一部の動作はC標準で定義されていないため、移植性がない可能性があることに注意しています。自己責任!

ゴルフをしていない:

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

#define f(X) start("" #X) ? 0 : f0
#define f0(X) update("" #X) ? 0 : f1
#define f1(X) update("" #X) ? 0 : f0

long f0 = 0;
long f1 = 0;

int start(const char *s) {
    f0 = f1 = strtol(s, NULL, 10);

    return 0;
}

int update(const char *s) {
    const char *a = strlen(s) ? s : "0";
    f0 = f1 += strtol(a, NULL, 10);

    return 0;
}

int main() {
    printf("f(1)()          -> %ld\n", f(1)());
    printf("f(1)(2)(0)(3)() -> %ld\n", f(1)(2)(0)(3)());
    printf("f(1)(-2)(3)()   -> %ld\n", f(1)(-2)(3)());
    printf("f()             -> %ld\n", f());

    return 0;
}

gcc arbitrary-length-currying.c -o arbitrary-length-currying && ./arbitrary-length-currying出力を使用したコンパイルと実行(いくつかの警告の後)

f(1)()          -> 1
f(1)(2)(3)(0)() -> 6
f(1)(-2)(3)()   -> 2
f()             -> 0

「任意の言語拡張なし」 -の間で交互のトリックghそれが未指定だと、マクロ呼び出しの連鎖を継続するには、動作が保証されていないかどうか、次のg最初の拡張のコンテキストに表示されますg。C11は6.10.3.4に例を追加して、指定されていないことを示しています。(IIRC、TenDRAのプリプロセッサは、望みどおりに拡張しないものです。)それ以外は、空のマクロ引数と暗黙的なintの両方をサポートする言語のバージョンはないため、有効なCプログラムは両方を使用できません。:)それでも、いい答えです。さらにゴルフを楽しみますか?
hvd

@hvd:ええ、おそらく数日中に戻って、ゴルフができるかどうかを確認します。これは不特定の動作であることは間違いありませんが、ここでの標準的な扱いは、言語が実装によって定義されるということです。gccで動作する限り、私は満足しています。
ジュリアンウルフ

私はあなたがあなたの答えに含めたコメントに対処しただけで、それは言語拡張に依存していないということです。はい、言語拡張機能を使用しても、ここでの回答としては完全に有効であり、別の方法で提案するつもりはありません。
hvd

ああ、それは間違いなく公平です。追加のフラグは必要ありませんが、これは移植性がない可能性があることを明記する必要があります。
ジュリアンウルフ

*s代わりに、空の文字列をテストできstrlen(s)ます。C文字列は暗黙的な長さで、charvalue で終了します0。argあり/なしの呼び出しを許可する素敵なマクロハック!
ピーター

4

8086マシンコード、27バイト

00000000  bb 00 00 85 c0 74 13 01  d8 be 00 01 89 e7 47 47  |.....t........GG|
00000010  57 b9 1b 00 f3 a4 5b 89  47 01 c3                 |W.....[.G..|
0000001b

このマシンコードはアドレス0x100にある必要があり、小さなコードモデル(cs = ds = es = ss)を想定しています。ただし、余分なバイトを消費せずに関数の場所を変更できます。オフセットに配置0すると、(xor si,siではなくmov si, 0x100)バイトが節約されます

必要な呼び出し規約

これは、呼び出し元がスタック上に少なくとも27バイトを事前に割り当てていることを前提としています。で数値を受け取り、でax関数ポインタを返しますbx。でこのポインターを呼び出すとax=0、チェーンが終了し、で合計が返されbxます。
したがって、最初の呼び出しでは:

mov bp, sp
sub sp, 28
mov ax, number_to_add
call function
; new function pointer in bx

次に、後続の各呼び出しに対して:

sub sp, 28
mov ax, number_to_add
call bx
; new function pointer in bx

終了します:

mov ax, 0
call bx
; result in bx
mov sp, bp

Ungolfed(マシンコードのコメント付き分解):

00000000  BB0000            mov bx,0x0      ; 0 is replaced after copying
00000003  85C0              test ax,ax
00000005  7413              jz 0x1a         ; if(ax==0) ret (with value in bx)
00000007  01D8              add ax,bx       ; arg += total
00000009  BE0001            mov si,0x100    ; address of the original: ds:0x100
0000000C  89E7              mov di,sp
0000000E  47                inc di
0000000F  47                inc di          ; dst = sp+2 = above return address
00000010  57                push di
00000011  B91B00            mov cx,0x1b
00000014  F3A4              rep movsb         ; copy the function code.
00000016  5B                pop bx            ; bx = start of copy destination
00000017  894701            mov [bx+0x1],ax   ; update total in the copied code
0000001A  C3                ret               ; with bx = function pointer

ゼロ以外のAXでこれを呼び出した後、bx = spからのマシンコードの変更されたコピーがバッファに書き込まれfunctionます 最初の命令の16ビット即値が合計を保持します。(の前の最後の命令で書かれていretます。)

push di/ pop bxmov bx, di(の前にrep movsb)に置き換えると、よりシンプルになりますが、節約にはなりません。

呼び出し側がdstバッファーへのポインターを渡すように要求すると、di4バイトを節約しspます。

関数の開始アドレスを関数のサイズと同じにすると、バイトが節約されます(mov cx, si)。


マシンコードバイトの逆アセンブリを含めた場合、これはより良い答えになります。マシンコードの答えには間違いなく、未使用のバージョンが必要です。たとえば、次のobjdump -b binary代わりに使用しますhexdump -C
ピーター

コメント付きの逆アセンブリで更新されました。可能な節約:呼び出し元にdstポインターdi(4バイト)を渡す必要があります。関数をstartのmov cx, si代わりにaddress = size:にしmov cx, 0x1bます。
ピーター

2

C#、62バイト

dynamic f(int n)=>(System.Func<int,dynamic>)(m=>m<0?n:f(n+m));

コールを終了するには、負の数で渡します。例

f(1)(2)(3)(-1) == 6

null終了するパラメータを渡すか、まったく渡さずに動作させたいと思います。しかし、私が試したすべての方法はたくさん長かった
TheLethalCoder

!m代わりに使用して、または最後のパラメーターとしてm<0渡すことができますか?null0
betseg

@betseg C#ではNoはa Booleanとしてのみ使用できますBoolean...試しましたnullが、長くなりました。??LHSがnullの場合はRHS を使用しますが、LHSがnullでない場合はRHS を使用する必要があるため、使用できませんでした。
TheLethalCoder

2

Scala、58文字

case class f(n:Int){def apply(m:Int)=f(n+m)
def apply()=n}

オンラインで試す

ゴルフをしていない:

case class f(n:Int){
  def apply(m:Int)=f(n+m)
  def apply()=n
}

説明:

このコードはcase class、intを取るコンストラクターで呼び出されたfを定義します。equals、hashcode、toString、copyメソッド、および同名のコンパニオンオブジェクトを生成するケースクラスを定義して、newキーワードなしでオブジェクトを作成できるようにします。

このクラスにはオーバーロードされた適用メソッドがあります。1つは別の整数を追加して更新された合計で新しいオブジェクトを作成し、もう1つは引数なしで合計を取得します。

Scalaでは、applyメソッドを持つオブジェクトは、メソッドのように呼び出すことがo.apply(x)できますo(x)。つまり、と記述することができます。これは、配列、リスト、マップ、およびFunction1匿名関数によって実装される特性の標準ライブラリで使用されます



2

Perl 5、36バイト

sub f{my$n=pop;sub{@_?f($n+pop):$n}}

say f(1)->(); # 1
say f(1)->(2)->(3)->(); # 6

これには何が必要-M5.016ですか?-M5.016ドロップしてmyから、数バイトをドロップして保存できるはずです。ただの場合sayは、-E代わりにフラグを使用できますが、これはアクティブuse strictにならないため、をドロップできますmy
クリス

@クリスはあなたが正しいです、それは5.16を必要としません、私の最初のリビジョンは(を使用して__SUB__)しましたが、私は提出する前にそれを変更し、5.16についてのビットを削除しませんでした。削除します。myしかし、ドロップは正しいとは思わない。
ホッブズ

(いいえ、私はsayコードの一部としてカウントしていません、それは単に説明目的のためです)
-hobbs

1
myなしuse strictで削除すると、$n暗黙的にグローバル変数になります。適切なperlスクリプトでは不適切な形式ですが、ワンライナーではかなり一般的であり、ここで機能するようです。
クリス

2

Brain-Flak、6バイト

実際、ToSは有効な戻り形式ポップであるため、2バイトを節約する0は実際には必要ないことに気付きました。

({{}})

オンラインでお試しください!

元の提出物、8バイト

0特別な値として使用:

({{}}{})

オンラインでお試しください!

説明

引数a 1a 2、…、a n0を指定すると、スタックは最初は次のようになります。

                                                       a n

                                                       

                                                       A 2

                                                       A 1

                                                       0

その後、コードは続き、すべてiをポップし、それらを累積し、0をポップしてそれらを追加し、結果をプッシュします。

(      )  -- push the following value:
 {  }     --   while ToS ≠ 0 (sums the runs):
  {}      --     pop 1 element
     {}   --   pop the remaining 0 & add it

代替ソリューション、8バイト

0をポップして合計に追加する代わりに、正しいスタックが最初は空であるため、スタックをスワップすることもできます。

({{}}<>)

オンラインでお試しください!

-rフラグを使用すると、0がスタックの一番上にあるため、最初にポップできます。

({}{{}})

オンラインでお試しください!

{}({{}})

オンラインでお試しください!


なんてこった...素晴らしいものだ!
ユージンD.グベンコフ

2

C(GCC)、83バイト

私の最初のCゴルフ!他にもいくつかのCソリューションがありますが、これは少し異なります。プリプロセッサの使用は純粋に表面的なものです。このアプローチは、コナーオブライエンの回答最初に議論されました

#define r union r
t=0;r{int v;r(*f)();};r e;r f(a){t+=a;e.v=a?f:t;t*=a>0;return e;}

最終値はゼロです。戻り値は共用体なので、結果を呼び出すにはfield fを使用し、最終値にアクセスするにはfieldを使用しますv。例

f(1).f(2).f(3).f(0).v

オンラインで試す

制限事項

グローバル変数は現在の合計を保持します。これは明示的に許可されていませんが、サブミッションは繰り返しの呼び出しをサポートします(端末呼び出しで合計がリセットされます)。これがグローバル状態の禁止の理由と思われます。

へのポインタfは、intメンバーを通じて返された共用体に格納されるため、これは明らかに移植性がありません。これがすべてのプラットフォームのGCCで動作するのか、Linuxだけで動作するのか、x86だけで動作するのか、ELFだけで動作するのか、わかりません。


2

APL(Dyalog Classic)48 47 46 44 32バイト

r←(a f)x
r←⍎'(a+x)f'↓⍨-0=x

0f

オンラインでお試しください!

ゼロを渡すことで終了します。呼び出し構文:((0 f 1) 2) 0

@ngnのおかげで-15バイト

が必要です ⎕IO←0

ゴルフのヒントは大歓迎です!


ターミネーター値として0を使用できる場合は、「if」および「else」句に変更:If x<0:If×xて交換します
-ngn

Derp。「非肯定的」と言っているのが見えませんでした
ザカリー

このトリックを知っていますか?r←⍎condition⊃'else' 'then'
-ngn


22 ...と言ったと思った> _ <
ザカリー


1

Dyvil、34バイト

infix int apply(i:int,j:int=0)=i+j

使用法

0() // = 0
0(1)() // = 1
0(1)(2)() // = 3

末尾()は省略できます。

説明

2つのintを取り、それらを追加する並置演算子を定義します。パラメーターにjは、0引数なしの呼び出しをサポートするデフォルト値があります。0例では、上記の名前が、リテラルではありません。


1

ジュリア v0.5 +、52バイト

type F n end
F()=0
(f::F)()=f.n
(f::F)(x)=(f.n+=x;f)

として呼び出しますF。これはおそらく、より少ないOOメソッドを採用することで大幅に短縮できますが、私は常にこのイディオムを使用する機会を得ることを好みます。

「終了呼び出しの前に少なくとも1つの呼び出しが行われる」と想定できる場合、6バイトを節約するために2行目を削除できます。



1

R、40バイト

f=function(x)function(y)`if`(y,f(x+y),x)

ここでは0が停止値として機能します。さらに2バイトの場合は、省略できます。

問題は、Rに簡潔な組み込みラムダがないことです。ただし、1つ追加すると、コードを26バイトにできます

f=x->(y->`if`(y,f(x+y),x))

(はい、それは有効なRです。インポートが必要です。)


1

PHP、44バイト

@ user63956からのアイデア

終了コール 0

function f($i){return[$_GET[0]+=$i][$i]?:f;}

オンライン版

着信呼NULL必要CAST [$i][+$i]

PHP、47バイト

function f($i){global$s;return$i?f.!$s+=$i:$s;}

オンライン版

PHP、52バイト

終了呼び出し、NULLまたはPHPでfalseのその他の値

function f($i){global$s;$i?$s+=$i:print$s;return f;}

出力print$sdie("$s")+ 2バイトに置き換えられた後にプログラムを終了する必要がある場合

オンライン版


1
関数は(印刷ではなく)戻るべきだと思います$s。あなたreturn$i?f:$sは最後に何かをすることができます
コナーオブライエン

ConorO'Brien I @わかりませんが、あなたの思考が右である場合には、5つのバイトを救うことができるありがとう
イェルクHülsermann

1
スーパーグローバル変数を使用して、数バイトを保存できますfunction f($i){return[$_GET[0]+=$i][$i]?:f;}
user63956

@ user63956非常に良いアイデア
ヨルグヒュルサーマン

1

PowerShell、86バイト

$f={$n=$args[0];$f=(gv f).value;{if($args){&$f($args[0]+$n)}else{$n}}.getnewclosure()}

オンラインでお試しください!

テストコード:

&(&(&(&(&(&$f 4)2)7)5)2)

出力: 20


非常に素晴らしい。PPCGへようこそ!$n="$args"代わりにを実行すると、バイトを保存できます$n=$args[0]$args[0]ただし、追加ではなく文字列連結を取得するため、もう一方では機能しません。
AdmBorkBork


1

Python、69バイト

def f(a=0,s=[]):
    if a:
        return lambda b=0:f(b,s+[a])
    return sum(s)

1
私はこれがpythonだと仮定していますか?回答で使用されている言語を明記する必要があります。
corvus_192

答えをもっとゴルフしてみてください。現状では、ゴルフはあまり良くありません。
Rɪᴋᴇʀ


1

R、54 52バイト

f=function(x){g=function(y='')'if'(y>'',f(x+y),x);g}

MickyTのおかげで2バイト節約されました!

Pythonの回答の1つに似ています。ゴルフをしていない:

f=function(x){
  g=function(y=''){
    if(y>''){
      f(y+x)
      }
      else{x}
  }
  g
}

として実行

> f(1)(2)(4)()
[1] 7

1
よくやった。if句を囲む内部ブレースを取り除くことができます。f=function(x){g=function(y='')'if'(y>'',f(x+y),x);g}
MickyT

あなたの「無料」バージョンがなぜそうなのか、私は少し困惑していますreturnreturnRの言語は他の言語の言語とは異なり、早すぎる中断を実行します。使用しないことreturnは慣用的です。一方、あなたの未ゴルフバージョンはまだゴルフされていifます。
コンラッドルドルフ

@KonradRudolphゴルフifは怠lazでしたが、これreturnは読みやすさのためだけです-の有無にかかわらず同じ結果が得られreturnます。
BLT

@BLT Hm。Rの無償は、間違ったこと(早期終了)を通知し、貨物カルトプログラミングのインスタンスであるため、読みやすさをreturn 低下せると強く感じています
コンラッドルドルフ

クール、また新しいことを学びました。それが私が戻ってくる理由の一つです。おかげ@KonradRudolph、また、このスタックオーバーフローの問題が面白いです:stackoverflow.com/questions/11738823/...
BLT

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.