Méfiez-vous de la tornade matricielle!

27

La tornade matricielle est comme toute autre tornade: elle est constituée de choses tournant autour d'un centre. Dans ce cas, des éléments de la matrice au lieu de l'air.

Voici un exemple de tornade matricielle:

Matrice tornade en action

Tout d'abord, nous commençons par sectionner la matrice en anneaux carrés, chaque section est constituée d'éléments qui sont plus éloignés de la frontière de la même distance. Ces sections seront tournées dans le sens horaire autour du centre. Dans les vraies tornades, la gravité augmente vers le centre, tout comme l'étape de rotation dans une tornade à matrice: la section la plus à l'extérieur (la rouge) est tournée d'un pas, la suivante (la jaune) est tournée de 2, et ainsi de suite sur. Une étape de rotation est une rotation de 90 ° autour du centre.

Tâche:

Votre tâche, si vous l'acceptez, consiste à écrire une fonction ou un programme qui prend en entrée une matrice carrée, à lui appliquer l'effet de tornade puis à sortir la matrice résultante.

Contribution:

L'entrée doit être une matrice carrée d'ordre nn >= 1. Aucune hypothèse n'est à faire sur les éléments de la matrice, ils pourraient être n'importe quoi.

Sortie:

Une matrice carrée du même ordre qui serait le résultat de l'application de l'effet tronado à la matrice d'entrée.

Exemples:

Une matrice d'ordre n = 1:

[['Hello']]               ===>    [['Hello']]

Une matrice d'ordre n = 2:

[[1 , 2],                 ===>    [[5 , 1],
 [5 , 0]]                          [0 , 2]]

Une matrice d'ordre n = 5:

[[A , B , C , D , E],             [[+ , 6 , 1 , F , A],
 [F , G , H , I , J],              [- , 9 , 8 , 7 , B],
 [1 , 2 , 3 , 4 , 5],     ===>     [/ , 4 , 3 , 2 , C],
 [6 , 7 , 8 , 9 , 0],              [* , I , H , G , D],
 [+ , - , / , * , %]]              [% , 0 , 5 , J , E]]
ibrahim mahrir
la source
Je pense que vous voulez préciser que les rotations sont des rotations à 90 °.
Erik the Outgolfer le
Aussi, avez-vous relevé ce défi ailleurs? Si oui, vous devez fournir une attribution.
Erik the Outgolfer le
1
@EriktheOutgolfer 1) J'ai clarifié cela. 2) Ce défi est le mien.
ibrahim mahrir le
4
@Giuseppe Dépend de l'hémisphère dans lequel vous vous trouvez;)
Jo King
12
Je voudrais d'abord dire que je pense que c'est un bon défi: beau travail! Mais je voudrais également brancher ce point parce que je pense que votre choix de dire qu'il pourrait s'agir de n'importe quel type de données laisse votre défi dans un endroit difficile. De même, avec votre déclaration selon laquelle l'entrée est une liste de listes, vous avez restreint les langues qui peuvent résoudre ce problème sans effectuer un peu de surcharge. Je pense que le défi est meilleur si ces exigences sont assouplies. J'espère que vous continuerez à publier de beaux défis comme celui-ci! :)
FryAmTheEggman

Réponses:

5

Python 3 , 100 octets

import numpy
def f(a):
 if len(a): a=numpy.rot90(a,axes=(1,0));a[1:-1,1:-1]=f(a[1:-1,1:-1]);return a

Essayez-le en ligne!

Aneesh Durg
la source
8
Python classique, juste tomber a[1:-1,1:-1]=f(a[1:-1,1:-1])comme si c'était la chose la plus normale au monde pour obtenir et définir directement l'intérieur d'un tableau à 2 dimensions
ETHproductions
1
@ETHproductions Pour être honnête, une partie de cela est la syntaxe héritée denumpy
Jo King
1
numpy.rot90(a,1,(1,0))est plus court de 3 octets et devrait également fonctionner.
Graipher
1
Quel est l'intérêt de la liaison TIO sans aucun cas de test? ..: S Le voici avec (a supprimé l'espace à if len(a):a=...-1 octet).
Kevin Cruijssen
5

Fusain , 44 octets

≔EθSθWθ«≔Eθ⮌⭆觧θνλθθM¹⁻¹Lθ≔E✂θ¹±¹¦¹✂κ¹±¹¦¹θ

Essayez-le en ligne! Le lien est vers la version détaillée du code. Fonctionne uniquement sur les carrés de caractères car les E / S par défaut de Charcoal ne rendent pas justice aux tableaux normaux. Explication:

≔EθSθ

Lisez le carré des caractères.

Wθ«

Boucle jusqu'à ce qu'elle soit vide.

≔Eθ⮌⭆觧θνλθ

Faire pivoter.

θM¹⁻¹Lθ

Imprimez-le, mais déplacez ensuite le curseur sur un carré en diagonale depuis le coin d'origine.

≔E✂θ¹±¹¦¹✂κ¹±¹¦¹θ

Coupez l'extérieur du tableau.

Neil
la source
5

Gelée , 27 octets

J«þ`UṚ«Ɗ‘ịZU$LСŒĖḢŒHEƊƇṁµG

Essayez-le en ligne!

Je pense que cela pourrait être beaucoup plus court.

           Input: n×n matrix A.
J          Get [1..n].
 «þ`       Table of min(x, y).
    UṚ«Ɗ   min with its 180° rotation.

Now we have a matrix like: 1 1 1 1 1
                           1 2 2 2 1
                           1 2 3 2 1
                           1 2 2 2 1
                           1 1 1 1 1

‘ị          Increment all, and use as indices into...
     LС    List of [A, f(A), f(f(A)), …, f^n(A)]
  ZU$       where f = rotate 90°

Now we have a 4D array (a 2D array of 2D arrays).
We wish to extract the [i,j]th element from the [i,j]th array.

ŒĖ     Multidimensional enumerate

This gives us: [[[1,1,1,1],X],
                [[1,1,1,2],Y],
                ...,
                [[n,n,n,n],Z]]

ḢŒHEƊƇ     Keep elements whose Ḣead (the index) split into equal halves (ŒH)
           has the halves Equal to one another. i.e. indices of form [i,j,i,j]
           (Also, the head is POPPED from each pair, so now only [X] [Y] etc remain.)

ṁµG        Shape this like the input and format it in a grid.
Lynn
la source
1
Vous pouvez probablement mettre µGle pied de page et affirmer que votre soumission est de 25.
M. Xcoder
5

Perl 6 , 78 73 72 octets

Merci à nwellnhof pour -5 octets!

$!={my@a;{(@a=[RZ] rotor @_: sqrt @_)[1..*-2;1..@a-2].=$!}if @_;@a[*;*]}

Essayez-le en ligne!

Bloc de code récursif qui prend un tableau 2D aplati et renvoie un tableau aplati similaire.

Explication:

$!={      # Assign code block to pre-declared variable $!
    my@a; # Create local array variable a
   {
     (@a=[RZ]  # Transpose:
             rotor @_: sqrt @_;  # The input array converted to a square matrix
     )[1..*-2;1..@a-2].=$!  # And recursively call the function on the inside of the array
   }if @_;    # But only do all this if the input matrix is not empty
   @a[*;*]  # Return the flattened array
}
Jo King
la source
Vous pouvez utiliser @a[*;*]au lieu de map |*,@apour aplatir le tableau. (Ce serait bien s'il y avait un moyen de travailler avec des tableaux non aplatis et des indices multidimensionnels, mais je ne peux pas y penser.)
nwellnhof
Mais ça @a[1..*-2;1..@a-2].=$!marche.
nwellnhof
5

Octave , 86 81 octets

f(f=@(g)@(M,v=length(M))rot90({@(){M(z,z)=g(g)(M(z=2:v-1,z)),M}{2},M}{1+~v}(),3))

Essayez-le en ligne!

Je suis conscient que les fonctions anonymes récursives ne sont pas la méthode la plus courte pour faire des choses dans Octave, mais elles sont de loin la méthode la plus amusante . C'est la fonction anonyme la plus courte que j'ai pu trouver, mais j'aimerais être dépassé.

Explication

La fonction récursive est définie selon cette réponse de par le plafond. q=f(f=@(g)@(M) ... g(g)(M) ...est la structure de base d'une telle fonction anonyme, avec g(g)(M)l'appel récursif. Depuis cela indéfiniment récursif, nous terminerons l'appel récursif dans un réseau de cellules sous condition: {@()g(g)(M),M}{condition}(). La fonction anonyme avec une liste d'arguments vide retarde l'évaluation après la sélection de la condition (bien que plus tard, nous voyons que nous pouvons utiliser cette liste d'arguments pour la définir z). Jusqu'à présent, il s'agissait simplement d'une comptabilité de base.

Maintenant, pour le travail réel. Nous voulons que la fonction retourne rot90(P,-1)avec P une matrice sur laquelle g(g)a été récursivement appelée la partie centrale de M. Nous commençons par définir z=2:end-1ce que nous pouvons cacher dans l'indexation de M. De cette façon, M(z,z)sélectionne la partie centrale de la matrice qui doit être être encore tornado par un appel récursif. La ,3pièce garantit que les rotations sont dans le sens horaire. Si vous vivez dans l'hémisphère sud, vous pouvez supprimer ce bit pour -2 octets.

Nous faisons alors M(z,z)=g(g)M(z,z). Cependant, la valeur de résultat de cette opération n'est que la partie centrale modifiée plutôt que la Pmatrice entière . Par conséquent, nous faisons {M(z,z)=g(g)M(z,z),M}{2}ce qui est essentiellement volé de cette réponse de par Stewie Griffin.

Enfin, conditionc'est juste que la récursivité s'arrête lorsque l'entrée est vide.

Sanchises
la source
+1 pour l'hémisphère sud
plafond du
Je n'ai pas encore essayé de comprendre la récursivité dans des fonctions anonymes, donc je ne vais pas essayer, mais je suis curieux de voir si la récursivité est plus courte que les boucles dans celle-ci .
Stewie Griffin
@StewieGriffin Je verrai ce que je peux faire :)
Sanchises
@StewieGriffin Soit dit en passant, n'hésitez pas à publier une version en boucle de ce défi dans Octave. Je me demande vraiment si vous pouvez battre l'approche récursive.
Sanchises
4

R , 87 octets

function(m,n=nrow(m)){for(i in seq(l=n%/%2))m[j,j]=t(apply(m[j<-i:(n-i+1),j],2,rev));m}

Essayez-le en ligne!

digEmAll
la source
Est-ce permis? L'image montre une flèche dans le sens des aiguilles d'une montre et la description ci-dessous indique une rotation dans le sens des aiguilles d'une montre ...
digEmAll
J'ai dû lire la question dix fois et je ne l'ai jamais remarquée dans le sens horaire (d'où mon commentaire). Hélas.
Giuseppe
Eheh, parlez-moi de ça ... Je suis le roi des messages mal interprétés: D
digEmAll
1
Malheureusement, la matrice 1x1 ne fonctionnera pas (car seq(0.5)renvoie 1 au lieu d'un vecteur vide)
digEmAll
4

MATL , 25 24 23 22

t"tX@Jyq-ht3$)3X!7Mt&(

Essayez-le en ligne!

L'indexation en MATL n'est jamais facile, mais avec un peu de golf, elle bat en fait la meilleure réponse actuelle de Jelly ...

t                       % Take input implicitly, duplicate.  
 "                      % Loop over the columns of the input*
   X@                   % Push iteration index, starting with 0. Indicates the start of the indexing range.
     Jyq-               % Push 1i-k+1 with k the iteration index. Indicates the end of the indexing range
         t              % Duplicate for 2-dimensional indexing.
  t       3$)           % Index into a copy of the matrix. In each loop, the indexing range gets smaller
             3X!        % Rotate by 270 degrees anti-clockwise
                7Mt&(   % Paste the result back into the original matrix. 

* Pour une n x nmatrice, ce programme nen itérations, alors que vous n'avez vraiment besoin que de n/2rotations. Cependant, l'indexation dans MATL (AB) est suffisamment flexible pour que l'indexation des plages impossibles soit juste un no-op. De cette façon, il n'est pas nécessaire de gaspiller des octets pour obtenir le bon nombre d'itérations.

Sanchises
la source
3

Python 2 , 98 octets

def f(a):
 if a:a=zip(*a[::-1]);b=zip(*a[1:-1]);b[-2:0:-1]=f(b[-2:0:-1]);a[1:-1]=zip(*b)
 return a

Essayez-le en ligne!

TFeld
la source
3

K (ngn / k) , 41 39 38 octets

{s#(+,/'4(+|:)\x)@'4!1+i&|i:&/!s:2##x}

Essayez-le en ligne!

{ } fonction avec argument x

#x longueur de x - la hauteur de la matrice

2##x deux copies - hauteur et largeur (supposées identiques)

s: affecter à s pour "forme"

!stous les indices d'une matrice de forme s, par exemple , !5 5est

(0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4
 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4)

Il s'agit d'une matrice à 2 lignes (liste de listes) et ses colonnes correspondent aux indices dans une matrice 5x5.

&/ minimum sur les deux rangées:

0 0 0 0 0 0 1 1 1 1 0 1 2 2 2 0 1 2 3 3 0 1 2 3 4

i&|i:assigner i, inverser ( |) et prendre des minima ( &) aveci

0 0 0 0 0 0 1 1 1 0 0 1 2 1 0 0 1 1 1 0 0 0 0 0 0

Ce sont les nombres d'anneaux aplatis d'une matrice 5x5:

4!1+ ajouter 1 et prendre des restes modulo 4

(+|:)est une fonction qui tourne en inversant ( |- nous avons besoin de le :pour le forcer à être monadique) puis en transposant ( +- puisque ce n'est pas le verbe le plus à droite dans le "train", nous n'avons pas besoin d'un :)

4(+|:)\xl'appliquer 4 fois x, en préservant les résultats intermédiaires

,/' aplatir chacun

+ transposer

( )@' indexer chaque valeur à gauche avec chaque valeur à droite

s# remodeler en s

ngn
la source
2
Je serai heureux de voir l'explication de votre code
Galen Ivanov
1
@GalenIvanov Bien sûr. Je ne pense pas que je puisse jouer au golf plus loin, donc je ferais aussi bien d'essayer de l'expliquer.
ngn
Merci! Vos solutions me donnent envie de commencer à apprendre k (ou même ngn / k :))
Galen Ivanov
@GalenIvanov Connaissant J (et APL?), Vous êtes déjà à mi-chemin. K est plus petit et plus simple, donc je recommanderais fortement de l'apprendre et, bien sûr, je suis heureux d'en discuter à tout moment dans le verger . ngn / k n'est qu'un sous-ensemble de la réalité, mais je vise à le rendre rapide et pratique.
ngn
Oui, je pense que je vais l'essayer.
Galen Ivanov
3

JavaScript (ES6), 99 octets

f=(a,k=m=~-a.length/2)=>~k?f(a.map((r,y)=>r.map(v=>y-m>k|m-y>k|--x*x>k*k?v:a[m+x][y],x=m+1)),k-1):a

Essayez-le en ligne!

Comment?

W

m=W12tx,y=max(|ym|,|xm|)

tx,yW=5m=2

(2222221112210122111222222)

k=m(x,y)

tx,yk

tandis que les autres restent inchangés.

Cela équivaut à dire qu'une cellule n'est pas tournée si nous avons:

(ym>k) OR (my>k) OR (X2>k2) with X=mx

qui est le test utilisé dans le code:

a.map((r, y) =>
  r.map(v =>
    y - m > k | m - y > k | --x * x > k * k ?
      v
    :
      a[m + x][y],
    x = m + 1
  )
)

kk=1k=3/2W

~k === 0
Arnauld
la source
3

Gelée , 24 octets

ṙ⁹ṙ€
ḊṖ$⁺€ßḷ""ç1$ç-ZUµḊ¡

Essayez-le en ligne!

Je pense que cela pourrait être beaucoup plus court.

- Lynn

Erik le Outgolfer
la source
Je me suis interrogé sur une solution comme celle-ci! Cela ḷ""me semble magique ^^ vous voulez ajouter une explication?
Lynn
@Lynn La dernière chose à laquelle je m'attendais était d'entendre que c'était ḷ""magique. C'est juste ḷ"avec un extra "... oh, il y a une légère possibilité qui ḷ"est aussi quelque chose que j'ai "inventé" qui n'a pas été beaucoup utilisé car il peut souvent être remplacé par un seul atome (pas dans ce cas, comme le peut 0également contenir ).
Erik the Outgolfer
2

Haskell , 108 octets

e=[]:e
r=foldl(flip$zipWith(:))e
g!(h:t)=h:g(init t)++[last t]
f[x,y]=r[x,y]
f[x]=[x]
f x=r$(r.r.r.(f!).r)!x

Essayez-le en ligne!

J'ai utilisé la transposition de Laikoni et l' ai légèrement modifiée pour faire pivoter un tableau de 90 °:

  e=[]:e;foldr(zipWith(:))e.reverse
 e=[]:e;foldl(flip$zipWith(:))e

Explication

r fait pivoter un réseau de 90 °.

(!)est une fonction de niveau supérieur: «appliquer au centre». g![1,2,3,4,5]est [1] ++ g[2,3,4] ++ [5].

f est la fonction tornade: les cas de base sont de taille 1 et 2 (en quelque sorte, 0 ne fonctionne pas).

La dernière ligne est l'endroit où la magie opère: nous appliquons r.r.r.(f!).rsur les rangées du milieu xpuis tournons le résultat. Appelons les lignes du milieu M . Nous voulons revenir sur les colonnes centrales de M , et pour y arriver, nous pouvons faire pivoter M et ensuite utiliser (f!). Ensuite, nous utilisons r.r.rpour faire revenir M dans son orientation d'origine.

Lynn
la source
2

Java 10, 198 192 octets

m->{int d=m.length,b=0,i,j;var r=new Object[d][d];for(;b<=d/2;b++){for(i=b;i<d-b;i++)for(j=b;j<d-b;)r[j][d+~i]=m[i][j++];for(m=new Object[d][d],i=d*d;i-->0;)m[i/d][i%d]=r[i/d][i%d];}return r;}

-6 octets grâce à @ceilingcat .

Essayez-le en ligne.

Explication:

m->{                         // Method with Object-matrix as both parameter and return-type
  int d=m.length,            //  Dimensions of the matrix
      b=0,                   //  Boundaries-integer, starting at 0
      i,j;                   //  Index-integers
  var r=new Object[d][d];    //  Result-matrix of size `d` by `d`
  for(;b<=d/2;b++){          //  Loop `b` in the range [0, `d/2`]
    for(i=b;i<d-b;i++)       //   Inner loop `i` in the range [`b`, `d-b`)
      for(j=b;j<d-b;)        //    Inner loop `j` in the range [`b`, `d-b`)
        r[j][d+~i]=          //     Set the result-cell at {`j`, `d-i-1`} to:
          m[i][j++];         //      The cell at {`i`, `j`} of the input-matrix
    for(m=new Object[d][d],  //   Empty the input-matrix
        i=d*d;i-->0;)        //   Inner loop `i` in the range (`d*d`, 0]
      m[i/d][i%d]            //     Copy the cell at {`i/d`, `i%d`} from the result-matrix
        =r[i/d][i%d];}       //      to the replaced input-matrix
  return r;}                 //  Return the result-matrix as result

best essentiellement utilisé pour indiquer à quel anneau nous nous trouvons. Et il fera ensuite tourner cet anneau, y compris tout ce qu'il contient une fois dans le sens des aiguilles d'une montre à chaque itération.

Le remplacement de la matrice d'entrée se fait parce que Java est passe-par-référence, donc un simple réglage r=msignifierait que les deux matrices sont modifiées lors de la copie à partir de cellules, provoquant des résultats incorrects. Nous devons donc créer une nouvelle Objectmatrice (nouvelle référence) et copier les valeurs dans chaque cellule une par une à la place.

Kevin Cruijssen
la source
1

MATLAB, 93 octets

function m=t(m),for i=0:nnz(m),m(1+i:end-i,1+i:end-i)=(rot90(m(1+i:end-i,1+i:end-i),3));end;end

Je suis sûr que cela peut être joué un peu plus en quelque sorte.

Explication

function m=t(m),                                                                          end % Function definition
                for i=0:nnz(m),                                                       end;    % Loop from 0 to n^2 (too large a number but matlab indexing doesn't care)
                                                            m(1+i:end-i,1+i:end-i)            % Take the whole matrix to start, and then smaller matrices on each iteration
                                                      rot90(                      ,3)         % Rotate 90deg clockwise (anti-clockwise 3 times)
                               m(1+i:end-i,1+i:end-i)=                                        % Replace the old section of the matrix with the rotated one
Jacob Watson
la source
1

C (gcc) , 128 118 115 octets

-15 octets de @ceilingcat

j,i;f(a,b,w,s)int*a,*b;{for(j=s;j<w-s;j++)for(i=s;i<w-s;)b[~i++-~j*w]=a[i*w+j];wmemcpy(a,b,w*w);++s<w&&f(a,b,w,s);}

Essayez-le en ligne!

vazt
la source
1

Haskell, 274 octets

w est la fonction principale, qui a le type [[a]] -> [[a]] que vous attendez.

Je suis sûr qu'un golfeur Haskell plus expérimenté pourrait améliorer cela.

w m|t m==1=m|0<1=let m'=p m in(\a b->[h a]++x(\(o,i)->[h o]++i++[f o])(zip(tail a)b)++[f a])m'(w(g m'))
p m|t m==1=m|0<1=z(:)(f m)(z(\l->(l++).(:[]))(r(x h(i m)):(p(g m))++[r(x f(i m))])(h m))
t[]=1
t[[_]]=1
t _=0
h=head
f=last
x=map
i=tail.init
g=x i.i
z=zipWith
r=reverse
AlexJ136
la source
Vous voudrez peut-être consulter nos conseils pour jouer au golf à Haskell, par exemple, l' utilisation de gardes au lieu de conditionnels permettra d'économiser quelques octets.
Laikoni