Kundakçı ninni bul


26

Kasabanın etrafında yürüdüğünü ve kurbanlarını çok özel bir örüntüye göre seçtiğini düşünen bir kundakçı düşünün (Ya da alternatif olarak, bahçenin etrafında uçan ve çiçeklerini çok özel bir örüntüye göre polenlemek için topladığınızı düşünün ). Diyelim ki şehir bir N × N matrisi, burada N 2 veya daha büyük bir tam sayıdır . Arda sol üst köşesinden ve kundakçı başlar ev setleri M (önlerinde noktalar M sırayla, her yangından sonra içinde hareket ediyor yönünü değiştirirken, şu anda konum evin sayıdır) Doğu ⟶ Güney ⟶ Batı ⟶ Kuzey ⟶ Doğu ⟶ Güney ... vb. ninnikundakçı, şehirden çıkmalarını sağlayan M'nin değeridir (yani, gemiyi durdurmadan önce en son ziyaret ettikleri ev). Bu bir örnek ile anlamak için daha kolay. Örneğin aşağıdaki matrisi alın:

3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1
  • Sol üst köşeden başlıyoruz, bu nedenle M = 3 ( Xkundakçının şu anki ve önceki konumlarını işaretler):
    X 2 3 2 7
    3 1 4 1 6
    2 5 3 1 1
    4 4 3 2 4
    1 1 1 1 1
    
  • Bilinen düzene göre, ilk önce doğu M (3) noktaları gider ve 2 üzerine iner, böylece M buna göre değişir:
    X 2 3 X 7
    3 1 4 1 6
    2 5 3 1 1
    4 4 3 2 4
    1 1 1 1 1
    
  • Sonra güneye 2 nokta güneyde gider ve M şimdi 1'dir :
    X 2 3 X 7
    3 1 4 1 6
    2 5 3 X 1
    4 4 3 2 4
    1 1 1 1 1
    
  • Şimdi 1 nokta batıya doğru hareket eder ve M 3 olur :
    X 2 3 X 7
    3 1 4 1 6
    2 5 XX 1
    4 4 3 2 4
    1 1 1 1 1
    
  • 3 nokta kuzeye hareket ettikten sonra kasabadan çıkar! Bu nedenle, 3 bu kundakçı ninni:
        X
    X 2 3 X 7
    3 1 4 1 6
    2 5 XX 1
    4 4 3 2 4
    1 1 1 1 1
    

Bir N × N matrisi verildiğinde (isteğe bağlı olarak N'yi de girdi olarak alabilirsiniz ), kundakçının ninniğini bulun. Daha fazla test senaryosu oluşturabileceğiniz ve kundakçının yolunu görselleştirebileceğiniz bir program yazdım: Çevrimiçi deneyin!

  • Sen kundakçı varsayabiliriz yapar (olduğunu, aslında matris çıkabiliriz) ninni var.
  • Matris basitlik için sadece 9'dan ( veya daha küçük ) sayıya eşit veya daha küçük pozitif tamsayılar içerecektir . Herhangi bir pozitif tamsayı işleyen çözümler tamamen açıktır.
  • Kundakçının , daha önce yaktıkları bir noktaya inebileceğini unutmayın, çünkü hareket ettikleri hissi ilk kez farklıdır. Böyle bir senaryoda, sadece bu öğenin değerini al ve her zamanki gibi tekrar hareket et.
  • Herhangi bir programlama dilinde rekabet edebilir ve herhangi bir standart yöntemle girdi alabilir ve çıktı alabilirsiniz ; bu boşluklar varsayılan olarak yasaklanmıştır. Bu , yani her dil için en kısa sürede (bayt cinsinden) kazanıyor.

Test durumları

-------------
9 2 3
1 7 2
8 7 6

Ninni: 9
-------------
2 1 2 1
3 1 1 2
1 2 2 1
1 1 1 3

Ninni: 2
-------------
3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

Ninni: 3
-------------
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2

Ninni: 2
-------------
3 2 1 2 1 1 1
2 3 2 3 2 1 1
2 1 1 1 3 1 2
3 1 1 1 1 1 1
4 5 2 3 1 1 1
1 2 1 2 1 2 2
1 2 2 3 2 1 2

Ninni: 3
-------------

Matrisler farklı formatta:

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

Beşinci test örneği, görselleştirilmesi çok ilginçtir .


1
Bu, Skip gibi bir tavşanın iki boyutlu, biraz farklı bir amacı olan bir genellemesi gibidir . Bu zorluğun teması
Bay Xcoder

kundakçı zaten yanmış bir kareye indiğinde ne olur?
Seviye River St

2
Kundakçının gerçekte kundakçı olmadığını ve bunun yerine her yerde güzel bir şey yapmak yerine onu yaktığını varsayabilir miyiz? Çok güzel bir fikir için +1 :)
ElPedro

2
Sizin için alternatif bir versiyon olan @ElPedro Sure: Bahçenin etrafında uçan bir arının ve çiçeklerin çok özel bir desene göre polenlenmesi için toplandığını hayal edin. : D Mutlu arkadaş canlısı golf!
Bay Xcoder

1
Bu çok daha iyi bir düşünce. Tekrar oy verebilseydim bunun için yapardım.
ElPedro

Yanıtlar:


11

MATL , 32 bayt

JQ6*`G5thYay&Zj3$)wyJ2@-^*+8M]b&

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

Nasıl çalışır

Giriş matrisi, beş sıfırlık bir çerçeve ile doldurulur, örneğin

3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

olur

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 3 2 3 2 7 0 0 0 0 0
0 0 0 0 0 3 1 4 1 6 0 0 0 0 0
0 0 0 0 0 2 5 3 1 1 0 0 0 0 0
0 0 0 0 0 4 4 3 2 4 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Sıfırların çerçevesi, kundakçı arının matristen ne zaman çıktığını tespit etmek için kullanılır . Beş sıfır olan uzatma , sıfır olmayan girişlerin herhangi birinden herhangi bir yöne kadar olan modüler bir uzunluk 9kaymasının, sıfır olmayan bir girişin etrafına sarılmadan doğru şekilde sıfırlanmasını sağlar.

Matris koordinatlarında, arı (6,6)genişletilmiş matrisin girişinde başlar . Bu girişi okur ve koordinatları gerektiği gibi günceller, okuma uzunluğunun ilgili modüle (modüler) bir yer değiştirmesini uygular. Bu, okuma değeri olana kadar bir döngüde tekrarlanır 0. Bundan önce okunan giriş (yani, son sıfır olmayan giriş) çıktıdır.

Koordinatlar aslında karmaşık bir sayı olarak saklanır, yani (6,6)olur 6+6j. Bu şekilde dört döngüsel yön hayali birimin güçleri olarak gerçekleştirilebilir. Karşılık gelen gücü ( j, 1, -jya da -1) koordinatları güncellemek için kullanılır kompleks yer değiştirmesinin elde edilmesi için okuma giriş ile çarpılır.

Ardışık olarak okunan değerler yığında tutulur. Döngüden çıkıldığında, yığın sırayla tüm sıfır olmayan değerleri 0, sonra da en son karmaşık koordinatları olan son okuma değerini içerir . Böylece üçüncü üst öğe gerekli çıktıdır.


1
Çok yenilikçi bir yaklaşım için +1.
LastStar007,

7

JavaScript (ES6), 70 68 bayt

m=>(g=d=>(n=(m[y]||0)[x])?g(--d&3,x-=d%2*(y+=--d%2*n,L=n)):L)(x=y=0)

Çevrimiçi deneyin!

Yorumlananlar

m => (                        // given m = input matrix
  g = d =>                    // g = recursive function taking the direction d
    (n = (m[y] || 0)[x]) ?    // let n be the content of the current cell; if it's defined:
      g(                      //   do a recursive call:
        --d & 3,              //     with the next direction (0 = E, 3 = S, 2 = W, 1 = N)
        x -=                  //     update x by subtracting ...
          d % 2 * (           //       ... ((d - 1) % 2) * n
            y += --d % 2 * n, //       and update y by adding ((d - 2) % 2) * n
            L = n             //       save n into L
          )                   //     end of x update
      )                       //   end of recursive call
    :                         // else:
      L                       //   stop recursion and return L
)(x = y = 0)                  // initial call to g() with x = y = d = 0

JS'deki modülo işaretinin temettü işareti olduğu düşünülürse, yön şu şekilde güncellenir:

 d | d' = --d&3 | dx = -(d%2)  | dy = --d%2 | direction
---+------------+--------------+------------+------------------
 0 |     3      | -(-1%2) = +1 | -2%2 =  0  | (+1,  0) = East
 3 |     2      | -( 2%2) =  0 |  1%2 = +1  | ( 0, +1) = South
 2 |     1      | -( 1%2) = -1 |  0%2 =  0  | (-1,  0) = West
 1 |     0      | -( 0%2) =  0 | -1%2 = -1  | ( 0, -1) = North

4

Kömür , 25 18 bayt

PS↶WKK«≔ιθ×Iι¶↷»⎚θ

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

PS

Giriş dizesini yazdırın, ancak yazdırma konumunu hareket ettirmeyin.

Pivotu sola çevirin, böylece yazdırma yönü şimdi yukarı kalkar.

WKK«

Baskı pozisyonunun altında bir karakter varken tekrarlayın.

≔ιθ

Karakteri bir değişkene kaydedin.

×Iι¶

Karakteri sayıya çevir ve bu kadar çok yeni satırı yazdır. Baskı yönü şimdi yukarıdayken, bu yatay olarak yazdırmayı sonlandırır. Sonuçta, baskı pozisyonunu, baskı pozisyonunun altındaki sayının verdiği miktar kadar istenen yöne kaydırdık.

↷»

Pivotu çevirin, böylece bir sonraki yeni satırlar döngünün bir sonraki geçişi için baskı konumunu bir sonraki yöne saat yönünde hareket ettirir.

F⟦ωθ⟧¿ιι⎚

Ne yazık ki hala tuvalimizi bozan girdiler var ve hatta ne yazık ki, tuvali temizlersek değişkenimizi de temizliyoruz. Yani, bu bir püf noktasıdır: boş dizgenin ve değişkenin bir listesi tekrarlanır. Döngünün ilk geçişinde, döngü değişkeni boştur, böylece tuval ve döngü değişkeni ve sonuç değişkeni silinir. Ancak döngü bitmedi! Döngünün ikinci geçişinde, yine de döngü listemizde saklanan değişkenimize erişmeye devam ediyoruz. Sadece yazdırmak için kalır.

⎚θ

Tuvali temizleyin ve kaydedilen değişkeni yazdırın. (@ ASCII-Yalnızca Charcoal'a yapılan düzeltme için teşekkürler.)



2

Kömür , 50 49 46 34 33 26 bayt

NθEθSMθ↑WKK«MIι✳⊗Lυ⊞υι»⎚⊟υ

Çevrimiçi deneyin

Bağlantı, kodun ayrıntılı sürümüne

Girdi , kendi satırında N , daha sonra dizinin satırları ayrı satırlarda olmalıdır.

Kömür'de iyi bir golfçü olmadığım için baytları atmanın herhangi bir yolu hoş ve aranıyor!

@Neil -12 bayt sayesinde! Sadece @ ASCII-1 sayesinde bayt! Yalnızca @ ASCII -7 sayesinde -7 bayt ( Clearsıfırlama değişkenleri yapan hatayı değiştirdi )


1

Kırmızı , 145 bayt

func[b][h:[0 1 0 -1 0]x: y: 1 i: 0
until[y: h/(i: i % 4 + 1) *(t: b/(y)/(x)) + y x: h/(i + 1) * t + x none = b/(y) or(x < 1 or(x > length? b))]t]

Çevrimiçi deneyin!

Daha okunabilir:

f: func[b][
    h: [0 1 0 -1 0]                                ; step lengths (combined for x and y) 
    x: y: 1                                        ; starting coords (1,1)
    i: 0                                           ; step counter 
    until[
        y: h/(i: i % 4 + 1) * (t: b/(y)/(x)) + y   ; next y; t stores the lullaby
        x: h/(i + 1) * t + x                       ; next x
        none = b/(y) or (x < 1 or (x > length? b)) ; until x or y are not valid indices
    ]
    t                                              ; return the lullaby
]


1

Temiz , 141 bayt

import StdEnv
d=[0,1,1,0,0,-1,-1,0:d]
$m[x,y]n[a,b:l]#r=size m
#u=x+a*n
#v=y+b*n
|0>u||0>v||u>=r||v>=r=n= $m[u,v]m.[u,v]l
?m= $m[0,0]m.[0,0]d

Çevrimiçi deneyin!

? :: {#{#Int}} -> IntKutusuz bir kutusuz tamsayı dizisi dizisini alarak ve sonucu döndüren işlevi tanımlar .


1

Java 8, 121 bayt

m->{int l=m.length,x=0,y=0,f=0,r=0;for(;x*y>=0&x<l&y<l;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];return r;}

Çevrimiçi deneyin.

Aynı 121 bayt bayt sayısı ile alternatif :

m->{int l=m.length,x=0,y=0,f=0,r=0;try{for(;;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];}finally{return r;}}

x,y-Koordinatın hala sınırların içinde olup olmadığını kontrol etmek yerine try- finally'u kullanır .

Çevrimiçi deneyin.

Açıklama:

m->{                   // Method with integer-matrix parameter and integer return-type
  int l=m.length,      //  Dimensions of the matrix
      x=0,y=0,         //  x,y coordinate, starting at [0,0]
      f=0,             //  Direction-flag, starting at 0 (east)
      r=0;             //  Result-integer
  for(;x*y>=0&x<l&y<l  //  Loop as long as the x,y coordinates are still within bounds
      ;                //    After every iteration:
       x+=f<1?         //     If the direction is east:
           r           //      Increase the `x` coordinate by `r`
          :f==2?       //     Else-if the direction is west:
           -r          //      Decrease the `x` coordinate by `r`
          :            //     Else (it's north/south):
           0,          //      Leave the `x` coordinate the same
       y+=f==1?        //     If the direction is south:
           r           //      Increase the `y` coordinate by `r`
          :f>2?        //     Else-if the direction is north:
           -r          //      Decrease the `y` coordinate by `r`
          :            //     Else:
           0,          //      Leave the `y` coordinate the same
       f=++f%4)        //     Go to the next direction (0→1→2→3→0)
    r=m[y][x];         //   Set `r` to the value of the current cell
  return r;}           //  Return the last `r` before we went out of bounds

0

Perl 5 , 92 bayt

sub b{1while eval join'&&',map{/./;map"(\$$_$&=".'$n=$_[$y][$x])'.$',x,'y'}'+<@_','->=0';$n}

Çevrimiçi deneyin!

Nasıl?

İç içe geçmiş haritalar ve birleştirme kümesi bunu üretir:

($x+=$n=$_[$y][$x])<@_&&($y+=$n=$_[$y][$x])<@_&&($x-=$n=$_[$y][$x])>=0&&($y-=$n=$_[$y][$x])>=0

hangi döngünün bitip bitmediğini belirlemek için değerlendirilir. Boolean soldan sağa değerlendirildiği için $n, değerlendirme sırasında gerçekte değeri (en fazla) dört kere değişir. Boolean mantığı Perl'deki kısa devreler nedeniyle $n, döngüden çıktığında ninni ninnidir.


0

Python 3 , 85 84 bayt

xcoder: -1 (Ben + ~ hilesini asla hatırlamıyorum)

def f(x):
 r=c=0
 while-1<r:d=x[r][c];r,c=len(x)-c+~d,r;x=[*zip(*x)][::-1]
 return d

Çevrimiçi deneyin!

Farklı yönlerde (E, S, W, N) hareket etmek yerine, bu çözüm her zaman doğuya doğru hareket eder ve her hareketten sonra ızgarayı saat yönünün tersine döndürür. Döndükten sonra, son sütun neydi şimdi ilk satırdı, yani satır endeksi sıfırdan azsa, panodan kaçtığımız anlamına gelir.


84 bayt : -d-1=>+~d
Bay Xcoder

0

Retina , 161 bayt

.
 $.%`*_#$&*
(?<=(.+¶)+|^)
A ¶A$#1*
~(K`{`^X\1YZ¶1S$4¶1XYZ¶2$4$2$4$3¶2XYZ¶3S¶3XY\1Z¶S
X
(_$*)(A_$*)
Y
( _$*)
Z
(?=\n\D$*\2\b.$*\3#(_+))
)`S
$$4$$2$$3
L$0`_+
$.0

Çevrimiçi deneyin!

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.