APLでのゴルフのヒント


28

私は最近、1つのコードゴルフチャレンジを開始しましたが、勝者はGolfScript(サプライズ、サプライズ!)のようです。おもしろいのは、GolfScriptに勝つチャンスがすべてある別の非常に強力なライバルがいたことです。その名前はAPLです。ここにAPLで書かれた多くの答えがあります。この言語はコードゴルフではかなり効率的であると思われるので、APLプログラムについて知っているコードゴルフのヒントを求めることにしました。いくつかのコード例を投稿してください。動作中の言語を見るのは通常非常に興味深いです。

回答:


23

編集:これを読んで、APLをまったく知らないが、それを使いたい人にとって、Dyalog APLをマスターすることは非常に良いリソースです。

  1. 評価は厳密に右から左です。これには変数の設定が含まれるので、それを利用してください。

    2+a, 1+a←1 -> 3 4

    aに設定され11+a評価され2a,2評価され1 22+1 2評価され3 4ます。

  2. Cと同様に、関数と組み合わせることができますa +← 3。Cとは異なり、これは汎用です:にfoo F← bar設定fooF barます。やや直感に反して、これが返す式として、barではなくを返しますF bar

    無名関数でも動作します:

          a←0
          a+←3 ⋄ a
    3
          a+←3 ⋄ a
    6
          a { ⍵/'!' } ←4 ⋄ a
    !!!!
    
  3. array:に割り当てることができA[3]←8ます。期待どおりです。ただし、複数のアイテムを同時に割り当てることもできます:A[3 5 6]←9 1 4、またはA[3 5 6]←9、すべてを同じアイテムに設定します。もちろん、ここに関数を追加することもできます。この場合、関数は各要素に個別に適用されます

  4. 彼はそれについてあまりにも幸せそうに見えなくても、あなたの友人です。

    1. Fがdyadicの場合、dyadic は引数a F b<->を切り替えますb F⍨ a。これは、中括弧を使用することからあなたを救うことができるので、ゴルフをするときに便利です:

      (F G H x) K y      <->     y K⍨ F G H x
      

      右手は常に左手よりも先に評価されるため、これにより評価順序が変更されます。

    2. Fがダイアディックの場合、モナド は関数の両側に同じ引数を適用します。

            5⍴5
      5 5 5 5 5
            ⍴⍨5
      5 5 5 5 5
      

      引数は一度だけ評価されます。これは特に外積に役立ちます。つまり、配列内の各値を同じ配列内の他の値と比較するため∘.=⍨に、行う必要のない代わりに使用できますx∘.=x←(whatever)

    3. Fが単項の場合、何も行いませんが、関数を引数から分離します。そのため、関数が複雑な場合でも、括弧を節約できます。

            {⍵+3}⍣5 6
            ∇{⍵+3}              
           ∇ ⍣ 5 6              
            ({⍵+3}⍣5)6
      21
            {⍵+3}⍣5⍨6
      21
      
  5. イディオムを学ぶ!その後、イディオムをゴルフします。例えば:

    ((((1↑⍴X),⍴Y)↑X)^.=Y)⌿X
    

    機械的に次のように変換できます。

    X⌿⍨Y^.=⍨X↑⍨(1↑⍴X),⍴Y
    

    そしてさらに:

    X⌿⍨Y^.=⍨X↑⍨(⊃⍴X),⍴Y
    

    (最初)1↑この場合と同等(1つを取る)。そしておそらく:

    X⌿⍨Y^.=⍨X↑⍨(≢X),⍴Y
    

    (集計)⊃⍴スカラー以外のすべての(形状の最初の要素)と同等です。


ラズベリーパイバージョンのほかに無料ライセンスを取得する方法はありますか?
Fabinout

それを得るための合法的な方法、明らかに。
Fabinout

2
@Fabinout:dyalog.comでは、無料のWindowsバージョンをダウンロードできます。[ダウンロードゾーン]をクリックしてから、[登録されていないダウンロード]をクリックします。登録が必要ですが、それ以外は完全に機能し、無料で合法です。あなたが学生の場合、フォームに記入することで無料で通常バージョンを入手できます。あなたが海賊行為であなたの人生を台無しにする国に住んでいないなら、あなたは何をすべきかを知っています。
マリヌス14年

Nars2000もあります。これは、Dyalog(およびいくつかのバグ)よりも多くの機能を備えたオープンソース実装です。素数関数やマルチセットなど、その機能の一部はゴルフに便利です。
トビア14年

1
GNU APLがあります。
M.アラグガン

14

電車

A(f g h)B      ←→  (A f B)g A h B  ⍝ fork
 (f g h)B      ←→  (  f B)g   h B  ⍝ fork
A(  g h)B      ←→         g A h B  ⍝ atop
 (  g h)B      ←→         g   h B  ⍝ atop
 (A g h)       ←→  ({A} g h)       ⍝ "Agh" fork
 (f g h k)     ←→  (f (g h k))     ⍝ 4-train
 (f g h k l)   ←→  (f g (h k l))   ⍝ 5-train, etc
 (f g h k l m) ←→  (f(g h(k l m))) ⍝ groups of 3 from the right, last could be 2
  f∘g B        ←→    f g B         ⍝ "compose" operator, useful in trains
A f∘g B        ←→  A f g B

これは、将来の読者のために、Oberonに短縮方法を伝えるべきではないということですか?
アダム

いいえ、PPCGで通常行うようにします。表現が(私が信じている)最短に達した後、その行を削除します。それは簡単なエクササイズです-あなたが個人的にそれから利益を得るとは思いません。
ngn

16まで下げることができますが、私はあなたのヒントを使用していません。
アダム

@Adámよく、あなたは電車を使用しています:)私は⎕MLのことを考えていなかったので、私のものは似ていました-ngn 18
1

から3個のグループ」ではないですか?
アダム

7

電車内/および電車内での対処のコツ

ときに電車を利用して、あなたは削減使用する場合がありf/合計のような+/、あるいは複製の減少を//。ただし、縮小の左側にさらに多くのパーツがある場合は、括弧を使用して上部を作成する必要があります。バイトを節約するためのいくつかのトリックを以下に示します。

1∊モナドの代わりに、∨/または∨⌿ブール配列で使用する

タスク:2つの等しい長さの文字列AとBが与えられ、AとBの対応する文字が等しい場合は2を返し、そうでない場合は0を返します。例えばA←'abc'B←'def'なります0A←'abc'してB←'dec'います2

dfnソリューションは可能性がありますA{2×∨/⍺=⍵}Bが、暗黙のうちにそれを短くしたいです。A(2×∨/=)B列車編成の規則2 (× ∨/ =)があなたが望むようにこれを解析するので、動作しません2 × (∨/=)

それを観察し∨/たり∨⌿、ブールベクトル(上∨/,または∨⌿,上位アレイ用)、すなわち、任意の1つのが存在するかどうかを尋ねる1∊我々は、私たちの列車を書くことができますので、2×1∊=

正しい引数を解くので、それを使用して各行または列を個別に減らすことはできません。

利用1⊥代わりモナドの+/+⌿

タスク:リストのリストLとインデックスNを指定すると、N番目のリストの合計の3倍を返します。例えばL←(3 1 4)(2 7)N←1を与え24ます。

dfnソリューションは可能性がありますN{3×+/⍺⊃⍵}Lが、暗黙のうちにそれを短くしたいです。N(3×+/⊃)L列車編成の規則3(× +/ ⊃)があなたが望むようにこれを解析するので、動作しません3 × (+/⊃)

un { abcd } =  a + b + c + d  =(a ×1³)+(b ×1² )+(c ×1¹)+(d ×1⁰)。したがって、+/a b c d同じである1⊥a b c d、と私たちは私たちのように、列車を書くことができます3×1⊥⊃

ランクの高い引数で1⊥は、と同等であることに注意してください+⌿

スカラー引数および/またはベクトル引数とともに使用するf.g代わりにf/g

タスク:リストLと数値Nが与えられた場合、Lの要素がNEg L←31 41 59で除算され、N←7を与える場合、最小除算剰余数の範囲1を返します1 2 3

dfnソリューションは可能性がありますN{⍳⌊/⍺|⍵}Lが、暗黙のうちにそれを短くしたいです。N(⍳⌊/|)L列車編成の規則⍳ (⌊/) |があなたが望むようにこれを解析するので、動作しません⍳ (⌊/|)

内積A f.g Bの引数は、スカラーおよび/またはベクトルでスカラ2つの関数のは同じですf/ A g B両方があるため(A[1] g B[1]) f (A[2] g B[2]) f (A[3] g B[3])など、私たちのように、私たちの列車を書くことができます⍳⌊.|

これは上位の配列では機能しないことに注意してください。

ブールの左引数と単純なベクトル右引数の∊⊆代わりに使用/

タスク:リストLと数値Nを指定して、Nより大きい数値のみが残るようにリストをフィルターします。例えばL←3 1 4N←1を与え3 4ます。

dfnソリューションは可能性がありますN{(⍺<⍵)/⍵}Lが、暗黙のうちにそれを短くしたいです。N(</⊢)Lバインディングルールがこれを解析するため、機能し(</) ⊢ませんが、演算子reduceではなく/関数replicateにしたいのです。

ブール型の左引数を持つダイアディックは、左引数の1の実行に従って右引数を分割し、0で示される要素を削除します。これは、私たちが望んでいるもののほとんどであり、不要なパーティションを保存します。ただし、monadicを適用することにより、パーティショニングを取り除くことができます。このように{(⍺<⍵)/⍵}なる可能性が{∊(⍺<⍵)⊆⍵}あり、したがって電車をとして書くことができます∊<⊆⊢

これは上位の配列では機能しないことに注意してください。

数値引数の0⊥代わりに、⊢/または⊢⌿数値引数とともに使用します

タスク:リストLと数値Nが与えられたら、NにLEgの右端の要素を掛けてL←3 1 4N←2与え8ます。

dfnソリューションは可能性がありますN{⍺×⊢/⍵}Lが、暗黙のうちにそれを短くしたいです。N(⊣×⊢/⊢)L列車編成の規則⊣ (× ⊢/ ⊢)があなたが望むようにこれを解析するので、動作しません⊣ × (⊢/⊢)

ことを確認して0⊥数値配列上と同じである⊢⌿ので、我々として私たちの列車を書くことができ、⊣×0⊥⊢

これにより、上位の配列の最後の主要なセルが選択されることに注意してください。


1
このチャットの回答をこれに追加できますか?
J.サレ

1
@J.Salléが追加されました。
アダム

7

乗算と加算を組み合わせるために使用します

(a×b)+C  ->  a⊥b,C
(C)+a×b  ->  a⊥b,C
(a×b)-C  ->  a⊥b,-C

仮定:

  • aそしてb、左引数として使用する場合、さらに括弧を必要としない用語です

  • C 左引数として使用する場合、括弧が必要な可能性のある式です

  • a b C 数値スカラーに評価する


5

複素数

しばしば見落とされがちですが、グリッド、迷路、フラクタル、幾何学を扱う表現を短縮する素晴らしい機会を提供します。

0j1⊥¨    0j1⊥   ⍝ pair(s) of reals -> complex
11 9∘○¨  11 9○  ⍝ complex -> pair(s) of reals
|z0-z1          ⍝ distance between two points
0j1×z   0j¯1×z  ⍝ rotate by ±90° around (0,0)
0j1*⍳4          ⍝ the four cardinal directions
+z       -+z    ⍝ reflect across x or y axis
+\0,z           ⍝ sequence of steps -> path
2-/z            ⍝ path -> sequence of steps
0j1⊥¨n-⍳2⍴1+2×n ⍝ lattice centred on (0,0)

4

モジュロベクトル長のインデックス付け

⊃i⌽aしばしばナイーブより短い⊃a[(≢a)|i]か、a⊃⍨i|⍨≢a(ここでaベクトルであり、i整数であり、⎕io0です)

(指摘に感謝EriktheOutgolfer)この上の便利なバリエーションがある:I↑Y⌽⍨I×XどこYいくつかの長さ-の連結であるIベクトルはとX私たちは、例えば、選択したいものの指標であります:3↑'JanFeb...Dec'⌽⍨3×month


3

定数関数

=⍨そして、≠⍨NGNへの感謝。

リストの各要素に単一の値が必要な場合があります。を使用したくなるかもしれませんが、使用する{value}¨方が短くなりますvalue⊣¨ が、いくつかの一般的な値では、さらに短くすることができます(を使用⎕IO←0):

¯1⍬⍸list

0⍬⍳list

1⍬⍷list

これらはリストでのみ機能することに注意してください(ネストされている場合もあります)。上位の配列の場合、次を使用してすべて0とすべて1を取得できます。

1=⍨

0≠⍨

を設定すると⎕ML←0、次のようにすべての数値をゼロにすることができます(あたかも)。

単一の数値のみが必要な場合は、1⊣またはを使用する代わりに、モナドを使用して1または0を取得できる場合があります0⊣


時には、あなただけのリストの各要素のための単一の値を必要としています。」 -注目すべきことは次のようになります。その値は、リストの最初の要素があるときに、あなたが使用することができます⊣\
NGN

@ngn私がいることを言うだろうして/、独自のポストメリット。
アダム

2

つかいます

括弧を避ける

(通勤)括弧を避けることでバイトを節約できます。左の引数を括弧で囲む必要があり、右の引数を括弧で囲まない関数がある場合は、バイトを保存できます(例:(A<B)÷C→)C÷⍨A<B

ダブルアレイ

配列のコピーを末尾に追加するには、,⍨Aまたはを使用します⍪⍨A

ダブルナンバー

2∘×double を使用する代わりに+⍨、引数を自分自身に追加するため、1+2∘×→ を使用できます1++⍨

平方数

2*⍨Y正方形に使用する代わりに×⍨Y、引数とそれ自体を乗算するため、2*⍨A+B→ を使用できます×⍨A+B

ランダム順列

?⍨N長さのランダムな順列を与えますN

自己分類

各主要セルの最初の出現のインデックスを見つける ⍳⍨A

ブールベクトルの末尾の1をカウントする

+/∧\⌽B末尾の1の数を数える代わりに、N使用できます⊥⍨

逆構成

A f∘g BですA f g Bが、必要な場合はを(g A) f B使用してくださいf⍨∘g⍨

逆引き

f/ a1 a2 a3ですa1 f (a2 f a3)。必要に応じて(a1 f a2) f a3、を使用しますf⍨/⌽

逆スキャン

f\ A B Cです
A (A f B) (A f (B f C))

f⍨/∘⌽¨,\ A B Cです
A (A f B) ((A f B) f C)

f⍨\⌽ A B Cです
((A f B) f C) (B f C) C

⌽f/∘⌽¨,\⌽ A B C。です
(A f (B f C)) (B f C) C


2

文字列の文字を列挙せずに列挙します ⍳≢

タスク:2つの文字列SとTが与えられ、それらの連結のインデックスをリストします。例えばS←'abcd'T←'xyz'を与え1 2 3 4 5 6 7ます。

dfnソリューションは可能性がありますS{⍳≢⍺,⍵}Tが、暗黙のうちにそれを短くしたいです。⍳≢,列車解析ルールがこれを(⍳)≢(,)あなたが望むように解析するので、は動きません(⍳≢),

左引数が空のDyadic は、現在の順序に従って単純な文字配列を格付けし⍳≢ます。これはと同じです。このように{⍳≢⍺,⍵} なることができる{⍬⍋⍺,⍵}ので、私たちは電車をとして書くことができます⍬⍋,

これは、数値配列または混合配列では機能しないことに注意してください。


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