Karınca permütasyonu oluşturun


13

Giriş

Daha önceki bir zorlukta karınca permütasyonu sınıfını tanımladım . Bir hatırlatma, bir permütasyon olarak p gelen sayılar 0 için r-1 , her bir giriş için, eğer sabırsız, bir p [i] ilk dışında, daha önceki bazı giriş yoktur , p [ik] öyle ki , p [i] == s [ ik] ± 1 . Eğlenceli bir gerçeği olarak, ben de için belirtti r ≥ 1 , tam orada 2 r-1 uzunluğunun Antsy permütasyon r . Bu, r uzunluğunun antsy permütasyonları ile r-1 uzunluğunun ikili vektörleri arasında bire bir yazışma olduğu anlamına gelir.. Bu meydan okumada, göreviniz böyle bir yazışmayı uygulamaktır.

Görev

Göreviniz, uzunluk 1 ≤ n ≤ 99 olan bir ikili vektörü alan ve n + 1 uzunluğunda bir karıncalanma permütasyonu çıkaran bir program veya işlev yazmaktır . Permütasyon 0 tabanlı 1 tabanlı olabilir (ancak bu tutarlı olmalıdır) ve giriş ve çıkış herhangi bir makul formatta olabilir. Ayrıca, farklı girdiler her zaman farklı çıktılar vermelidir; bunun dışında, hangi antsy permütasyonunu istersen geri dönebilirsin.

En düşük bayt sayısı kazanır.

Misal

4 uzunluğundaki (0 tabanlı) antsy permütasyonları

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

ve programınız uzunluk 3'ün sekiz bitlik vektörlerinin her biri için bunlardan birini döndürmelidir:

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

Program bunun yerine her ikili vektörün tamsayı temsilini alabilir mi?
mbomb007

1
@ mbomb007 Hayır, çünkü önde gelen sıfırlar önemlidir. 0 1ve 0 0 1farklı uzunluklarda çıktılar vermelidir.
Zgarb

Yanıtlar:


3

Jöle , 12 11 10 bayt

ḟẋLṭ+
0;ç/

Çevrimiçi deneyin! veya uzunluk 4'ün tüm permütasyonlarını oluşturabilir .

Nasıl çalışır

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

Python 2, 62 60 bayt

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

2 bayt golf için @xnor sayesinde!

Ideone üzerinde test edin .


İçinde virgül mü gerekiyor x=0,?
ETHproductions

0,bir demettir. Virgül olmazsa, x ile eşleme başarısız olur.
Dennis

Sanırım nyapmak için çevirin [n*len(x)]ve haritayı bir liste comp değiştirin.
xnor

@xnor Gerçekten. Teşekkürler!
Dennis

3

Python, 54 bayt

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

Aşağıdaki prosedürü kullanır:

  1. Listeye 1 ekleyin.
  2. Her 0 giriş için konumunu 0 dizinli listeye yazın.
  3. Her giriş için, 1 sayısını kendi başına yazarak sağına yazın.
  4. Adım 2 ve 3'ün sonuçlarını giriş olarak ekleyin.

Örneğin, l=[1,0,1,0]verirf(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

Bir 0 eklemek aynı sonucu verir. Bu enumeratehantal, tekrarlı olarak daha iyi yapıp yapamayacağını göreceğim.


Akıllı teknik! Her dilde farklı tekniklerin nasıl en iyi olduğu büyüleyici. Bu JS taşımak için çalıştı, ancak sumsözdizimi eksikliği ve dilimleme nedeniyle 57'de sona erdi .
ETHproductions

3

JavaScript (ES6), 48 47 45 bayt

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

Bu, ilk öğeyi doğrudan hesaplayarak ve sonra her bir basamağın yeni bir yüksek veya yeni bir düşük olup olmadığını belirlemek için ikili vektörü kullanarak başlamış olmam dışında, @ETHproductions'ın yöntemine benzer olduğu ortaya çıktı. Düzenleme: @ETHproductions sayesinde 1 bayt kaydedildi. Sıfır ile başlayıp daha sonra ayarlayarak 2 bayt kaydedildi. Önceki yöntemim @ Dennis'in yöntemine benziyordu, ancak 54 bayt aldı:

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

2

Perl, 33 bayt

İçin +1 içerir -p

STDIN'de boşluk olmadan vektörü dize olarak ver:

antsy.pl <<< 110

antsy.pl:

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

2

JavaScript (ES6), 52 bayt

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

Test edin:

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">

açıklama

Bu, bir karıncalanma permütasyonu tersine çevrildiğinde, her bir öğenin önceki düşük girişlerin maksimumundan 1 daha fazla veya önceki yüksek girişlerin minimumundan 1 daha az olması avantajından yararlanır. Daha yüksek bir öğeyi 0ve daha düşük bir öğeyi a olarak 1göstererek, n uzunluğunun antsy permütasyonları ile n - 1 uzunluğunun ikili vektörleri arasında tam bire bir uyum oluşturabiliriz .

Dennis tekniği ile yapabileceğim en iyi şey 57 51 bayt:

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'ın çözümü 56'dır (@Neil sayesinde 1 bayt kaydedildi):

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

i-i*xolabilir i*!x.
Neil

@Neil Ah evet, teşekkürler.
ETHproductions


0

Toplu, 127 bayt

@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

Girişi komut satırı parametreleri olarak alır, çıkış satırı ayrılır. (STDIN'e ekstra ücret ödemeden boşlukla ayrılmış olarak girmek mümkündür.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.