Bir yılan gibi slither


21

Fikir

Daha önce matris spiraller, tam dönüşler ve hatta çapraz dönüşler yaptık , ancak bulabildiğim kadarıyla yılan dönüşleri yapmıyoruz !

Bir yılan rotasyonu nedir?

Uzun kuyruktaki bölücüler gibi aralarındaki bölücülerle ileri geri dönen matrisin satırlarını hayal edin:

    +--------------+
      1  2  3  4  5|
    +------------  |
    |10  9  8  7  6|
    |  +-----------+
    |11 12 13 14 15|
    +------------  |
     20 19 18 17 16|
    +--------------+

Şimdi bu öğeleri 2'ye döndürdüğünüzü hayal edin. Her bir öğe, bir satırda hareket eden insanlar gibi ilerler ve sondaki öğeler dökülür ve başa döner:

    +--------------+
-->  19 20  1  2  3|
    +------------  |
    | 8  7  6  5  4|
    |  +-----------+
    | 9 10 11 12 13|
    +------------  |
<--  18 17 16 15 14|
    +--------------+

Tek sayıda satır varsa, sağdan çıkar, ancak yine de başlangıca sarılır. Örneğin, işte 3 rotasyon:

    +--------------+
      1  2  3  4  5|
    +------------  |
    |10  9  8  7  6|
    |  +-----------+
    |11 12 13 14 15
    +--------------+


    +--------------+
-->  13 14 15  1  2|
    +------------  |
    | 7  6  5  4  3|
    |  +-----------+
    | 8  9 10 11 12  -->
    +--------------+

Negatif bir dönüş sizi geri götürür. İşte bir -2 dönüş:

    +--------------+
<--   3  4  5  6  7|
    +------------  |
    |12 11 10  9  8|
    |  +-----------+
    |13 14 15  1  2  <--
    +--------------+

Meydan okuma

İşleviniz veya programınız herhangi bir uygun biçimde 2 giriş alacaktır:

  • Bir matris
  • Kaç yer döndüreceğini gösteren bir tam sayı (pozitif veya negatif).

Geri dönecek:

  • Döndürülmüş matris

Notlar:

  • Kod golfü. En az bayt kazanır.
  • Matrislerin kare olması gerekmez, ancak en az 2 satır ve 2 sütun içerecektir
  • Pozitif tamsayılar satır 1'i sağa döndürür
  • Negatif tamsayılar 1. satırı sola döndürür
  • Uygunsa, pozitif / negatif rotasyon numaralarının anlamını tersine çevirebilirsiniz.
  • Dönme sayısı madde sayısından daha büyük olabilir. Bu durumda, sarılacak. Başka bir deyişle, öğe sayısına göre modulo sayısına eşdeğer olacaktır.
  • Matris yalnızca tam sayıları içerecek, ancak tekrarlar da dahil olmak üzere tüm tam sayıları içerebilir

Test Kılıfları

Biçim:

  • Matris
  • Dönme numarası
  • Beklenen getiri değeri

4 5
6 7

1

6 4
7 5

2  3  4  5
6  7  8  9
10 11 12 13

-3

5  9  8  7
12 11 10 6
13 2  3  4 

8 8 7 7
5 5 6 6

10

5 5 8 8
6 6 7 7

4
+/- işaretinin ters anlamı iyi. Bence giriş sol üstte kalmalı.
Jonah

7
Bu kesinlikle Python'da bir cevaba ihtiyaç duyuyor.
640KB

Yanıtlar:


7

Jöle , 10 bayt

UÐeẎṙṁ⁸UÐe

Soldaki ekseni ve sağdaki dönüş tamsayısını kabul eden ikili bir Link (pozitif / negatif ters anlamını kullanır)

Çevrimiçi deneyin!

Nasıl?

UÐeẎṙṁ⁸UÐe - Link: matrix of integers, M; integer, R
 Ðe        - apply to even indices of M:
U          -   reverse each
   Ẏ       - tighten
    ṙ      - rotate left by R
     ṁ     - mould like:
      ⁸    -   chain's left argument, M
        Ðe - apply to even indices:
       U   -   reverse each

6

R , 121 110 101 bayt

function(m,n,o=t(m)){o[,j]=o[i<-nrow(o):1,j<-c(F,T)];o[(seq(o)+n-1)%%sum(1|o)+1]=o;o[,j]=o[i,j];t(o)}

Çevrimiçi deneyin!

Bakış

function(m,n) {           # Input: m - matrix, n - shift
  o <- t(m)               # Transpose the matrix, since R works in column-major order
                          # while our snake goes in row-major order
  i <- nrow(o):1          # Take row indices in reverse
  j <- c(F,T)             # Take even column indices (FALSE, TRUE, FALSE, TRUE, ...)
  o[,j] <- o[i,j]         # "Normalize" the matrix by reversing every second column
  o[(seq(o)+n-1) %%       # Perform the shift: add n-1 to indices,
    length(o)+1] <- o     # Modulo sequence length, and +1 again
  o[,j] <- o[i,j]         # Reverse even columns again to return to snake form
  t(o)                    # Transpose the matrix back to orginal shape and return
}

3

Python 3.8 (yayın öncesiSSSse) , 119 bayt

lambda m,r,n=-1:[[m[(k:=(j+(s:=r+i)//w)%h)][::n**k][s%w]for i in range(w:=len(m[0]))][::n**j]for j in range(h:=len(m))]

matrix, rotationYeni matrisi veren, adsız bir işlev .
Ters rotasyon işaretini kullanır.

Çevrimiçi deneyin!

Nasıl?

Daha n=-1sonra parantez içinde tasarruf etmek için önceden yola çıktık ve matrisi olduğu gibi mdöndürdük r.

Yeni bir matris ile aynı boyutlara sahip oluşturulur m- bir genişliği olan w(w:=len(m[0]) ) ve bir yüksekliğe h( h:=len(m)).

Bu matrisin diğer tüm satırları ters çevrilir ([::n**j] ).

Değerler m, geçerli satır satırlarını kullanarak orijinal satır ve sütunlarını hesaplayarak aranır.i ve sütunundaki j...

Biz set siçin r+ive khiç(j+s//w)%h . kMevcut öğemizin erişebileceği orijinalin sırasıdır.

Tek dizinli satırlara sağdan kolayca erişmek için [:n**k], bu elemanlara (ile ) erişmeden önce bu satırları tersine çeviririz , bu, ilgilenilen unsurun bulunduğu anlamına gelir s%w.


3

J , 41 30 21 bayt

Jonah sayesinde -11 bayt!

-9 bayt FrownyFrog & ngn sayesinde!

$@]t@$(|.,@t=.|.@]/\)

Çevrimiçi deneyin!

ters +/-


1
30 bayt, +/- ters değil, ama yine de yardımcı kullanıyor: $@]t@$(|.,@(t=.#\,`(|.@,)/.]))( Çevrimiçi deneyin! )
Jonah

düzeltme: +/- hala ters.
Jonah

@Jonah Şimdi bu J! Geçenlerde alternatif bir ters çevirme ile aynı numarayı uyguladığınızı hatırlıyorum, ancak görünüşe göre bunu unutmuşsunuz. Teşekkür ederim! Çalışırken &.her zaman sol argümanı kaybediyordum, bu yüzden vazgeçtim.
Galen Ivanov

1
21 bayt , thx @ngn
FrownyFrog

@ FrownyFrog Vay, şimdi ilk boyutunun yarısı. Kendimi aptal hissediyorum ... Teşekkürler!
Galen Ivanov

2

JavaScript (Node.js) , 102 bayt

Girişi olarak alır (matrix)(integer). Tamsayının işaretinin anlamı ters çevrilir.

m=>n=>(g=m=>m.map(r=>r.sort(_=>~m,m=~m)))(m.map(r=>r.map(_=>a[(l+n++%l)%l]),l=(a=g(m).flat()).length))

Çevrimiçi deneyin!

Yardımcı işlevi

g

g = m =>        // m[] = input matrix
  m.map(r =>    // for each row r[] in m[]:
    r.sort(_ => //   sort r[]:
      ~m,       //     using either 0 (don't reverse) or -1 (reverse)
      m = ~m    //     and toggling m before each iteration
                //     (on the 1st iteration: m[] is coerced to 0, so it yields -1)
    )           //   end of sort()
  )             // end of map()

Ana işlev

m => n =>                    // m[] = matrix, n = integer
  g(                         // invoke g on the final result
    m.map(r =>               //   for each row r[] in m[]:
      r.map(_ =>             //     for each entry in r[]:
        a[(l + n++ % l) % l] //       get the rotated value from a[]; increment n
      ),                     //     end of inner map()
      l = (                  //     l is the length of a[]:
        a = g(m).flat()      //       a[] is the flatten result of g(m)
      ).length               //       (e.g. [[1,2],[3,4]] -> [[1,2],[4,3]] -> [1,2,4,3])
    )                        //   end of outer map()
  )                          // end of call to g


1

Kömür , 36 bayt

FEθ⎇﹪κ²⮌ιιFι⊞υκIE⪪Eυ§υ⁻κηL§θ⁰⎇﹪κ²⮌ιι

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

Eθ⎇﹪κ²⮌ιι

Girişin alternatif satırlarını ters çevirin.

F...Fι⊞υκ

Diziyi düzleştir.

Eυ§υ⁻κη

Düzleştirilmiş diziyi döndürün.

⪪...L§θ⁰

Diziyi tekrar satırlara bölün.

E...⎇﹪κ²⮌ιι

Alternatif satırları ters çevirin.

I...

Her girişi dizeye ve çıktıya, satır başına çift aralıklı satır başına bir sayı olan varsayılan çıktı biçiminde dönüştürün. (Bir ayırıcıyla biçimlendirme, ayırıcının uzunluğuna mal olur.)



1

Japt , 28 bayt

mÏ%2©XÔªX
c éV òUÎl
W©UªßV1V

Dene

Arnauld Limanı'nın cevabı . En büyük zorluk, yeniden kullanılabilir bir fonksiyon yaratmaktı. Özellikle, diğer her sırayı tersine çeviren bir yardımcı işlev vardır. Aldığım yaklaşım özyinelemeli bir çağrı yapmak ve bir değişkenin ayarlanmış olup olmamasına bağlı olarak.

Transpiled JS:

// U: first input argument (matrix)
// m: map it through a function
U = U.m(function(X, Y, Z) {
  // if the row index is even, don't alter it
  // if the row index is odd, reverse it (w)
  return Y % 2 && X.w() || X
});
V = U
  // flatten the matrix
  .c()
  // shift by the amount specified in second argument
  .é(V)
  // partition back to matrix
  .ò(
    // the number of columns should be the same as input
    U.g().l()
  );
// if W is specified, return the result from the first line
W && U ||
  // otherwise, make a recursive call with the shifted matrix
  rp(V, 1, V)

1

Python 3 , 94 bayt

lambda m,n:g(roll(g(m),n))
g=lambda b:[b[i][::(-1)**i]for i in r_[:len(b)]]
from numpy import*

Çevrimiçi deneyin!

Jonathan Allan'ın cevabından tek sıra tersine çevirme kullandı .

lambda m,n:g(roll(g(m),n))  #reverse odd rows, shift elements, then reverse odd rows again.
g=lambda b:[b[i][::(-1)**i] #reverse odd rows
    for i in r_[:len(b)]]   #r_[:x] = range(x)
from numpy import*          #roll() and r_[]


1

C # (Visual C # Etkileşimli Derleyici) , 141 bayt

a=>n=>{for(dynamic l=a.Length,w=a.GetLength(1),i=l,j,b=a.Clone();i-->0;)a[(j=(i+n%l+l)%l)/w,j/w%2<1?j%w:w-j%w-1]=b[i/w,i/w%2<1?i%w:w-i%w-1];}

Çevrimiçi deneyin!

@Someone sayesinde toplam -5 bayt!

Giriş matrisinde yerinde değişiklik yapan adsız işlev.

Tek bir döngü, hücreler üzerinde yinelenir. Aşağıdaki formülleri kullanarak yukarıdan aşağıya ve soldan sağa tarayabilirsiniz:

  • row=i/w
  • col=i%w

iBir döngü sayacı nerede ve wsütun sayısıdır. Yılan paterninde tarama yaparken bu biraz değişir.

  • row=i/w
  • col=i%w (0, 2, 4 vb. Satır)
  • col=w-i%w-1 (1., 3., 5. vb. Satır)

Unutulmaması gereken bir başka şey de, %in C # 'nin diğer bazı dillerde olduğu gibi pozitif bir değere dönüşmemesidir. Bunun için birkaç ekstra bayta ihtiyaç var.

// a: input matrix
// n: number of cells to rotate
a=>n=>{
  for(
    // l: total number of cells
    // w: number of columns
    // i: loop index
    // j: offset index
    // b: copy of input matrix
    dynamic
      l=a.Length,
      w=a.GetLength(1),
      i=l,j,
      b=a.Clone();
    // iterate from i down to 0
    i-->0;
  )
    // calculate the offset `j` and use
    // the above formulas to index
    // into `a` for setting a value
    a[
      (j=(i+n%l+l)%l)/w,
      j/w%2<1?j%w:w-j%w-1
    ]=
    // use the un-offset index `i` and
    // the above formulas to read a
    // value from the input matrix
    b[
      i/w,
      i/w%2<1?i%w:w-i%w-1
    ];
}

Bildirimleri birleştirerek 3 bayttan tasarruf edebilirsiniz dynamic; yorum da l. Çevrimiçi deneyin!
zamirim monicareinstate

Güzel :) Bu beyanname tekrar döngüye de taşınabilir. varDeğişkenlerin bir listesini bildirmenize izin vermeyen golf oynamak için kullanma eğilimindeyim . Muhtemelen bunu neden özledim. İyi yakalama!
dana

y2 byte'ı kurtarmak için tamamen kurtulun : Çevrimiçi deneyin!
zamirim monicareinstate

@someone - teşekkürler!
dana

1d dizi ve genişlik girişi ile TIO 135 .
zamirim
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.