Trova la ninna nanna del piromane


26

Immagina un incendiario che cammina per la città e raccoglie le sue vittime secondo uno schema molto specifico (o, in alternativa, immagina un'ape che vola intorno al giardino e raccoglie i suoi fiori per impollinare secondo uno schema molto specifico ). Diciamo che la città è una matrice N × N , dove N è un numero intero maggiore o uguale a 2 . L'incendiario inizia dall'angolo in alto a sinistra e imposta successivamente i punti M della casa davanti a loro (dove M è il numero della casa in cui si trovano attualmente), mentre cambia la direzione in cui si sta muovendo dopo ogni incendio, nell'ordine Est ⟶ Sud ⟶ Ovest ⟶ Nord ⟶ Est ⟶ Sud ... e così via. La ninna nannadel piromane è il valore di M che li fa uscire dalla città (ovvero l'ultima casa che visitano prima di fermare l'abominio). Questo è molto più facile da capire con un esempio. Prendi ad esempio la seguente matrice:

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
  • Iniziamo nell'angolo in alto a sinistra, quindi M = 3 ( Xsegna la posizione attuale e precedente dell'incendiario):
    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
    
  • Secondo l'ordine noto, per prima cosa va a est M (3) punti e atterra su un 2, quindi M cambia di conseguenza:
    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
    
  • Quindi va a sud di 2 punti e M ora è 1 :
    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
    
  • Ora si sposta di 1 punto verso ovest e M diventa 3 :
    X 2 3 X 7
    3 1 4 1 6
    2 5 XX 1
    4 4 3 2 4
    1 1 1 1 1
    
  • Dopo che si è spostato di 3 punti verso nord, esce dalla città! Pertanto, 3 è la ninna nanna di questo incendiario:
        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
    

Data una matrice N × N (puoi anche prendere N come input), trova la ninna nanna del piromane. Ho scritto un programma con il quale è possibile generare più casi di test e visualizzare il percorso del piromane: provalo online!

  • Si può supporre che l'incendiario ha una ninna nanna (che è, in realtà può uscire dalla matrice).
  • La matrice conterrà solo numeri interi positivi inferiori o uguali a 9 (cifre), per semplicità. Le soluzioni che gestiscono qualsiasi numero intero positivo sono completamente benvenute.
  • Nota che l'incendiario può atterrare in un punto che hanno già bruciato, nel caso in cui il senso in cui si muovono sia diverso dalla prima volta. In uno scenario del genere, prendi semplicemente il valore di quell'elemento e muoviti di nuovo come al solito.
  • Puoi competere in qualsiasi linguaggio di programmazione e puoi prendere input e fornire output attraverso qualsiasi metodo standard , tenendo presente che queste scappatoie sono vietate per impostazione predefinita. Questo è , quindi vince l'invio più breve (in byte) per ogni lingua .

Casi test

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

Ninna nanna: 9
-------------
2 1 2 1
3 1 1 2
1 2 2 1
1 1 1 3

Ninna nanna: 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

Ninna nanna: 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

Ninna nanna: 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

Ninna nanna: 3
-------------

Le matrici in un formato diverso:

[[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]]

Il quinto caso di test è molto interessante da visualizzare .


1
È come una generalizzazione di Skip come un coniglio in due dimensioni, con un obiettivo leggermente diverso. La tematica di questa sfida e il suo titolo sono stati ispirati da una canzone di Hozier
Mr. Xcoder

cosa succede quando l'incendiario atterra su una piazza che è già bruciata?
Level River St,

2
Possiamo supporre che il piromane non sia in realtà un piromane e invece stia facendo qualcosa di carino in ogni luogo piuttosto che bruciarlo? +1 per una bella idea :)
ElPedro

2
@ElPedro Certo, una versione alternativa per te: immagina un'ape che vola intorno al giardino e raccoglie i suoi fiori per impollinare secondo uno schema molto specifico. : D Buon golf amichevole!
Mr. Xcoder

1
È un pensiero molto più bello. Se potessi votare nuovamente, lo farei.
ElPedro

Risposte:


11

MATL , 32 byte

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

Provalo online! Oppure verifica tutti i casi di test .

Come funziona

La matrice di input è riempita con una cornice di cinque zeri, quindi ad esempio

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

diventa

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

La cornice di zeri viene utilizzata per rilevare quando l' ape incendiaria è uscita dalla matrice. L'estensione con cinque zeri assicura che uno spostamento modulare di lunghezza fino a 9in qualsiasi direzione da una qualsiasi delle voci diverse da zero atterrerà correttamente in uno zero senza avvolgersi in una voce diversa da zero.

Nelle coordinate della matrice, l'ape inizia all'ingresso (6,6)della matrice estesa. Legge quella voce e aggiorna le coordinate come richiesto, applicando uno spostamento (modulare) della lunghezza di lettura nella direzione corrispondente. Questo viene ripetuto in un ciclo fino a quando il valore letto è 0. La voce che è stata letta prima di quella (ovvero l'ultima voce diversa da zero) è l'output.

Le coordinate sono effettivamente memorizzate come un numero complesso, quindi ad esempio (6,6)diventa 6+6j. In questo modo le quattro direzioni cicliche possono essere realizzate come poteri dell'unità immaginaria. La potenza corrispondente ( j, 1, -jo -1) viene moltiplicato per l'ingresso di lettura per ottenere uno spostamento complesso che viene utilizzato per l'aggiornamento delle coordinate.

I valori letti successivamente vengono mantenuti nello stack. Quando il ciclo viene chiuso, lo stack contiene tutti i valori di lettura diversi da zero in ordine, quindi l'ultimo valore di lettura che è 0, quindi le coordinate complesse più recenti. Quindi il terzo elemento in alto è l'output richiesto.


1
+1 per un approccio molto innovativo.
LastStar007,

7

JavaScript (ES6), 70 68 byte

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

Provalo online!

Commentate

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

Dato che il segno del modulo in JS è quello del dividendo, la direzione viene aggiornata in questo modo:

 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

Carbone , 25 18 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

PS

Stampa la stringa di input, ma non spostare la posizione di stampa.

Ruotare il perno a sinistra, in modo che la direzione di stampa sia ora verso l'alto.

WKK«

Ripeti finché c'è un carattere sotto la posizione di stampa.

≔ιθ

Salva il personaggio in una variabile.

×Iι¶

Trasforma il personaggio in un numero e stampa tante nuove righe. Dato che la direzione di stampa è ora in alto, questo finisce per stampare in orizzontale. Il risultato è che abbiamo spostato la posizione di stampa nella direzione desiderata della quantità indicata dal numero sotto la posizione di stampa.

↷»

Ruota il perno in modo che le righe successive spostino la posizione di stampa nella direzione successiva in senso orario per il passaggio successivo del ciclo.

F⟦ωθ⟧¿ιι⎚

Sfortunatamente abbiamo ancora l'input che ingombra la nostra tela, e ancora più sfortunatamente, se cancelliamo la tela cancelliamo anche la nostra variabile. Quindi, questo è un po 'un trucco: un elenco della stringa vuota e la variabile viene ripetuta ciclicamente. Al primo passaggio del ciclo, la variabile del ciclo è vuota, quindi l'area di disegno e la variabile del ciclo e la variabile del risultato vengono tutte cancellate. Ma il ciclo non è finito! Al secondo passaggio del ciclo, riusciamo ancora ad accedere alla nostra variabile accuratamente conservata nel nostro elenco di cicli. Resta semplicemente da stampare.

⎚θ

Cancella la tela e stampa la variabile salvata. (Grazie solo a @ ASCII per la correzione di Carbone.)



2

Carbone di legna , 50 49 46 34 33 26 byte

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

Provalo online

Il collegamento è alla versione dettagliata del codice

L'input deve essere N su una riga propria, quindi le righe dell'array su righe separate.

Tutti i modi per sbarazzarsi dei byte sono i benvenuti e desiderati, poiché non sono un buon giocatore di golf in Carbone!

-12 byte grazie a @Neil! -1 byte grazie solo a @ ASCII! -7 byte grazie solo a @ ASCII (modificato un bug che ha reso le Clearvariabili di ripristino)


1

Rosso , 145 byte

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]

Provalo online!

Più leggibile:

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

Pulito , 141 byte

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

Provalo online!

Definisce la funzione ? :: {#{#Int}} -> Int, prendendo un array unboxed di array unboxed di numeri interi e restituendo il risultato.


1

Java 8, 121 byte

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;}

Provalo online.

Alternativa con lo stesso conteggio byte di 121 byte :

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;}}

Utilizza try-finally invece di verificare se x,y coordinata è ancora entro i limiti.

Provalo online.

Spiegazione:

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 byte

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

Provalo online!

Come?

L'insieme di mappe nidificate e il join producono questo:

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

che viene quindi valutato per determinare se il ciclo termina. Poiché il valore booleano viene valutato da sinistra a destra, il valore di $neffettivamente cambia (fino a) quattro volte durante la valutazione. Poiché la logica booleana è in cortocircuito in Perl, il valore di $nè la ninna nanna quando si esce dal loop.


0

Python 3 , 85 84 byte

xcoder: -1 (non ricordo mai il trucco + ~)

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

Provalo online!

Invece di spostarsi in direzioni diverse (E, S, W, N), questa soluzione si sposta sempre verso est e ruota la griglia in senso antiorario dopo ogni spostamento. Dopo aver ruotato, quella che era l'ultima colonna ora è la prima riga, quindi se l'indice di riga è inferiore a zero significa che siamo scappati dal tabellone.


84 byte : -d-1=>+~d
Mr. Xcoder

0

Retina , 161 byte

.
 $.%`*_#$&*
(?<=(.+¶)+|^)
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

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.