Pythでのゴルフのヒント


46

PythはPythonにヒントを得た手続き型プログラミング言語で、PPCGユーザーisaacgによって作成されました

Pythでゴルフをするための一般的なヒントは何ですか?私は、少なくともPythに特有のゴルフ問題全般のコードに適用できるアイデアを探しています。

回答ごとに1つのヒントをお願いします。

回答:


25

最初にPythonでコードを書く

PythはPythonに非常に似ているため、PythonプログラムをPythに翻訳するのは非常に簡単です。ただし、Pythはコマンドごとに1文字の言語であるため、Pythをそのまま記述するのは難しい場合があります。最初にPythonで書くことにより、一度に考えることは少なくなります(Pythonはコーディングが非常に簡単な言語であるため)。


1
また、PythでPython構文を使用できるので、プログラムの一部を個別に変換したり、必要に応じてPythonを使用したりすることもできます。(ここでやったように
FryAmTheEggman 14年

@ mbomb007 Pythインタープリターをダウンロードし、ドキュメントを読みます。それが、Pythプログラムを書くための唯一の信頼できる方法です。
ジャスティン

@ mbomb007ごめんなさい。それが私がPythを書く方法を学んだ方法です(ソースコードを見て)。Pythに関するドキュメントは基本的にありません。基本的に試行錯誤して構文を学習する必要があります。
ジャスティン

22

変数を知る

Pythには、3つのカテゴリの変数があります。汎用の事前初期化変数、ユーザー入力に基づいて事前初期化された変数、および最初の使用時に暗黙的に割り当てを生成する変数です。

ジェネリック変数:

b = "\n"
d = " "
k = ""
G = "abcdefghijklmnopqrstuvwxyz"
H = {}                            # (empty dict)
N = '"'
T = 10
Y = []
Z = 0

入力初期化変数:

Q = eval(input())
z = input()

これらの初期化は、関連する変数がコード内の文字列の外側で使用される場合にのみ、指定されたプログラムで実行されることに注意してください。さらに、両方が使用される場合、順序はQ、次にzです。

初回使用変数の割り当て:

JおよびK。両方を同じ値に初期化する場合は、などの式を使用して初期化できます。KJ0これは、lengthierと同等J0K0です。


18

さらに新しいオンライン通訳を使用して、回答をテストしてください。

これは新しいソフトウェアであるため、バグがある可能性があります。問題を報告してください。


2
驚くばかり!私はグーグルでこれを見つけることができませんでした、必要なものだけです!
-theonlygusti

12

行末の文字列には、終了引用符は必要ありません。例えば:

"Hello, world!

完全に有効なHello Worldプログラムです。


本当に明らかなことですが、これは「Pythプログラミング言語」の最初のGoogle結果です。エソランで独自のページを作成しましたか?
theonlygusti

3
@theonlygustiはい、そうしました。また、昨年10月に初めての結果ではありませんでした。
isaacg

9

C基本圧縮に使用

これは実際には文書化されておらず、文字列のCは実際に直接chr-> intではなく、ベース256->ベース10(1つの文字列で同じ)です。これは、intの圧縮に非常に役立ちます。このスクリプトを使用して圧縮できます。

sCMjQ256

取り12345678910、それはßÜ>(そこにいくつかの印刷できないもの)になります。

また、intの配列では、それらを連結できます。また、コードポイントに変換し、ベース128の数値として処理することで、大きな文字列でも使用できます。

のもう1つの使用法はC、@ xnorにこれを見せてくれてありがとう、任意の大きな数字を作ることです。素朴な方法は次のとおりです。

^TT

しかし、次の方法で1バイト改善できます。

CG

このベース256は、アルファベット全体を逆変換します。結果156490583352162063278528710879425690470022892627113539022649722=〜1.56e62


ドキュメントに追加されました。
isaacg


8

短い機能...エラー...機能を使用する

ラムダの引数た場合mapまたはreduce単に引数に一つの操作を適用し,,あなたは短いフォームを使用し、できるMFfMxはと同等でmfdxfFxはと同じです.UfbZx。たとえば、入力として数値のリストを取得し、各数値が増分されるとしましょう。最初のアプローチは次のとおりです。

mhdQ

ただし、次のように書き換えることができます。

hMQ

同様のことがに適用さreduceFます。例として、整数のリストの積を計算するという課題があるとします。繰り返しますが、最初の試行は次のとおりです。

.U*bZQ

ただし、ではF、次のように短縮できます。

*FQ

3バイト削ります...悪くない!


Q関数に入力が欠落している場合は補完されるため、必要ありません*F
スタンストラム

7

Pythの実装を最新の状態に保ちます。

私はPythをかなり定期的に改善しており、あまり有用でない機能を削除し、より有用な機能を追加しているので、最新情報に注目し、定期的に実装のコピーを更新してください。

最近追加された機能:(10/19/14現在)

y*2数値として、および文字列とリストのすべてのサブセットのリストとして機能します。例えば:

pyth -c 'y"abc'
['', 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc']

ff通常はfilterコマンドです。現在、2番目の引数として数値を指定して呼び出すと、その数値で始まり1ずつカウントアップする無限シーケンスをフィルター処理し、結果のシーケンスの最初の要素を返します。

たとえば、10億を超える最小の素数を見つけるコードは次のとおりです。

pyth -c 'f!tPT^T9'
1000000007

これらは便利な追加のように見えますが、古いものの代わりに何を使用できますyzか?mvdczd...最短の方法ですることはできません
デニス

1
@Dennis Pyth yが複数の非常に簡単に解析される入力形式、たとえばPython形式など、1つだけを持つ必要はないと思うので、古いものを捨てました。それで、はいmvdczd、残念ながら、やらなければならないと思います。
isaacg 14年

@Dennisの問題は解決し、これをrの文字列処理スイートに追加しました。
isaacg 14年

rとても便利に見えます。
デニス14年

@isaacgこれがトピックから外れている場合は申し訳ありませんが@、Fdr1 + 1 @ Q2Iq%Qd0d のルート操作を使用して係数計算機を作成する方法を疑問に思っています。使用しようとすると、index代わりにデフォルトの意味が使用されます。この動作を回避する方法はありますか?
スターダスト

5

関数の名前付き引数(サポートされなくなりました)

関数のデフォルト値がゴルフに役立つ場合があります。Pythは実際にこれをサポートしています(驚いたことに)。例えば:

DC=Z1RZ;C;C5

印刷されます:

1
5

これを行うときに、JとKを使用して文字を保存することもできます。

DgJ1K1R+JKg;g2;g2 3

プリント:

2
3
5

これは通常、再帰アルゴリズムに役立ちます。

これはもはや機能しませんが、誰かが古いバージョンのPythを使用してゴルフをしたい場合に備えて、ここに残しました。


16
うわー-Pythがこれをサポートしていることに気づかなかったので、言語を書きました!
isaacg

残念ながら、これはPythのより新しいバージョンでは機能しなくなりました。
isaacg

このヒントは、他の古いヒントの1つと同様に削除する必要がありますか?そうでない場合は、このヒントが適用されるバージョンをマークする必要があります。
mbomb007

@ mbomb007私はバージョンを見つけることを意味してきましたが、私はあまりにも怠beenでした。私がそれを見つけるまで、その方が良いと思うなら、それを削除します。
FryAmTheEggman

@FryAmTheEggmanタイトルでサポートされていないと言っているので、あなた次第だと思います。
mbomb007

5

を使用して2つの要素タプルを展開する F

ある2つのアリティ関数rに対して、2要素のタプルがありJ = (a, b)、欲しいとしましょうr(a,b)

これを行う単純な方法はrhJeJです。

これを行うための便利な方法はr.*J、unpack演算子を使用することです。

これを行うための本当におしゃれな方法はrFJ、fold演算子を使用することです。


.uそのために使用することはまだ可能ですか?.u今は累積的に減少しているようです。
ヴェン

.u->。*これは少し前に行われた変更ですが、決して更新されませんでした。
isaacg

4

短い算術関数を使用する

h:リストの最初の要素を返す以外に、数値をインクリメントします。たとえば、とhT評価され11ます。より短い+1T

t:これは、数値をデクリメントします(リストの末尾を返す以外)。たとえば、とtT評価され9ます。より短い-T1

y:これは数値を2倍にします。たとえば、とyT評価するか20*T2またはより短い+TT


4

mapリストの生成に使用

基本的には、Pythonのファンシーリストの内包表記に相当します。既存のリストまたは範囲を使用して、値が重要でない場合でも、各値を反復処理してマッピングします。

2つの例:

  • 8個のゼロのリストを生成します。

    mZ8 の代わりに *8]Z

  • 0〜9の5つの乱数のリストを生成します。

    mOT5 の代わりに V5~Y]OT)

    2番目のものはリストを自動的に割り当てますY(実際にはYに追加します)が、さらに=YmOTU5短いものです。


4

EOFでの暗黙的なQ

これは、今日の新しい変更です。

Q評価された入力に対して自動的に初期化される変数です。アリティを解決するのに必要な回数だけ、Pythプログラムの最後に暗黙的に追加されます。ゴルフにこれを使用する方法の例を見るために、入力のCollat​​z関数を計算したいとします。

最短の書き方は次のとおりです。

@,/Q2h*3QQ

ただし、Qファイルの末尾ではsが暗黙的であるため、次のように簡単に記述できます。

@,/Q2h*3

2バイトを節約します。

注非必須の引数を持つ関数を充填これらの引数を持っていないということ。例えば、c"12 12"暗黙的を持っていないQため、c唯一の1つの引数が必要です。


3

関数を繰り返し適用するには、reduceを使用します。

変数をそれ自体の機能に設定し、特定の回数繰り返す必要があるとします。たとえば、入力からCollat​​zシーケンスの後で100番を見つける問題を考えてみましょう。初期数がの場合、シーケンス内の次の数を見つける最短の方法Q

@,/Q2h*Q3Q

これを100回適用して結果を印刷する最も明白な方法は

V100=Q@,/Q2h*Q3Q;Q

100回ループし、毎回Q​​の値を更新してから、ループを終了してQを出力します。

代わりに、シーケンス変数(H)を無視するreduce関数を使用できます。

u@,/G2h*G3GU100Q

これは2文字短くなります。シーケンス内の要素と同じ回数だけループしようとすると、3文字短くなります。


3

通常、Anyに代わる短い選択肢があります

シーケンスのいずれかが条件を満たしているかどうかを確認する場合、通常はを使用します.Em。たとえば、リスト内のいずれかが5以上であるかどうかを確認する場合:

.Emgd5Q

しかし、smsumはboolsで機能するため、true / falseではなくtrue / falseである必要があるだけであれば機能します。

smgd5Q

filter を使用して、さらに短くすることもできます。

fgT5Q

最後のものは本当にthoughいように見えます。

.All については、私が考えることができる唯一のことは、反対の条件を使用し、1文字保存するためにそれを否定することです.Am

!f<T5Q

3

すべての制御フローオプションを確認します

ループ:

F:forループ。Pythonのように。

V:範囲にわたるforループ。変数も範囲も指定する必要がないため、2文字短くなります。

W:whileループ。Pythonのように。

#:無限のwhileループ。エラーまたは明示的なブレークでエスケープします。Pythでのみtry ... except機能します。

機能:

D:一般的な定義。Pythonと同じです。

L:1つの引数、Pythonのラムダのような割り当て関数はありませんが、名前が付けられています。関数名、変数名、およびリターン(R)を指定する必要はないため、3文字短くなります。

関数型プログラミング:

f:フィルター-入力ラムダで真理を返す入力シーケンスの要素を選択します。

f:入力以上の最初の整数で、真のフィルター結果が得られます。

m:マップ-入力ラムダを使用して入力シーケンスの要素を変換します。

u:Reduce-入力ラムダで入力シーケンスを折りたたみ、アキュムレータを3番目の引数に初期化します。

o:順序-入力ラムダをキーとして使用する入力シーケンスの古い要素。

通常、特定の問題には複数の可能性があり、それぞれでテストソリューションを作成することによってのみ、どれが最短であるかを判断できます。


.x最近ではtry-exceptブロックに使用できます。
mbomb007

@ mbomb007はブロック以外を無視する方法がありますが、それは空のままにしておくことができますか?例:.x{some_statments}{except_block - can this be empty}
グルパッドママダプール

@GurupadMamadapur # ... Bは、式の内部にいない場合はこの方法で使用できます
-isaacg

3

リスト内の2つの要素を切り替える

2つの要素を切り替えるのは非常に費用のかかる作業です。そのため、使用したい2つのアプローチがあります。

TMP変数アプローチ

準備として、リストを定義し、Yいくつかの番号を入力します。目標は、2番目と3番目の要素を切り替えることです。

=Y[1 3 5 3 6 7)AGH,1 2

単純にtmp変数を割り当て、J = Q[G]最初のリストの割り当てをY[G] = Y[H]行い、次に2番目の最後の割り当てを行いY[H] = Jます。ここでのコツは、2つのリスト割り当てをネストすることです。したがって、印刷を抑制したり、referを2回使用したりする必要はありませんY

J@YGXXYG@YHHJ

の代わりに

J@YG XYG@YHXYHJ

翻訳アプローチ

切り替えたい要素がリスト内で一意である場合、このアプローチを使用します。本当に短いです。そのため、今回は1番目と3番目の要素を切り替えます(値15は一意です)。

=Y[1 3 5 3 6 7)K,Z2

これはリストの翻訳機能を使用します:

XYm@YdK)

この翻訳は、すべての要素を置き換えY[0]Y[1]、すべてY[1]Y[0]。そのため、値が一意でない場合、悪いことが起こりました。たとえば、K,1 2結果はになり[1, 5, 3, 5, 6, 7]ます。

ステートメントがコードの最後のステートメントである場合、閉じ括弧はオプションです。


3

でデバッグする <newline>

コードが命令型プログラミングスタイルで記述されている場合、中間結果を簡単に出力できるため、デバッグが非常に簡単です。(パーマリンク

FN.:Q2                loop
      =Y+-Y-FNhN      some random command
                Y     print intermediate result
                 ;Y   end for loop and print result

しかし、大量のPythプログラムは、map、filter、reduceなどの関数型プログラミングの要素を使用しているため、単純な印刷はできません。しかし、\nコマンドを使用して、まだ可能です。

u(reduce)を使用する同じコードは次のようになります:(permalink

u        .:Q2Y   reduce .:Q2, start with G = Y
 +-G-FHhH        random command

中間値を出力する場合は、単に挿入するだけです\n:(permalink

u         .:Q2Y   reduce
   \nG             print(G)
 +-\nG-FHhH        random command

\naa改行で出力してを返しますa。したがって、プログラムの機能を変更することを心配することなく、どこにでも挿入できます。


最近では、このために改行を使用できますが、改行も印刷されます。
-PurkkaKoodari

@ Pietu1998はい、いつも使っています。投稿を更新する時間。
寂部

3

最大2つの整数を見つける

g#

たとえば、あなたが持っていると仮定J=5してK=12。その後、g#JK= 12、およびg#KJ= 12も同様です。

これは@ Pietu1998によって発見されました。

誰かがすでにそれを見つけたかどうかはわかりませんが、2バイトでmax(A、B)を実行するクールな方法があります。3を使用する必要はありませんeS,ABg#AB同じことをします。(ただし、max(1、A-B + 1)回ループするため、非常に非効率的です。最適化は、Bのように大きくなる可能性が高い数値を置くことです。)


@ジャクベこれは本当です。チャットでこれを入力しているときに何かを間違えているようです。
PurkkaKoodari

2

Pythのjoin方法

joinPython のメソッドは、文字列のみを結合するため、少し面倒なことがよくあります。Pyth's joinはより寛大です。デフォルトでは、文字列内のすべてのオブジェクトを変換します。

例えば、jkUT与える0123456789jb["abc"4,5\f]7与える

abc
4
(5, 'f')
[7]

最近、さらに文字列に変換する機能が追加されました-最初の引数も同様に文字列に強制されます、例えばj2\a\b->"a2b"
isaacg

1

数値が整数かどうかを知る

I巧妙なトリックは、nvariantを使用して、数値が整数であるかどうかを判断することです。

sI

これは、切り捨てたときに数値が変わらないかどうかをチェックしますが、整数の場合は変わりません。

たとえば、これを完全な正方形チェックとして使用できます。

sI@Q2

1

Packed Pythを使用する

Packed Pythは新しい「プログラミング言語」であり、Pythとまったく同じですが、文字ごとに8ビットではなく文字ごとに7ビットを使用します。

これを使用するには、pythリポジトリーを複製します。ファイルpacked-pyth.pyはインタープリターです。

あなたのコードがであるとしましょう"Hello, world!

まず、ファイルにそれを入れます: echo -n '"Hello, world!' > code.pyth

次に、PythコードをPacked Pythファイルにパックします。 python3 packed-pyth.py -p code.pyth code.ppyth

最後に、Packed Pythコードを実行します。 python3 packed-pyth.py code.ppyth

コードを実行するとき、-d実際に実行されているPythコードが何であるかを確認するフラグを提供し、コードを含むファイルの後に2番目のコマンドライン引数として入力を提供できます。

逆さま:

  • コードは1/8短くなります。

欠点:

  • ASCIIのみ。

  • インタラクティブな入力はありません。

  • 完全なデバッグオプションは使用できません。

  • 悪いエラー報告。


1
セーフモードの場合と同じように、フラグに移動できますか?
マルティセン

これは素晴らしいです:D
Maltysen

@Maltysenバイトスコアが1つ増えると思います。
isaacg

Pythは印刷可能なASCIIのみを使用するため、さらにパックできませんか?
リルトシアスト

1

IとGCD を使用した分割可能性テスト

免責事項:これ、負でない整数でのみ機能します。

2つの非負整数が割り切れるかどうかを確認するには、次の操作を実行できます。

iI<divisor><dividend>

場合によって割り切れるB≥B≥0 、次いでGCD(A、B)= B

必ずしもバイトを節約するわけではありません!%<dividend><divisor>が、次の理由で節約がもたらされる可能性があります。

  • Pythプログラムの終了時に(Q配当のような)暗黙的なものを微調整できる場合があります。
  • <pfn>単独で機能するため、として使用できます。
  • によるモジュロを処理し0ます。

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


もう1つの利点iIは、それ自体では関数!%ですが、そうではないため、プレフィックス関数として使用できます。
エリックアウトゴルファー

@EriktheOutgolferありがとう、利点のリストに追加:)
Xcoder氏17

0

自身に適用される関数に変数を割り当てる

アリティ1の関数があり、それを変数に適用してそれ自体に適用する場合、次の構文を使用できます。

=<function><variable>

の代わりに:

=<variable><function><variable>

たとえば、変数をインクリメントする場合はZ、次の操作を実行できます。

=hZ

これで1バイト節約できます=ZhZ

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