Modular SNUSPで数値の最も短い表現を見つける


10

バックグラウンド

多くの難解なプログラミング言語にはリテラルに数値が組み込まれていないため、実行時に計算する必要があります。これらの多くの場合、数値表現は非常に興味深いものになります。Underloadの数値の表現についてはすでに課題がありました。この課題は、モジュラーSNUSPで数値を表現することです。(この課題を完了するためにSNUSPを学ぶ必要はないことに注意してください。必要な情報はすべて仕様に含まれていますが、背景が興味深いかもしれません。)

タスク

この課題の目的のために、モジュラーSNUSP数は、文字のうちに形成された文字列である@+=最後の文字があることを除いて、#最後から二番目の文字がでなければならず、ということ+=(それがすることはできません@)。例えば、有効な数字が含まれ@+#==#@@+@=#。無効な数字の例としては+=@@#、と+?+#

Modular SNUSP番号の値は、次のように再帰的に計算されます。

  • # 値は0です(これが基本ケースです)。
  • 数値の形式=xが任意の文字列xである場合、その値はの値と同じですx
  • 数値の形式がの場合、+x任意の文字列についてx、その値はの値にx1を加えたものに等しくなります。
  • 数値の形式が@cx1つの文字cと文字列のx場合、その値はの値にの値をx足したものに等しくなりますcx

この課題では、非負の整数を入力として受け取り、入力と等しい値を持つ最短のModular SNUSP番号である文字列を出力するプログラムを作成する必要があります。

明確化

  • 同じ値を持つ複数の文字列が存在することは完全に可能です。特に、一部の整数については、その値を持つ最短のModular SNUSP番号が同点になります。そのような場合、同点で関係する数値を出力できます。
  • 数を見つけるために使用するアルゴリズムに制限はありません。たとえば、文字列を総当たりで評価することは合法的な戦術ですが、検索スペースを減らすために賢いことをしています。
  • PPCGでの通常のように、提出物は完全なプログラムまたは関数のいずれかです(言語でより簡潔な方を選択します)。
  • これは入力形式と出力形式の処理に関する問題ではないので、非負の整数を入力して文字列を出力するための適切な手段を使用できます。metaに関する完全なガイドがありますが、最も一般的に使用される有効なメソッドには、関数の引数/戻り値、コマンドライン引数、および標準入力/標準出力が含まれます。

テストケース

以下は、最初の数の最も短い表現です。

  • 0#
  • 1+#
  • 2++#
  • 3+++#または@++#
  • 4++++#または+@++#または@=++#
  • 5@+++#または@@++#
  • 6+@+++#または+@@++#または@=+++#または@=@++#または@@=++#
  • 7@++++#または@+@++#
  • 8@@+++#または@@@++#
  • 9+@@+++#または+@@@++#または@+++++#または@++@++#または@+@=++#または@@=+++#または@@=@++#
  • 10@=@+++#または@=@@++#または@@@=++#(考えられるすべての回答に含まれるため、これは確認するのにかなり重要なテストケースです=
  • 11@+@+++#または@+@@++#または@@++++#または@@+@++#
  • 12+@+@+++#or +@+@@++#または+@@++++#or +@@+@++#または@=+@+++#or @=+@@++#または@=@=+++#or @=@=@++#または@=@@=++#or @@=++++#または@@=+@++#orまたは@@=@=++#
  • 13@@@+++#または@@@@++#
  • 14+@@@+++#または+@@@@++#または@=@++++#または@=@+@++#または@@+++++#または@@++@++#または@@+@=++#
  • 15@+@++++#または@+@+@++#または@@=@+++#または@@=@@++#または@@@=+++#または@@@=@++#

大きなテストケースとして、入力から出力40があるべきである@@@=@@+++#@@@=@@@++#@@@@=@+++#、または@@@@=@@++#

勝利条件

の挑戦、勝者はバイト単位で測定、最短のエントリです。


1
=として最適に発生し@=ますか?
orlp

3
ちなみに、興味深い答えはほとんどないので、これらの種類のチャレンジは通常metagolfとして投稿するのが最善です(文字列を評価してすべての可能な文字列をループするだけです)。
orlp

3
@orlp:同意しない。最適な答えを見つけるのは比較的簡単であり、メタゴルフはスコアリングに他の制限を課さないため、この課題はメタゴルフとしては簡単すぎるでしょう。私はここでの答えのほとんどがブルートフォースであると期待していますが、仕様はブルートフォースがa)最短ではないかもしれない、そしてb)それ自体がゴルフにとって興味深いと思われるほど複雑です。勝利条件の変更が必要な場合、おそらく他の唯一の興味深いものは最速コードであり、それは別の課題としてより理にかなっています。

私たちも同様に脳非難の番号ゴルフチャレンジを持っていた
ASCIIのみ

回答:


3

OracleのSQL 11.2、341の 262バイト

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c,i)AS(SELECT'#',0,0,e,1 FROM e UNION ALL SELECT c||s,DECODE(c,'+',1,'@',p,0)+v,v,e,i+1 FROM n,e WHERE i<11)CYCLE s SET y TO 1 DEFAULT 0 SELECT s FROM n WHERE:1=v AND rownum=1;

古いバージョン

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c) AS(SELECT'#',0,0,e FROM e UNION ALL SELECT s||c,CASE c WHEN'+'THEN 1 WHEN'='THEN 0 WHEN'@'THEN p ELSE 0 END+v,v,e FROM n,e WHERE LENGTH(s)<10)CYCLE s SET y TO 1 DEFAULT 0 SELECT MIN(REVERSE(s))KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s))FROM n WHERE v=:1;

:1 Modular SNUSPで表す数値

ゴルフなし:

WITH e AS (SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),  
n(s,v,p,c,i) AS                   
(
  SELECT '#',0,0,e,1 FROM e
  UNION ALL
  SELECT s||c
       , DECODE(c,'+',1,'@',p,0)+v 
       , v
       , e
       , i+1
  FROM n,e
  WHERE i<11
) CYCLE s SET y TO 1 DEFAULT 0
SELECT s FROM n WHERE:1=v AND rownum=1;

最初に、数字を表すために使用される各シンボルごとに1つ、文字列の最後でのみ使用される#を引いた3行のビューを作成します。

SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4;    

次に、再帰的ビューnは、3つのシンボルで可能なすべての文字列を生成し、それらを#に連結して評価します。

パラメータは次のとおりです。

s:評価される数値のモジュラーSNUSP表現
v:前の反復によって計算されたsの10進値
p:v i-2反復によって計算された
c:sに連結する次のシンボル
i:s の長さのみゴルフ目的で2つのLENGTH()を取り除く必要がある

DECODE(c,'+',1,'@',p,0)+v 

最後のシンボルが+の場合、1を
追加します。@の場合、i-2反復の値を追加します
。それ以外の場合、シンボルは#または=です。vは再帰的ビューのinit部分で0で初期化されるため、どちらの場合でも、新しいvは前のvと等しくなります。

WHERE i<11

3つのシンボルで可能なすべての文字列が計算されます。この部分は、大きなクランチまでリクエストが実行されないことを保証します。

CYCLE s SET y TO 1 DEFAULT 0

文字列の構成には規則がないため、重複が発生する可能性があります。Oracleは再帰的なビューにあるため、それらの重複をサイクルとして解釈し、ケースが明示的に処理されない場合はエラーをスローします。

SELECT s FROM n WHERE:1=v AND rownum=1;

パラメータ:1として入力された10進数に評価される最初のモジュラーSNUSP表現を返します。

私のテストでは、その最初の行は常に最も短い表現の1つです。

データベースが同じように機能しない場合は、最後の句を次のように置き換えます。

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY i)FROM n WHERE:1=v

2

JavaScript(ES6)、100バイト

n=>eval("for(a=[['#',0,0]];[[s,t,p],...a]=a,t-n;)a.push(['='+s,t,t],['+'+s,t+1,t],['@'+s,t+p,t]);s")

単純なブルートフォース幅優先検索アルゴリズム。


40にとっては42と評価され、「@@@@@@ = ++#」を返す
SEは悪であるため、aditsuはやめ

でも、12のためにそれは13と評価され、「@@@ +++#」を与える
SEは悪であるため、aditsuはやめ

うーん、変更t<nしても効果t-nがあると思います...
Neil

2

Pyth、41バイト

L?b+ytb@[yttb001)Chb0+hfqQyTs^L"+@="UhQ\#

テストスイート

使い方:

2つの部分があります。TrailingなしのSNUSP式の値を計算する再帰関数#と、ブルートフォースルーチン。

評価:

L?b+ytb@[yttb001)Chb0
L                        Define the function y(b) as follows
 ?b                      If b is nonempty
   +ytb                  The sum of y(tail(b)) and   # tail(b) = b[1:]
   @[       )            The element in the list at location
   Chb                   Character values of the first character.
                         Modular indexing means that 
                         + -> 3
                         @ -> 0
                         = -> 1
                         Index 2 is filler.
    [yttb001)            @ adds y(tail(tail(b)). Tail suppresses the error when
                         called on an empty list, so this treats @# as zero, but
                         this can't lead to problems because removing the @ will
                         always make the expression shorter.
                         + adds 1, = adds 0.
 0                       If b is the empty string, return 0

強引な:

+hfqQyTs^L"+@="UhQ\#
               UhQ      0 ... Q     # Q is the input
        ^L"+@="         Map that list to all strings formed from the characters
                        "+@=", with that many characters.
       s                Concatenate
  fqQyT                 Filter for strings which evaluate to the input
 h                      Take the first success, which is the shortest due to
                        the order the strings were generated.
+                 \#    Add a '#' and output

1

CJam、58

ri:M;'#0_]]{_{M&}#_)!}{;{~[2,+1$f+"@=+"\]z\f+\af.+~}%}w=0=

ニールの答えから少しインスピレーションを得たブルートフォース。オンラインでお試しください

効率的なバージョン、107

ri0"#"a{_{:B\:A={'=A0j+}{A(B={'+B0j+}{AB>{BAB-j_N={'@\+}|}N?}?}?}{;_(0j'+\+a\,1>_W%.{j}Na-'@\f++{,}$0=}?}2j

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

これは動的プログラミングを使用します。


1

Haskell89 86バイト

編集:

  • -3バイト:圧縮はインデックス付けよりも短かった。

ニールの答えから多くのインスピレーションを得た別のブルートフォースソリューション。(ゴルフが導入される前は、それはisaacgのPythのように機能していましたがl。)

f n=[s|(a,_,s)<-l,a==n]!!0
l=(0,0,"#"):[(a+c,a,d:s)|(a,b,s)<-l,(c,d)<-zip[0,1,b]"=+@"]

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

  • f 整数を受け取り、文字列を返すメイン関数です。
  • lは、最初(a,b,s)に最も短い表現であるタプルの無限リストであり、sそれらの値ab、最初の文字が取り除かれた表現の値と一緒です。(他の人も注意/気づいたように、後者を0として扱うことは無害です#。)
  • 最初の要素l以外の要素は、リスト内包表記を使用して再帰的に生成されます。リストに新しい表現を生成するdために先頭に追加される文字でありs、「c」はに対応する増分aです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.