デコードファクターツリー


11

ファクターツリーのエンコードに失敗した場合のファクターツリーの定義は次のとおりです。

  • 空の文字列は1です。
  • 連結は乗算を表します。
  • 括弧(またはペア文字)で囲まれた数値nは、n番目の素数を表し、2が最初の素数です。
    • これは再帰的に行われることに注意してください。n番目の素数は、括弧内のnの因子ツリーです。
  • 数値の因子は、最小から最大の順に並べる必要があります。

たとえば、2〜10の因子ツリーを次に示します。

()
(())
()()
((()))
()(())
(()())
()()()
(())(())
()((()))

この課題では同様の形式を使用します。ただし、この課題はこれらの構造をデコードすることです。

テストケース

臆面もなく盗まは、 再利用、最後のチャレンジから。

上記9に加えて…

()()((()))((())) => 100
(()(()(()))) => 101
(()())(((())))(()(())) => 1001
(((((((()))))))) => 5381
(()())((((()))))(()()(())(())) => 32767
()()()()()()()()()()()()()()() => 32768

ルール

  • 入力内のペアの文字は、かっこ、角かっこ、中かっこ、または山かっこから選択します。質問があれば、他の形式(XMLタグなど)を許可する場合があります。
  • 2から2 15または32768 までの任意の数の因子ツリーを処理できるはずです。
  • これはであるため、バイト単位の最短回答が優先されます。

回答:



8

プロローグ(SWI) 134の 128 127 124バイト

この答えは、私と0 'のコラボレーションの一部です。私たちは一緒にこれに取り組みましたが、私がそれを投稿している唯一の理由は、私がRock、Paper、Scissorsに勝ったからです。

\Q-->{Q=1};"(",\N,")",\B,{findnsols(N,I,(between(2,inf,I),\+ (between(3,I,U),0=:=I mod(U-1))),L)->append(_,[Y],L),Q is Y*B}.

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

説明

この答えは、プロローグでのゴルフを楽しいものにする完璧な例です。


この答えは、明確な節の文法にPrologsの強力なシステムを使用しています。ここに、少しだけ文法があります。

head(1)-->[].
head(Q)-->"(",head(N),")",head(B),{prime(N,Y),Q is Y*B}.
isprime(I):- \+ (between(3,I,U),0 =:= I mod(U-1)).
prime(N,Y):-
  findnsols(N,I,(
    between(2,inf,I),
    isprime(I)
  ),L),
  append(_,[Y],L),!.

最初の構築規則は次のとおりです。

head(1)-->[].

これは、空の文字列が1に対応することをPrologに伝えます。

構築の2番目のルールは、もう少し複雑です。

head(Q)-->"(",head(N),")",head(B),{prime(N,Y),Q is Y*B}.

これは、空でない文字列には、これらの同じ規則を持つ句の右側、これらの同じ規則を持つ句の右側に括弧が含まれることを示しています。

また、この句の値(Q)が規則に従っていることもわかります。

{prime(N,Y),Q is Y*B}

これを分解すると、Q2つの数字Yとの積になりBます。 B左側の句の値だけで、YあるN番目プライムNカッコ内の句の値です。

このルールは、因子ツリーの両方の形成ルールをカバーします

  • 連結乗算
  • エンクロージャーはn番目のプライムを取ります

次に、述語定義について説明します。改変されていないバージョンには2つの述語があります(私の実際のコードでは、述語を前方に連鎖させています)。ここでの2つの関連する述語はisprime/1、素数に一致する、およびprime/2、与えられたN、およびYに一致する場合に一致するiff YNth番目の素数である場合です。最初に

isprime(I):- \+ (between(3,I,U),0 =:= I mod(U-1)).

これは、素数性の非常に標準的な定義で機能します。2をI含む2を含むが、Iその除算は含まないと主張しIます。

次の述語も非常に簡単です

prime(N,Y):-
  findnsols(N,I,(
    between(2,inf,I),
    isprime(I)
  ),L),
  append(_,[Y],L),!.

素数でfindnsolsある最初のN数を見つけるために使用し、最後の数を返します。ここでのコツは、SWIが処理する方法のために常に最小の素数findnsolsを見つけることが保証されない一方で、常により小さな素数をより早く見つけることです。ただし、これは、より多くの素数を見つけられないようにカットする必要があることを意味します。 Nbetween


ゴルフ

コードで理由を2回転送できます。isprimeは定義が内に移動できる場合にのみ使用されるためですprime。次primeは、DCGの内部に直接移動することですが、カットインを使用して素数が多くなりすぎprimeないようにするためfindnsols、少し問題があります。カットは、必要なビットだけではなく、DCG全体をカットします。ドキュメントを少し掘り下げた後、once/1DCG全体ではなく、この部分のみをカットするために使用できることがわかりました。しかし、文書をさらに掘り下げてみると、->オペレーターを使用して同様のタスクを実行できることも明らかになりました。->オペレータはほぼ同等である,!,我々は、他の側に私たちのカットを移動してappend/3し、それを置き換えます->

SWI-Prologでは、述語(および規則)に演算子を名前として付けることができます。これにより、通常必要な括弧を削除できます。これにより、ルールを呼び出すことで6バイトを節約できます\



1

JavaScript(ES6)、98バイト

notjaganのPython answerに触発されました。入力式を巨大で見苦しい実行可能文字列に変換します。

s=>eval(s.split`)(`.join`)*(`.split`(`.join`(g=(n,k)=>(C=d=>n%--d?C(d):k-=d<2)(++n)?g(n,k):n)(1,`)

関数Cg関数を1つにマージすると、いくつかのバイトを節約できますが、さらに再帰が必要になります。

テストケース

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