Voidのデコード


25

空のリストは、リスト以外のオブジェクトを含むレベルのリストです。または、再帰的な定義を好む場合

  • 空のリストは無効です

  • 他の無効リストのみを含むリストは無効です

すべての無効リストには有限の深さがあります。

voidリストの例を次に示します(Python構文を使用):

[]
[[]]
[[],[]]
[[[]]]
[[[]],[]]
[[],[[]]]

voidリストではないものの例を次に示します。

["a"]
[[...]]
[1]
2
[[],([],[])]

仕事

2つの別個の関数(または必要に応じてプログラム)を作成します。1つは引数として正の整数(必要に応じてゼロを含めることもできます)を取り、voidリストを返す必要があり、もう1つはvoidリストを取り、整数を返す必要があります。これらの2つの関数は、常に互いに逆でなければなりません。の出力をfに渡す場合、の結果としてのg元の入力を取得する必要がfありgます。これは、マッピングが1:1でなければならないことを意味します。つまり、すべての整数に対して、その整数を与えるvoidリストが1つだけ存在し、すべてのvoidリストに対して、そのvoidリストをg与える整数が1つだけ存在fします。

あなたは本質的に全単射を作成しています

言語のネイティブリストタイプの代わりに、空のリストの文字列表現(カンマとスペースの有無にかかわらず)を使用することもできます。

得点

スコアは、2つの関数を合わせた長さになります。これはので、この合計を最小限に抑えることを目指してください。



1
この質問は2つの機能を要求しますが、重複は前半だけを要求します。
イアンミラー

3
ラット。私はまだ書いたベストアンサーを投稿しそうでしたが、それは他のチャレンジの資格がありません。
カレブKleveter

2
@IanMiller他の課題にはエンコーディングのガイドラインがありますが、これはこれとは異なります。
カレブKleveter

1
おそらく、この質問が単なるデコーダーである方が理にかなっているでしょうか?エンコーダーについてはすでに質問があるからです。

回答:


7

Pyth、27 + 29 = 56バイト

f

L?bol`NS{sm[d+d]Y]d)ytb]Y@y

テストスイート

g

L?bol`NS{sm[d+d]Y]d)ytb]Yxyl`

テストスイート

システムは非常に単純です:特定の数以下のすべての可能なリストを生成します[。次に、まだ生成していないリストがほぼ終了するように並べ替えます。これはすべてy、両方のプログラムで同一の関数によって行われます。と書かれています

L?bol`NS{sm[d+d]Y]d)ytb]Y

次に、のこのリストにインデックスを付けf、を検索しgます。

生成するリストの数は、無限に並べ替えられたリストの目的の位置またはその前に表示される可能性のあるすべてのリストを生成するのに十分な数に選択されます。

プログラムは、オプションとして0を許可/返します。


5

Python 2、96バイト

オンラインでお試しください!全単射をテストします。

f=lambda l:len(l)and f(l[0])*2+1<<f(l[1:])

voidリストを負でない整数にします。42バイト。

g=lambda n:n*[g]and[g(n/(n&-n)/2)]+g(len(bin(n&-n))-3)

リストを無効にするために、負でない整数を取ります。54バイト。より再帰的な試みは同じ長さを与えました。

g=lambda n,i=0:n*[g]and[g(n/2,i+1),[g(n/2)]+g(i)][n%2]

1

Java 7、725バイト

f(int)325バイト):

String f(int i){String s="";for(int j=0,e=0;e<i;e+=v(s))s=Integer.toBinaryString(j++);return"["+s.replace("1","[").replace("0","]")+"]";}int v(String s){for(;!s.isEmpty();s=s.replaceFirst("1","").replaceFirst("0",""))if(s.replace("1","").length()!=s.replace("0","").length()|s.charAt(0)<49|s.endsWith("1"))return 0;return 1;}

g(String)75 + 325バイト):

int g(String s){int r=0;for(String i="10";!i.equals(s);i=f(++r));return r;}

method gはmethod fを使用して、入力されたものに等しいものが見つかるまで、可能性のあるvoidリストをループすることで結果を計算しますf

説明:

一般に、メソッドfは整数のすべてのバイナリ文字列表現をループし、有効なものが見つかるたびにカウンタを増やします。有効なバイナリ文字列この挑戦のために、以下の規則に従わ:彼らはで始まり1、で終わり0。それらは同じ数の1と0を持っています。あなたが最初に削除するたびに10と検証が再び残っているものは、これらの2つのルールが適用されます。カウンタが入力と等しくなった後、すべて1[とで置き換えることにより、そのバイナリ文字列を文字列voidリストに変換します0をでし]ます。

メソッドgについては、"[]"(void-listを表す0)で開始しf、整数を増やしながらinput-Stringに一致するまでmethod を使用し続けます。

String f(int i){         // Method `f` with integer parameter and String return-type
  String s="";           //  Start with an empty String
  for(int j=0,e=0;e<i;   //  Loop as long as `e` does not equal the input
      e+=v(s))           //    And append increase integer `e` if String `s` is valid
    s=Integer.toBinaryString(j++);
                         //   Change `s` to the next byte-String of integer `j`
                         //  End of loop (implicit / single-line body)
  return"["+             //  Return the result String encapsulated in "[" and "]"
    s.replace("1","[").replace("0","]")+"]";
                         //  after we've replaced all 1s with "[" and all 0s with "]"
}                        // End of method `f`

int v(String s){         // Separate method with String parameter and integer return-type
  for(;!s.isEmpty();     //  Loop as long as String `s` isn't empty
      s=s.replaceFirst("1","").replaceFirst("0",""))
                         //    After each iteration: Remove the first "1" and "0"
    if(s.replace("1","").length()!=s.replace("0","").length()
                         //   If there isn't an equal amount of 1s and 0s
       |s.charAt(0)<49   //   or the String doesn't start with a 1
       |s.endsWith("1")) //   or the String doesn't end with a 0
      return 0;          //    Return 0 (String is not valid)
                         //  End of loop (implicit / single-line body)
  return 1;              //  Return 1 (String is valid)
}                        // End of separate method

int g(String s){         // Method `g` with String parameter and integer return-type
  int r=0;               // Result integer
  for(String i="[]";!i.equals(s);
                         //  Loop as long as `i` does not equal the input String
      i=f(++r));         //   After each iteration: Set `i` to the next String in line
  return r;              //  Return the result integer
}                        // End of method `g`

入出力の例:

ここで試してみてください。(注:最後のいくつかのテストケースではかなり遅くなります。すべてのテストケースで約10〜15秒かかります。)

0   <-> []
1   <-> [[]]
2   <-> [[][]]
3   <-> [[[]]]
4   <-> [[][][]]
5   <-> [[][[]]]
6   <-> [[[]][]]
7   <-> [[[][]]]
8   <-> [[[[]]]]
9   <-> [[][][][]]
10  <-> [[][][[]]]
11  <-> [[][[]][]]
12  <-> [[][[][]]]
13  <-> [[][[[]]]]
14  <-> [[[]][][]]
50  <-> [[[][[[]]]]]
383 <-> [[[][]][[[][]]]]

1
私はそれ[][]がリストだとは思いません。おそらく、Javaの動作を誤解しているのかもしれません。[...]それらをすべて追加し、マップを0に[]することでトリックを実行できます。
小麦ウィザード

@WheatWizardああ、いいコール。これを修正しようとします。とにかく十分なバイトがまだありませんでした。; P
ケビンクルーッセン

@WheatWizard OK、今すぐ修正する必要があります。タフだが楽しいチャレンジbtw。あなたが何を意味するのか理解するまでにしばらく時間がかかり、この答えを書くのにさらに時間がかかりましたが、楽しかったです。:)
ケビンクルーッセン



0

Python 3 -sign / abs、73バイト

f=lambda n:[[[]]*(n<0),[[]]*abs(n)]
g=lambda l:[-1,1][not l[0]]*len(l[1])

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

単純な実装で、負の数をサポートします。

整数iがエンコードされます[sign(i), abs(i)]。ここでsign(i)=[] if i > 0 else [[]]およびabs(i)=[[]] * iは、長さがabs(i)の空のリストのリストです。

Python 3バイナリ、126バイト

これは、より精巧なバージョン(そしてもっと長く...)であり、絶対値はバイナリリスト表現でエンコードされます。

f=lambda n:[[[]]*(n<0),[[[]]*int(i)for i in f"{n:+b}"[1:]]]
g=lambda l:[-1,1][not l[0]]*int(''.join(map(str,map(len,l[1]))),2)

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


1
より複雑なvoidリストでは機能しません:オンラインで試してください!
Jitse

ああ、どういうわけか、すべての無効なリストにマッピングがあるはずだということを懐かしく思っていました...そのとおりです。
movatica

0

スタックス、合計33バイト

これらのプログラムは互いに逆です。それらは、すべてのvoidリストとすべての非負整数との間で変換するため、0が含まれます。これは、おそらく、私が知らないある種の代数の有名な関数のようです。頭を包むために、最初にプログラムをpythonの関数として実装しました。

def convert_to_void(n):
    lst = []
    while n > 0:
        n -= 1
        choices = len(lst) + 1
        choice = n % choices
        cutpoint = len(lst) - choice
        n //= choices
        newgroup = lst[cutpoint:]
        del lst[cutpoint:]
        lst.append(newgroup)
    return lst

def convert_from_void(lst):
    n = 0
    while lst != []:
        newgroup = lst.pop()
        n *= len(lst) + len(newgroup) + 1
        n += len(newgroup) + 1
        lst.extend(newgroup)
    return n

staxプログラムの動作は同じです。

非負の整数→無効リスト、15 バイト

ƒâ₧~└3BI─¿-rÅ;ì

実行してデバッグする

無効リスト→非負整数、18 バイト

Çäê[!σ`c↑Ö§░NR╥ç=Æ

実行してデバッグする

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