Bizim tarzımız bu


18

Piet, çeşitli nedenlerden dolayı ilginç bir programlama dilidir. Bugün bir sebep üzerinde duracağız: roll komutu. Roll komutu aslen PostScript'teydi ve yığını işlemenin güçlü bir yoludur.

Roll komutu yığının en iyi iki öğesini açar ve parametre olarak kullanır. İlk attığımız değeri turns, ikincisini arayacağız depth. N derinliğine dönüş yığının en üst elemanını alır, yığındaki n'inci eleman yapar ve üstündeki elemanların her birini bir yukarı taşır. Eğer turns negatif ise bu ters yönde yapılır. Yani, n'inci eleman yukarı taşınır ve diğer elemanlar aşağı taşınır. Bu tekrarlanır abs(turns).

Meydan okuma

Yığını alan ve rulo yürüttükten sonra bu yığını döndüren bir program veya işlev yazın.

kurallar

  • Giriş ve çıkış, bir liste, dizi, sınırlayıcılı bir dize, bir kerede bir öğeye geçirilmiş veya başka herhangi bir makul biçimde olabilir. Çıktı, girdi ile aynı formatta olmalıdır.
  • depth asla negatif olmayacak ve asla yığının uzunluğundan daha büyük olmayacaktır.
  • Giriş yığını her zaman en az iki öğe içerir.
  • Bu yani her dilde en kısa cevap kazanır. Bu nedenle, bir yanıtı kabul etmeyeceğim.
  • Standart boşluklar yasaktır.

Test Durumları

in:  out:
2    
4    
1    3
2    4
3    1
4    2
5    5
6    6

in:  out:
-2   
3
1    2
2    3
3    1

in:  out:
-42
0
1    1
2    2
3    3
4    4
5    5

2
her dilde en kısa cevap kazanır , [code-golf] böyle çalışmaz. En kısa cevap kazanır. Dönemi.
mbomb007

4
@ mbomb007 ahem buna ne dersiniz
Christopher

7
Bu hiçbir şekilde rick haddeleme içermediğini çok hayal kırıklığına uğradım
Christopher

2
@ mbomb007 Etiket açıklamasında veya meta üzerinde hızlı bir aramada görmüyorum, bu yüzden böyle olduğunu düşünmüyorum.
Mike Bufardeci

2
@ mbomb007 Eğer değiştirmemi isterseniz, lütfen "yanılıyorsunuz ve haklıyım" demek dışında bir çeşit argüman sağlayın. Bunu reddettiğiniz için emsal var ve hiçbir yerde zorlukların tam olarak bir kazanan gerektirdiği veya bir cevabın kabul edilmesi gerektiği söylenemez.
Mike Bufardeci

Yanıtlar:


8

Haskell , 64 62 bayt

Düzenleme: -2 bayt: @xnor yanlış düşündüğüm bir şey gördü.

rInts listesini alır ve döndürür .

r(t:d:l)|d<1=l|(x,y)<-d%l,(z,w)<-mod t d%x=w++z++y
(%)=splitAt

Çevrimiçi deneyin!

splitAt n llistesini böler lindeksinde n, modbölümü, geri kalan hesaplar ++bitiştirir listeleri.


1
Bence (%)=splitAtinfix tanımlayarak 2 bayt kesebilirsiniz .
xnor

@xnor Oh, kendimi bir şekilde işe yaramayacağına ikna etmiştim
Ørjan Johansen

8

JavaScript (ES6), 49 47 bayt

(t,d,...a)=>a.splice(t=(t%d+d)%d,d-t).concat(a)

Düzenleme: Yığın öğelerini ayrı parametreler olarak alarak @Shaggy sayesinde 2 bayt kaydedildi. Açıklama:

  • Dönüş derinliğin bir katı olduğunda hiçbir şey olmaz. Bu nedenle ilk adım dönüş modülo derinliğini hesaplamaktır. JavaScript sadece geri kalanını nasıl hesaplayacağını bildiğinden, bunu iki adımda yapmak zorundayım.
  • Döndürme 1üst öğeyi öğeye taşır depth. Bir dönüş 2hamle üst iki elemanları, vb Ancak, aynı zamanda öne doğru sırayla ve derinlik arasındaki unsurları taşıyarak bunu başarabilirsiniz. splicebu öğeleri kaldırır ve concatkalan öğelere ekler. (Aynı uzunlukta olduğu için bir dizi kavrama kullanabilirdim.)
  • Bunun aksine slice, ikinci parametre splicekaldırılacak öğe sayısıdır.

İle (t%d+d)%daynı değil t%dmi?
Luke

@ Hayır, %geriye kalan, bu yüzden negatif olduğunda olumsuz bir cevap verir t.
Neil

(t,d,...a)=>Kurallar, girdinin bir kerede bir öğeye geçirilmesine izin verdiği için 2 bayt kaydedebilirsiniz .
Shaggy

@Shaggy Teşekkürler, bunu fark etmemiştim.
Neil

7

CJam, 31 bayt

)\):N@\,0a|={NW*1$1$>)\+@@<\+}*

Giriş ve çıkış yığındaki dizilerdir, son öğe yığının tepesini temsil eder.

Yığın izleme:

                   e# Stack:                [6 5 4 3 2 1 4 2]
)                  e# Take out first value: [6 5 4 3 2 1 4] 2
\                  e# Swap:                 2 [6 5 4 3 2 1 4]
)                  e# Take out first value: 2 [6 5 4 3 2 1] 4
:N                 e# Store in N:           2 [6 5 4 3 2 1] 4; N=4
@                  e# Rotate:               [6 5 4 3 2 1] 4 2
\                  e# Swap:                 [6 5 4 3 2 1] 2 4
,                  e# Range:                [6 5 4 3 2 1] 2 [0 1 2 3]
0                  e# Push 0:               [6 5 4 3 2 1] 2 [0 1 2 3] 0
a                  e# Wrap in array:        [6 5 4 3 2 1] 2 [0 1 2 3] [0]
|                  e# Logical or:           [6 5 4 3 2 1] 2 [0 1 2 3]
                   e# (This will replace an empty array with [0] to handle a special case of n=0)
=                  e# Get array value:      [6 5 4 3 2 1] 2
{NW*1$1$>)\+@@<\+} e# Push block:           [6 5 4 3 2 1] 2 {NW*1$1$>)\+@@<\+}
*                  e# Preform n times:      [6 5 4 3 2 1]
  N                e# Push N:               [6 5 4 3 2 1] 4
  W*               e# Negate:               [6 5 4 3 2 1] -4
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1]
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1] -4
  >                e# Slice a[-4:]          [6 5 4 3 2 1] -4 [4 3 2 1]
  )                e# Take first value:     [6 5 4 3 2 1] -4 [4 3 2] 1
  \                e# Swap:                 [6 5 4 3 2 1] -4 1 [4 3 2]
  +                e# Append:               [6 5 4 3 2 1] -4 [1 4 3 2]
  @@               e# Rotate twice:         [1 4 3 2] [6 5 4 3 2 1] -4
  <                e# Slice a[:-4]:         [1 4 3 2] [6 5]
  \                e# Swap:                 [6 5] [1 4 3 2]
  +                e# Append:               [6 5 1 4 3 2]
e# Preform the block again:                 [6 5 2 1 4 3]

6

Mathematica, 58 50 bayt

Düzenleme: 8 bayt kaydettiği için Martin Ender'e teşekkürler.

Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&

Açıklama:

Listenin başlangıcının yığının üstünü temsil ettiği bir liste bekleyen saf işlev. Listenin öğelerini saf işleve geçiriyoruz Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&. xöğesi, üçüncü argümanla başlayan öğelerin sırasına ayarlanır. sonra, öğenin ilk #2(ikinci argüman) öğelerini xsola #(ilk argüman), sonra Joinkalan öğelerinix .

3Yığın öğelerini başlangıçta bir listede olmak yerine doğrudan işleve bağımsız değişken olarak geçirirsek bayt tasarrufu yapar , ancak daha sonra giriş ve çıkış biçimleri eşleşmez.

Orijinal çözüm:

#/.{t_,d_,x___}:>{x}~Take~d~RotateLeft~t~Join~Drop[{x},d]&

Bu infix fonksiyonları zinciri hakkında gerçekten tatmin edici bir şey var. Birinci eleman ile bir liste değiştirir t, ikinci elemanın d, ve geri kalan elemanlar xbirinci döner sonucu ile delemanlarını {x}sola tsaat ve geri kalan elemanlarının birleştirilmesi {x}.


1
Güzel! ±Değiştirme kuralının tek baytlık bir önek işlevini kullanarak 3 bayt ve TakeDropaşağıdaki şekilde yararlanarak başka bir 1 bayt kaydedebilirsiniz : ±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
Greg Martin

Sadece Greg ile aynı şeyi yorumlayacaktım, ama aslında daha da kısa sürebilirsin. Ya (bu girdi alır çünkü bu biraz tehlikeli olsa da isimsiz variadic işlevi yapmak ...&[1, 1, 3, 4]ve getiri {3, 4}veya el ile bunu Applybaşlangıçta: Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&(açık konuşmak gerekirse, benim ilk öneri atlar @@#&).
Martin Ender

5

Yakut, 40 bayt

x=->s{n,d,*s=s;s[0,d]=s[0,d].rotate n;s}

Çevrimiçi deneyin!

Girişi bir liste olarak alır, bir liste döndürür. rotateHem pozitif hem de negatif rotasyonları kaldırabilen yerleşik bir varlığın olması bunu önemsiz kılar.


5

Python, 141 98 87 74 bayt

@Cole sayesinde 11 bayt kaydedildi

def f(s):*s,d,t=s;n=len(s)-d;return s*0**d or s[:n]+s[-t%d-d:]+s[n:-t%d-d]

Girişi, son öğenin yığının en üstünde olduğu liste olarak alır.

Kesilecek listenin bir bölümünü belirlemek için sıfır derinliğini filtrelemek için 0ⁿ hile ve python'un işaret ayarlama modulo operatörünü kullanır.


Neden sadece almıyorsun f(s,t,d)?
cole

@Kol Açma için teşekkürler! Ancak, ne demek istediğini anlayamıyorum f(s,t,d)(girdi bütün yığın).
Uriel

açmak için harika bir fikir, ama bana bunun için kredi gerektiğini sanmıyorum (sadece değişkenleri ayrı ayrı almanızı öneririm). Girdi spesifikasyonu derinliği almanıza izin veriyor gibi görünüyor ve yığından ayrı değişkenler olarak dönüyor: "Girdi ve çıktı bir liste, dizi, sınırlayıcılı bir dize, bir kerede bir öğeye geçirilmiş veya başka herhangi bir makul biçimde olabilir. Çıktı, girdi ile aynı biçimde olmalıdır. "
cole

İle 1 bayt kaydedebilirsiniz r=-t%d-d. Ayrıca, değiştirilmesi s*0**dile s*(d<1)bayt sayımı tutar ama belki okunabilirliği (bu hedefi öyle değil) geliştirir. 0**0==1Python'da bunun ilginç olduğunu bilmiyordum .
Ben Frankel

@BenFrankel Yapamam kaydet -t%d-d(eskiden olduğu gibi) bir değer olarak, çünkü ne zaman dolduğunu 0bu bölünme-by-sıfıra istisna tetikleyecektir.
Uriel

3

JavaScript ES6, 109 92 bayt

x=>{for(i=x.shift(),i=i>0?i:-i,j=x.shift();i-->0&&j>0;)x=x.splice(j,1).concat(x);return x}

Çevrimiçi deneyin!

Girdiyi bir tamsayılar dizisi biçiminde alır.
Ayrıca ok sayısı vardır: P

Açıklama:

Kod, listenin ilk iki öğesini ayıklamak için shift işlevini kullanır.

Daha sonra, ilk elemanın mutlak değerini alır, bu da dönüş sayısıdır.

Javascript sıfır indekslendiğinden, derinlik endeksinin 1 azaltılması gerekir.

Derinlik endeksi 0 veya 1 ise hiçbir şey değişmemelidir, ancak azalma nedeniyle 0 endeksi değişikliklere neden olacaktır. Bu nedenle derinlik endeksi <= 0 değilse döngüden çıkın.

Ek (a, b) işlevi, diziden başlangıç ​​dizini a ile b uzunluğunun alt dizisini döndürür ve orijinal diziyi bu öğeler olmadan bırakır.

Orijinal dizinin geri kalanı ile birleştirildiğinde, bu, dizinin derinlik dizinindeki tek bir dönüşüdür.

Bu işlemi n kez gerçekleştirerek, burada n tur sayısıdır, sonuçta elde edilen dizi rulo operatörünün sonucudur.



2

TI-Basic, 141 , 150 bayt (rakip olmayan)

Prompt L1
L1(1→T
L1(2→D
seq(L1(C),C,3,dim(L1→L1
If TD>0
Then
For(A,1,T
L1(1→B
For(C,2,D
L1(C→L1(C–1
End
B→L1(D
End
End
If TD<0
Then
For(A,1,-T
L1(D→B
For(C,D,2,-1
L1(C–1→L1(C
End
B→L1(1
End
End
L1

Düzenleme: derinliğin sıfır olduğu sabit durum (+9 bayt)

TI-Basic 0 uzunluklu listeleri desteklemediğinden, bu yaklaşım iki uzunluklu bir giriş için çalışmaz.

Açıklama:

Prompt L1                # 4 bytes, input list
L1(1→T                   # 7 bytes, turns
L1(2→D                   # 7 bytes, depth
seq(L1(C),C,3,dim(L1→L1   # 18 bytes, remove turns and depth from list
If TD>0                  # 6 bytes, if turns is positive and depth is nonzero (can't be negative)
Then                     # 2 bytes
For(A,1,T                # 7 bytes, do this 'turns' times
L1(1→B                    # 7 bytes, backup the first item
For(C,2,D                # 7 bytes, shuffle the rest along
L1(C→L1(C–1               # 12 bytes
End                      # 2 bytes
B→L1(D                   # 7 bytes, restore the backup to where it should be
End                      # 2 bytes
End                      # 2 bytes
If TD<0                  # 6 bytes, if T is negative and D is nonzero
Then                     # 2 bytes
For(A,1,-T               # 8 bytes, do this -'turns' times
L1(D→B                   # 7 bytes, backup the Dth item
For(C,D,2,-1             # 10 bytes, shuffle the items the other way
L1(C–1→L1(C              # 12 bytes
End                      # 2 bytes
B→L1(1                   # 7 bytes, restore backup to where it belongs
End                      # 2 bytes
End                      # 2 bytes
L1                       # 2 bytes, implicitly return

Ben de 2 elementli liste davası ile başa çıkmak için kod gerektiğini düşünüyorum; şu anda seq(.
lirtosiast

1

Toplu işlem, 163 bayt

@set s=
@set r=
@set/ad=%2,t=(%1%%d+d)%%d
:l
@shift
@set/af=t-=1,f^^=d-=1
@if %f% lss 0 (set r=%r% %2)else set s=%s% %2
@if not "%3"=="" goto l
@echo%r%%s%

Girdiyi komut satırı parametreleri olarak alır ve boşlukla ayrılmış bir liste çıkarır. Değişken arasındaki tve arasındaki parametreler , diğer tüm parametreleri alan değişkenin başına eklenebilecek şekilde dçıkarılır .rs

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.