アリ順列の生成


13

前書き

以前の挑戦でアリ順列のクラスを定義しました。覚え書きとして、0からr-1までの数字の順列pは、最初のエントリを除くすべてのエントリp [i ]に対して、p [i] == p [ ik]±1。楽しい事実として、私はまたのためにあると述べR≥1 、まさにそこにある2 R-1の長さのイライラ順列rが。これは、長さrのアンチ順列と長さr-1のバイナリベクトルとの間に1対1の対応があることを意味します。。この課題では、あなたの仕事はそのような通信を実装することです。

タスク

あなたの仕事は、長さのバイナリーベクターにかかるプログラムや関数の書き込みにある1≤N≤99を、長さのイライラ順列出力するN + 1。順列は0ベースまたは1ベースのいずれか(ただし、これは一貫している必要があります)であり、入力と出力は任意の妥当な形式にすることができます。さらに、異なる入力は常に異なる出力を与える必要があります。それ以外の場合は、必要な任意の順列を自由に返すことができます。

最も低いバイトカウントが優先されます。

長さ4の(0ベース)anty順列は次のとおりです。

0 1 2 3
1 0 2 3
1 2 0 3
1 2 3 0
2 1 0 3
2 1 3 0
2 3 1 0
3 2 1 0

そして、あなたのプログラムは長さ3の8ビットのベクトルのそれぞれに対してそれらの1つを返さなければなりません:

0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

プログラムは代わりに各バイナリベクトルの整数表現を取ることができますか?
mbomb007

1
@ mbomb007いいえ、先行ゼロが重要なためです。0 1また0 0 1、異なる長さの出力を提供する必要があります。
ズガルブ

回答:


3

ゼリー12 11 10 バイト

ḟẋLṭ+
0;ç/

オンラインでお試しください!または、長さ4のすべての順列を生成します

使い方

0;ç/   Main link. Argument: B (bit array)

0;     Prepend a 0 to B.
  ç/   Reduce [0] + B by the helper link.


ḟẋLṭ+  Helper link. Left argument: A (array or 0). Right argument: b (bit)

 ẋ     Repeat A b times, yielding A or [].
ḟ      Filter false; remove the elements of A or [] from A.
  L    Get the length of the resulting array.
       This yield len(A) if b = 0 and 0 if b = 1.
    +  Add b to all elements of A.
   ṭ   Tack; append the result to the left to the result to the right.

3

パイソン2、62の 60バイト

x=0,
for n in input():x=[t-n+1for t in x]+[n*len(x)]
print x

@xnorに2バイトのゴルフをありがとう!

Ideoneでテストします。


にカンマが必要x=0,ですか?
ETHproductions

0,タプルです。コンマがないと、x上のマッピングは失敗します。
デニス

フリップn[n*len(x)]てマップをリストコンプに変更できると思います。
-xnor

@xnor確かに。ありがとう!
デニス

3

Python、54バイト

lambda l:[i-i*x+sum(l[i:])for i,x in enumerate([1]+l)]

次の手順を使用します。

  1. リストの先頭に1を追加します。
  2. 0エントリごとに、0インデックス付きリストにその位置を書き込みます。
  3. エントリごとに、それ自体をカウントせずに1の数をその右側に書き込みます。
  4. 手順2と3の結果をエントリごとに追加します。

たとえば、l=[1,0,1,0]与えるf(l) == [2,1,3,0,4]

List with prepended 1         1 1 0 1 0

0-indexed position for 0's        2   4
Number of 1's to right        2 1 1 0 0
Sum of above two              2 1 3 0 4

0を先頭に追加しても同じ結果になります。enumerateそれがより良い再帰的に行うことができるかどうか、私は参照してくださいよ、不格好です。


巧妙なテクニック!言語ごとに異なるテクニックが最適であることが魅力的です。私はこれをJSに移植しようとしましたが、sum構文の不足とスライスのために57になってしまいました。
ETHproductions

3

JavaScript(ES6)、48 47 45バイト

a=>[h=l=0,...a.map(c=>c?--l:++h)].map(e=>e-l)

これは@ETHproductionsのメソッドと似ていますが、最初の要素を直接計算し、バイナリベクトルを使用して各桁が新しい高値か新しい低値かを判断することから始めました。編集:@ETHproductionsのおかげで1バイト保存されました。ゼロから始めて、後で調整することで2バイトを節約しました。私の以前の方法は@Dennisの方法に似ていることが判明しましたが、54バイトかかりました。

a=>a.reduce((r,b)=>[...r.map(e=>b+e),r.length*!b],[0])

2

Perl、33バイト

+1を含む -p

STDINにスペースなしの文字列としてベクトルを指定します。

antsy.pl <<< 110

antsy.pl

#!/usr/bin/perl -p
s%^|.%y/0//+($&?++$a:$b--).$"%eg

2

JavaScript(ES6)、52バイト

v=>[...v,l=0].map(x=>x?l++:h--,h=v.length).reverse()

テストしてみましょう:

f=v=>[...v,l=0].map(x=>x?l++:h--,h=v.length).reverse()
g=v=>console.log(f((v.match(/[01]/g)||[]).map(x=>+x)))
<input oninput="g(this.value)" value="010">

説明

これは、anty順列が逆になったときに、各アイテムが前の低エントリの最大値より1大きいか、前の高エントリの最小値より1小さいという事実を利用します。上位のアイテムをaとして、0下位のアイテムをa として示すことにより1、長さnのアンティ順列と長さn-1のバイナリベクトルとの正確な1対1の対応を作成できます。

Dennisの手法でできる最善の方法は57 51バイトです。

v=>v.reduce((x,n)=>[...x.map(i=>i+n),!n*++j],[j=0])
v=>v.map(n=>x=[...x.map(i=>i+n),!n*++j],x=[j=0])&&x

xnorのソリューションは56です(@Neilのおかげで1バイト保存されます):

l=>[1,...l].map((x,i)=>i*!x+eval(l.slice(i).join`+`||0))

i-i*x可能性がありますi*!x
ニール

@Neil Ahはい、ありがとう。
ETHproductions


0

バッチ、127バイト

@set s=%*
@set/an=h=l=%s: =+%
@for %%b in (%*)do @call:%%b
:0
@echo %n%
@set/an=h+=1
@exit/b
:1
@echo %n%
@set/an=l-=1

入力をコマンドラインパラメーターとして受け取り、出力は行で区切られます。(追加費用なしで、STDINでスペースで区切って入力することができます。)

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