プレフィックス表記からポスト表記へ


19

免責事項:いいえ、これは文字列を逆にするための冗談の挑戦ではありません。

仕事

サポートする操作は、減算(-)だけです。

また、サポートするアトムは2つだけです(ゼロ(0)および1(1))。

ここでは、プレフィックス表記は、-AB後置記法に相当しAB-AかつB式です。

あなたの仕事は、プレフィックス表記の式を、ポストフィックス表記の同等の式に(再帰的に)変換することです。

定義

プレフィックス表記の式は、次の文法によって生成されます。

S > -SS
S > 0
S > 1

後置記法の式は、次の文法によって生成されます。

S > SS-
S > 0
S > 1

Prefix notation:  --01-0-01
Parentheses:      -(-01)(-0(-01))
Convert:          (01-)(0(01-)-)-
Postfix notation: 01-001---

ルールと自由

  • 一貫性がある限り、操作とアトムの名前を任意の文字に変更できます。
  • 入力形式は出力形式と一致している必要があります(入力がプレフィックス表記であり、出力がポストフィックス表記であるという事実は別として)。

テストケース

Input       Output
1           1
0           0
-01         01-
-10         10-
--01-0-01   01-001---

Dadaのテストケースクレジット。


1
さらにいくつかのテストケースを追加してください。
シャギー

@Shaggyどんな種類のテストケースが欲しいですか?
リーキー修道女

@LeakyNun回答の最新バージョンで行ったように、入力と出力をイテレータとして使用しても問題ありませんか?
L3viathan

L3viathan I @そう...と仮定
漏れ修道女

回答:


12

brainfuck、32バイト

,[[->++++<<+>]>[[-]<<[.[-]<]]>,]

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

私は使った @コードポイント(64)が便利なので、操作としてました。 U3 * 85 + 1 = 256 = 0を使用して、同じバイトカウントでも可能です。

説明

テープはスタックとして使用されます。メインループの各反復で、データポインターはスタックの最上部の2つのセルを開始します。

,[                Take input and start main loop
  [->++++<<+>]    Push input, and compute 4*input
  >[              If 4*input is nonzero (and thus input is not @):
    [-]<<           Zero out this cell and move to top of stack
    [.[-]<]         Pop from stack and output until \0 is reached
  ]
  >,              Move pointer into the correct position.  If input was @, the earlier > pushed \0 onto the stack.
]

6

網膜37 30 29バイト

M!`-*.
+m`^-(.*)¶(\d.*)
$1$2-

オンラインでお試しください!用語は常に数字で始まることを認識して7バイトを節約したので、一致を最後まで制限する必要はありません-(以前は2つの用語が続くことが保証されていた唯一のものでした)。-sを独自の行に入れないことで1バイトを節約しました。たとえば、-01-0¶1に置き換えられ01-ます。私が持っている場合今、--010つまり--0¶1¶0、私はインナーを変更する-0¶1には01-、私は交換することができるように-01-¶0して01-0-、それは問題で実際にしない2の-S I削除、など、行の先頭に1を削除し、私はそうテストが簡単です。


これはあなたのものだと思います:)
レオ

@Leo DOESは例えば、一般的には動作しません-0-0-00になるはずです0000---
ニール

あなたは正しい、ごめんなさい。私は別のアイデアを持っていますが、それはかなり異なっているので、新しい答えとして投稿します
レオ

1
@レオ私は今何かを見つけました...-
ニール

1
@Leo最新のゴルフで私たちは結ばれました!
ニール

6

Haskell62 59バイト

f(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
fst.f

オンラインでお試しください!使用法:fst.f $ "--01-0-01"0また1、文字よりも大きい任意の文字を指定できます-

編集: Zgarbのおかげで-3バイト!

この関数fは、1つの式を再帰的に解析し、有効なprefix-expressionを作成できる単純な文法に従って、この式のタプルを後置記法と残りの文字列で返します。

<exp> ::= - <exp> <exp> | 0 | 1

a入力文字列の最初の文字がより大きい場合-、アトミック式になり、文字とa入力文字列の残りを含む文字列のタプルを返します。

が見つかった場合-、2つの式を解析する必要があります。これは(a,x)<-f r、最初の式を取得しa、残りの文字列をx再度解析(b,c)<-f xして、2番目の式bと最後の残りの文字列を取得することで実現できますc。タプルでは関数2をタプルの2番目の要素にマッピングし、3バイトよりも短い(a,(b,c))<-f<$>f rため<$>、これは正確に行われます(a,x)<-f r,(b,c)<-f x。式と残りの文字列の両方を取得した後、式が連結され、「-」が追加されます(a++b++"-",c)


1
ケースを組み合わせることで3バイトを節約できますf(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
。– Zgarb

@Zgarbありがとう!何らかの理由でf(x:r)|x<'0',(a,(b,c))<-f<$>f r=(a++b++"-",c)|1<3=([x],r)、両方のケースを組み合わせたバージョンを探したときだけ考えました。これはバイト長です。
ライコニ

5

Haskell、54バイト

v f""=""
v f(a:s)=last(v.v:[id|a>'-'])((a:).f)s
h=v h

この関数vは、文字列と関数を受け取り、最初の部分式を再配置し、すべてが再配置されるまで、文字列の残りの部分に関数を適用します。呼び出しスタックと関数引数は、どの式が解析されているかを追跡します。この関数hはチャレンジに答え、vダミーの最初の引数としてそれ自体で呼び出されます。


1
うわー!(1)それはわずか53であり、最後の改行を数える必要はありません。(2)最初の行はv f l=l、2番目に移動すると短縮できます。
Ørjanヨハンセン

1
複数の式全体を解析する必要はないと思うので、無名関数を使用してバイトを保存できますv id
Ørjanヨハンセン

1
実際、最初の行は有効な入力で呼び出されることはないため、削除するだけです。
Ørjanヨハンセン

1
ガードに分割することは、lastトリックを1バイト上回ることになります。
Ørjanヨハンセン

4

Perl 5、57バイト

sub f{"@_"=~s/x((?0)|.)((?0)|.)/my$n=$2;f($1).f($n).x/re}

x代わりに演算子として使用します-(以下のTryItOnlineリンクを参照)。

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

説明:
/x((?0)|.)((?0)|.)/完全な式に再帰的に一致します:x最初にa 、次に式(?0)(再帰呼び出し)またはアトム(.)の後に別の式または原子が続きます。
次に、2番目の式/アトム(my$n=$2;)を保存する必要があります。そうしないと、再帰呼び出しで上書きされます。
関数が再帰的(最初の式で呼び出されたf($1)後、第2に、) f($n)、およびx(末尾に添付されています.x)。


4

Pythonの3、117 112 105 100 98 76 62 61 59バイト

def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]

変更ログ:

  • 可能な場合は改行を削除しました(-5バイト)
  • 全機能の代わりにラムダ(-7バイト、@ Dadaに感謝)
  • 他にない(-5バイト、@ Leaky Nunに感謝)
  • 熱心なゴルフを取り消す(-2バイト、@ Leaky Nunに感謝)
  • 代わりにグローバルリストで動作します(-22バイト)
  • 実際には、代わりにイテレータで作業しましょう(-14バイト)
  • 変更!=>(-1バイト、@ovs'提案からコピー)
  • 遅延評価のトリック(-2バイト、@ ovsに感謝)

次のように使用します。

>>> list(p(iter("--01-0-01")))
['0', '1', '-', '0', '0', '1', '-', '-', '-']


2
lambda x:p(x)[0]おそらくあなたのf機能を置き換えることができます。
ダダ

1
必要ありませんelse、考えます。
リーキー修道女

1
d="-"本当にバイトを節約できますか?
リーキー修道女

1
def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]59バイトの場合
-ovs

3

Pyth、20バイト

L+&-hbTsyM.-Btbytbhb

これにより、yパラメーターとして文字列を予期する関数が作成されます。

オンラインで試す:デモまたはテストスイート

説明:

この関数yは、最初のプレフィックス式を解析してポストフィックス式に変換します。したがって、のようy"10"に呼び出された場合にのみ返され1ます。

L+&-hbTsyM.-Btbytbhb
L                      define a function y(b), that returns:
   -hbT                   remove the chars "10" from the first char b
                          (T=10, and - will convert a number to a string)
  &                       if this gives the empty string (a falsy value)
 +                hb         then append b[0] to it and return it
                             (so this will parse a digit 0 or 1 from the string)
  &                       otherwise (the first char is a -)
               ytb           parse the first prefix expression from b[1:]
                             (recursive call)
          .-Btb              remove this parsed expression bifurcated from b[1:]
                             this gives a tuple [b[1:], b[1:] without first expr]
        yM                   parse and convert an expression from each one
       s                     join the results
 +                hb         and append the b[0] (the minus) to it and return

2

網膜34 31 29バイト


;
-;
¶
+`¶(.+);(.+)
$1$2-
;

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

;ノードを示すために使用されます。ノードは、最初は単一の番号で構成され、その後、既に解析されたものに成長します。-が改行に変換されるので.+、解析されていないもの以外の何でもつかむことができます-


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