Faro bir dizi karışık


31

Bir Faro karıştırması , sihirbazlar tarafından bir desteyi "karıştırmak" için sıklıkla kullanılan bir tekniktir. Bir Faro shuffle'ı gerçekleştirmek için önce güverte 2 eşit yarıya kesilir, sonra iki yarıya eklenir. Örneğin

[1 2 3 4 5 6 7 8]

Faro karıştırdı

[1 5 2 6 3 7 4 8]

Bu, herhangi bir sayıda tekrar edilebilir. İlginçtir ki, bunu yeterince tekrarlarsanız, her zaman orijinal diziye geri dönersiniz. Örneğin:

[1 2 3 4 5 6 7 8]
[1 5 2 6 3 7 4 8]
[1 3 5 7 2 4 6 8]
[1 2 3 4 5 6 7 8]

1'in altta ve 8'in üstte kaldığına dikkat edin. Bu bir dış karışıklık yapar . Bu önemli bir ayrımdır.

Meydan okuma

Bir A tamsayı dizisi ve bir N sayısı verildiğinde, N Faro karıştırmasından sonra diziyi çıkar . A , tekrarlanan veya negatif elementler içerebilir, ancak her zaman eşit sayıda element olacaktır. Dizinin boş olmayacağını varsayabilirsiniz. Ayrıca N'nin 0 olamayacak şekilde negatif olmayan bir tam sayı olacağını varsayabilirsiniz. Bu girdileri herhangi bir makul şekilde alabilirsiniz. Bayt cinsinden en kısa cevap kazanır!

Test IO:

#N, A,                                              Output
1,  [1, 2, 3, 4, 5, 6, 7, 8]                        [1, 5, 2, 6, 3, 7, 4, 8]
2,  [1, 2, 3, 4, 5, 6, 7, 8]                        [1, 3, 5, 7, 2, 4, 6, 8]
7,  [-23, -37, 52, 0, -6, -7, -8, 89]               [-23, -6, -37, -7, 52, -8, 0, 89]
0,  [4, 8, 15, 16, 23, 42]                          [4, 8, 15, 16, 23, 42]
11, [10, 11, 8, 15, 13, 13, 19, 3, 7, 3, 15, 19]    [10, 19, 11, 3, 8, 7, 15, 3, 13, 15, 13, 19]

Ve büyük bir test durumu:

23, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

Çıkması gerekir:

[1, 30, 59, 88, 18, 47, 76, 6, 35, 64, 93, 23, 52, 81, 11, 40, 69, 98, 28, 57, 86, 16, 45, 74, 4, 33, 62, 91, 21, 50, 79, 9, 38, 67, 96, 26, 55, 84, 14, 43, 72, 2, 31, 60, 89, 19, 48, 77, 7, 36, 65, 94, 24, 53, 82, 12, 41, 70, 99, 29, 58, 87, 17, 46, 75, 5, 34, 63, 92, 22, 51, 80, 10, 39, 68, 97, 27, 56, 85, 15, 44, 73, 3, 32, 61, 90, 20, 49, 78, 8, 37, 66, 95, 25, 54, 83, 13, 42, 71, 100]  

Dizi sıfır eleman içerebilir mi?
Leaky Nun

@LeakyNun Hayır diyeceğiz, sıfır elementi işlemeniz gerekmez.
DJMcMayhem



1
Sonlu bir kümenin herhangi bir permütasyonu, eğer yeterince zaman tekrarlanırsa, başladığı yere kadar geri döner; Bu Faro karıştırmaları için özel değil.
Greg Martin,

Yanıtlar:


10

05AB1E , 5 bayt

Kod:

F2äø˜

Açıklama, giriş: N, array:

F      # Do the following N times
 2ä    # Split the array into 2 pieces
   ø   # Zip
    ˜  # Deep flatten

CP-1252 kodlamasını kullanır . Çevrimiçi deneyin! .


1
Kahretsin, çok yavaştım!
George Gibson

19

vim, 62 59 54

qrma50%mb:norm@q<cr>ggqOjdd'apjma'b@q<esc>0"qDJ<C-a>D@"i@r<esc>xxdd@"

Vay. Bu muhtemelen PPCG için yazdığım en hacimli şey ve bu da bir şeyler söylüyor.

Giriş, ilk satırda N, ardından dizinin elemanları, her biri kendi satırında alınır.

qr         first, we're going to record the contents of the @r macro. this is
             the macro which does the faro-shuffle operation.
  ma       set the mark 'a at the beginning of the file
  50%      move to the 50% point of the file (i.e. halfway down)
  mb       set another mark here
  :norm@q  evaluate the recursive macro @q. we'll get to what that does later,
             but the interesting part here is that it's :norm@q instead of @q.
             this is because a recursive macro terminates at the end of the
             file, which means when @q terminates, @r would also abort, which
             would make calling it with a count impossible. running @q under
             :norm prevents this.
  gg       move back to the top of the file for the next iteration
q          end recording
O          now we're inserting contents of the @q macro, the recursive part
             we can't record it directly because it's destructive
  j        move to line directly below mark 'b (which was just set before @q)
  dd       delete this line and bring it...
  'ap      up after mark 'a (which starts on line 1, bringing the N/2th line
             directly below line 1, aka line 2)
  jma      replace mark 'a one line below this so that the next time we call
             'ap, the line from the second half is interleaved with the lines
             from the first half
  'b       jump back to mark 'b (remember, 'b is the last line of the first
             half of the file, originally reached via 50%)
  @q       call ourselves, causing the macro to run until hitting EOF
0"qD       delete this into register "q
J          delete the empty line that remains
<C-a>      here's another interesting bit: we want to run @r N times. but 0@r
             means "go to column 0, and then run @r once." so we have to
             increment the input number...
D@"        and then *that* many times...
  i@r        insert @r...
xx         ... and finally, delete two characters, which is the extra @r from
             the increment
dd         delete the sequence of @rs into the "" register...
@"         and run it!

Aslında bu cevabı yazarken birkaç vim hatası buldum:

  • Makroların kaydedilmesi diğer makroların içinde (metnini elle ayarlarken, ile değil q) veya :*maps içinde mümkün değildir .

  • :let @a='<C-v><cr>'<cr>i<C-r>a ne olursa olsun, her ne sebeple olursa olsun iki yeni satır çıkarır.

Bunları daha sonra araştırabilirim.

Dr Green Eggs ve Ham DJ 3 bayt için teşekkürler !


4
Bu güzel ve korkunç. Muhtemelen bunu yapmak için yeterince sabrım yok. :PAyrıca, "rckyerine 2 byte vgg"rcçıkarabilir ve dw@"i@r<esc>yerine AA@R<C-v><esc><esc>0D@"
çıkarabilirsin

@DrGreenEggsandHamDJ İlk önce bunu yapamazsınız, çünkü o da yeni bir hat kapmaktır, ancak ikinci optimizasyon işe yarar. Teşekkürler!
Doorknob

7

Python 2, 59 bayt

def f(n,L):exec"l=len(L)/2;L=(L+L[1:]*~-l)[::l];"*n;print L

Diğer Python cevaplarından biraz daha uzun, farklı bir yaklaşım. Sadece pozitif eşit sayıda eleman için çalışır.

örneğin 1, [1,2,3,4,5,6,7,8], diziyi alın ve len(L)/2-1eksi ilk elemanı eksi olarak ekleyin , örn.

[1,2,3,4,5,6,7,8,2,3,4,5,6,7,8,2,3,4,5,6,7,8,2,3,4,5,6,7,8]

Sonra her len(L)/2öğeyi alın.

[1,2,3,4,5,6,7,8,2,3,4,5,6,7,8,2,3,4,5,6,7,8,2,3,4,5,6,7,8]
 ^       ^       ^       ^       ^       ^       ^       ^

6

Python, 68 57 bayt

f=lambda n,x:n and f(n-1,sum(zip(x,x[len(x)/2:]),()))or x

11 baytlık golf oynamak için @ Sp3000'e teşekkürler!

İdeone üzerinde test et .


6

Haskell, 62 bayt

0!a=a
n!a|s<-length a=(n-1)![a!!mod(div(s*i+i)2)s|i<-[0..s-1]]

Let s = 2 • t listesinin boyutu. I yeni listenin inci elemanı alarak elde edilir görüntü tanımını buraya girineski liste inci elemanı sıfır endeksli, modülo s .

Kanıt: eğer i = 2 · k sonra bile olduğunu

                                         görüntü tanımını buraya girin

ve eğer i = 2 · k + 1 tuhafsa, o zaman

                        görüntü tanımını buraya girin

Böylece indeksleme için kullanılan değerler 0, t , 1, t + 1, 2, t + 2,…


5

J - 12 bayt

Zarf (!), Sol tarafta karışık, sağ tarafta karışık olacak şekilde dizili.

/:#/:@$0,#^:

J ayrıştırıcısının açık zarf yazmak için kuralları var, ancak çok düşük önceliğe sahipler: soldan bir argüman olarak bir fiil çekimi kullanmak istiyorsanız, aksi takdirde gerekli parantez kümesini çıkartabilirsiniz. Bu yüzden yukarıdakiler aslında kısadır (/:#/:@$0,#)^:, soldaki karıştırıcı sayısını bir zarf olarak alır ve ardından diziyi sağa karıştırmak için alan monadik bir işlev haline gelir.

Bu, aşağıdaki gibi karıştırdık dedi. #dizinin uzunluğu, 0,#iki öğe listesidir: 0'dan sonra sıfırdan farklı bir şey. Sonra #/:@$bunu girdi dizisi olduğu sürece bir listeye kopyalar ve sort vektörünü alır .

Bir listenin sıralama vektörü, listenin nasıl sıralanacağına ilişkin bilgidir: en küçük öğenin (0 tabanlı) invdex'i, ardından bir sonraki en küçükün dizini vb. Örneğin, sıralama vektörü 0 1 0 1 ...böylece olacaktır 0 2 4 ... 1 3 5 ....

Eğer J şimdi bu sıralama vektörünü sıralayacak olsaydı, Faro-shuffle olurdu; ama 0 1 2 3 ...geri döneceğimizden beri bu önemsiz olurdu . Kullandığımız Yani diyadik/: giriş dizisi sıralamak o sanki 0 2 4 ... 1 3 5 ... hangi Faro-karıştırır o.

Aşağıdaki örnek kullanım. Tryj.tk'te kendiniz deneyin !

   1 (/:#/:@$0,#^:) 1 2 3 4 5 6 7 8
1 5 2 6 3 7 4 8

   f =: /:#/:@$0,#^:

   2  f  1 2 3 4 5 6 7 8
1 3 5 7 2 4 6 8

   7  f  _23 _37 52 0 _6 _7 _8 89   NB. "negative 1" is spelled _1
_23 _6 _37 _7 52 _8 0 89

   1  f  0 0 0 0 1 1 1              NB. odd-length lists
0 1 0 1 0 1 0

5

Pyth - 8 7 bayt

@acacg sayesinde 1 bayt kurtarıldı

usCc2GE

Burada çevrimiçi deneyin .


2
Hmm ... Pyth Jelly'i yenerse Jelly cevabında yanlış bir şeyler olmalı.
Sızdıran Rahibe,

2
Giriş sırasını değiştirin ve Qbayttan tasarruf etmek için ’ yi kaldırın . Jelly Pyth'i yenerse Pyth cevabında yanlış bir şeyler olmalı. :)
isaacg

@isaacg kahretsin, daha önce denediğime yemin edebilirdim. Bu neden işe yarıyor? Bu u, hiçbiri için varsayılana bağlanmamalı ve sabit nokta yapmamalı mı?
Maltysen

@Maltysen Haklısın, bence sadece denediğim bir test davasında işe yaradı. Bunun için üzgünüm.
isaacg,

@LeakyNun @Dennis ve @issacg sayesinde Pyth ve Jelly şimdi eşittir (7 bayt). ; D
Kevin Cruijssen,


2

JavaScript (ES6), 61 51 bayt

(n,a)=>[...a].map((e,i)=>a[(i<<n)%~-a.length||i]=e)

Giriş dizisini yerinde değiştirir ve orijinal dizinin bir kopyasını döndürür. Bu kabul edilemez ise, &&adeğiştirilen diziyi döndürmek için sonlandırılabilir. Sadece nJavaScript'in tamsayı aritmetiğindeki sınırlamalar nedeniyle küçük değerler için çalışır . Lynn'in formülüne göre daha büyük olan 61 60 bayt özyinelemeli sürüm n:

f=(n,a,l=a.length)=>n?f(n-1,a.map((_,i)=>a[(i*-~l>>1)%l])):a

2

MATL , 11 bayt

w:"tn2/e!1e

Düzeltme için @Dennis'e teşekkürler

Çevrimiçi deneyin!

açıklama

w         % Take the two inputs N and A. Swap them
:         % Generate [1 2 ... N]
"         % Repeat N times
  tn2/    %   Duplicate A. Number of elements divided by 2
  e       %   Reshape to that number of rows
  !       %   Transpose
  1e      %   Reshape to one row
          % End (implicit)
          % Display (implicit)

Neden wgerekli?
David

@David Bu düzeltme oldu. Onsuz, N = 0 için döngü girilmez ve ikinci giriş alınmaz
Luis Mendo

Ahh bu can sıkıcı!
David,

2

J, 22 19 17 bayt

@Gareth sayesinde 3 bayt .

@Algorithmshark sayesinde 2 bayt .

-:@#({.,@,.}.)]^:

kullanım

>> f =: -:@#({.,@,.}.)]^:
>> 2 f 1 2 3 4 5 6 7 8
<< 1 3 5 7 2 4 6 8

>>STDIN nerede ve <<STDOUT ise.

Önceki 22 bayt sürümü:

({~[:,/@|:@i.2,-:@#)^:

kullanım

>> f =: ({~[:,/@|:@i.2,-:@#)^:
>> 2 f 1 2 3 4 5 6 7 8
<< 1 3 5 7 2 4 6 8

>>STDIN nerede ve <<STDOUT ise.


Çünkü J'nin ayrıştırma kuralları , size 2 karakter için dış parens bırakabilirsiniz.
algorithmshark

18 bayt{~2,@|:@i.@,-:@#^: için aktarılmış bir indeks kullanarak alternatif .
mil, 19

17 bayt kullanan diğer bir alternatif de[:,@|:]]\~_2%~#^:
mil

@milesI ,@|:@$~2,-:@#^:15 bayt için işe yarıyor
Jonah

1

Mathematica 44 bayt

@Miles sayesinde 4 byte kurtarıldı.

Riffle@@TakeDrop[#,Length@#/2]&~Nest~##&

Riffle @@ TakeDrop[#, Length@#/2] &~Nest~## &[list, nShuffles]Listeyi iki eşit alt listeye böler ve karıştırır Riffle.


 Riffle @@ TakeDrop[#, Length@#/2] &~Nest~## &[Range@8, 1]

{1, 5, 2, 6, 3, 7, 4, 8}


Riffle @@ TakeDrop[#, Length@#/2] &~Nest~## &[Range@100, 23]

{1, 30, 59, 88, 18, 47, 76, 6, 35, 64, 93, 23, 52, 81, 11, 40, 69, 98, 28, 57, 86, 16, 45, 74, 4. 33, 62, 91, 21, 50, 79, 9, 38, 67, 96, 26, 55, 84, 14, 43, 72, 2, 31, 60, 89, 19, 48, 77, 7, 36. 65, 94, 24, 53, 82, 12, 41, 70, 99, 29, 58, 87, 17, 46, 75, 5, 34, 63, 92, 22, 51, 80, 10, 39, 68; 97, 27, 56, 85, 15, 44, 73, 3, 32, 61, 90, 20, 49, 78, 8, 37, 66, 95, 25, 54, 83, 13, 42, 71,100 }


Kullanılması TakeDropkullandığımız bir çözüm bulabiliriz 40 bayt olarak Riffle@@TakeDrop[#,Length@#/2]&~Nest~##&da diziyi çekerken ##ek argüman olarak ayrıştırılmasına Nest.
mil,

@miles. Kullanımı çok güzel TakeDrop. Ve ##diziyi eklemek için kullanmak daha iyidir .
DavidC

1

APL, 23 21 karakter

({⊃,/⍵(↑,¨↓)⍨2÷⍨⍴⍵}⍣N)A

Varsayım olmadan (Dennis sayesinde) ve 1 karakter daha kısa:

({{∊,⌿2(2÷⍨≢⍵)⍴⍵}⍣⎕)⎕

Çevrimiçi olarak deneyin .


1

java, 109 bayt

int[]f(int[]a,int n){for(int x,q=a.length,d[];0<n--;a=d){d=new int[q];for(x=0;x<q;x++)d[(2*x+2*x/q)%q]=a[x];}return a;}

Açıklama: Öğelerin faro karıştırıldıklarında nasıl hareket ettiklerini gösteren bir desen vardır:

x orijinal dizin olsun

yeni dizin olalım

L dizinin uzunluğu olsun

  • y çift x
  • x, L'nin yarısından büyük veya ona eşitse, o zaman y artışı
  • y'yi dizinin sınırları dahilinde tut

veya kod olarak: y=(2*x+x/(L/2))%L

Bu, göstergelerin 0 ile başladığını varsayar. İşte kod daha sonra açıklanmıştır:

int[] faroShuffle( int[] array, int numberOfShuffles ) {
    //repeat the faro shuffle n times
    for( int index, length=array.length, destination[]; 0<numberOfShuffles--; array=destination ) {
        //new array to copy over the elements
        destination=new int[length];
        //copy the elements into the new array
        for( index=0; index<length; index++ )
            destination[(2*index+2*index/length)%length]=array[index];
        //at the end of each loop, copy the reference to the new array and use it going forward
    }
    return array;
}  

test durumları için ideone bakın


Bir yıldan fazla geçtiğini biliyorum, ancak birkaç parçayı golf oynayabilirsiniz: void f(int[]a,int n){for(int x,q=a.length,d[];0<n--;a=d)for(d=new int[q],x=0;x<q;)d[(2*x+2*x/q)%q]=a[x++];}( 107 bayt - şu anki cevabınız 119 btw, 109 değil, yani -12 bayt). Giriş dizisini değiştirdiğiniz için, geri döndürmenize gerek yoktur, böylece baytları azaltmak için boşluğa değiştirebilirsiniz. Ah, ve eğer bir a->n->{for(int x,q=a.length,d[];0<n--;a=d){d=new int[q];for(x=0;x<q;x++)d[(2*x+2*x/q)%q]=a[x];}}
körleme

1

Julia, 45 42 bayt

a\n=n>0?reshape(a,endof(a)÷2,2)'[:]\~-n:a

Çevrimiçi deneyin!

Nasıl çalışır

\Bu görev için ikili operatörü (yeniden) tanımlarız . Let bir bir dizi ve olmak N , negatif olmayan bir tam sayı.

Eğer n pozitifse, diziyi karıştırırız. Bu, uzunluğu (a) ÷ 2 sıra ve iki sütun matrisine yeniden şekillendirerek elde edilir . 'Elde edilen matrisi, iki satır oluşturarak, ardından sonucu düzleştirerek dönüştürür [:]. Julia matrisleri sütun ana düzeninde sakladığından, bu iki sırayı araya sokar.

Daha sonra, \ardışık olarak a ve n - 1 ( ~-n) argümanları olarak çağırırız , böylece ek karışıklıklar yaparız. Bir kez n ulaşır 0 , biz mevcut değerini döndürür bir .


0

Pyke, 7 bayt

VDlec,s

Burada dene!

V       - Repeat N times:
 D      -  a,b = a (2nd arg first time round)
  le    -  b = len(b)//2
    c   -  a = chunk(a,b)
     ,  -  a = zip(*a)
      s -  a = sum(a, [])

0

Aslında 15 bayt

`;l½≈@│t)HZ♂i`n

Çevrimiçi deneyin!

Açıklama:

`;l½≈@│t)HZ♂i`n
`            `n  do the following n times:
 ;l½≈              push half the length of the array
     @             swap
      │            duplicate entire stack
       t)H         last L//2 elements, first L//2 elements
          Z♂i      zip, flatten each element

0

Prolog, 116 bayt

a([],[[],[]]).
a([H,I|T],[[H|U],[I|V]]):-a(T,[U,V]).
f(X,0,X).
f(X,N,Y):-N>0,M is N-1,f(X,M,Z),a(Z,[A,B]),append(A,B,Y).

kullanım

?- f([1,2,3,4,5,6,7,8],2,X).
X = [1, 5, 2, 6, 3, 7, 4, 8] ;
false.


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.