Salida de posiciones diagonales de mí al cuadrado


18

Dado un número n, genera una lista ordenada de índices basados ​​en 1 que caen en cualquiera de las diagonales de una n*nmatriz cuadrada.

Ejemplo:

Para una entrada de 3:

El cuadrado será:

1 2 3
4 5 6
7 8 9

Ahora seleccionamos todos los índices representados por \, /oX ( #o se rechazan las posiciones no diagonales)

\ # /
# X #
/ # \

El resultado será:

[1,3,5,7,9]

Casos de prueba:

1=>[1]
2=>[1,2,3,4]
3=>[1,3,5,7,9]
4=>[1,4,6,7,10,11,13,16]
5=>[1,5,7,9,13,17,19,21,25]

No habrá respuesta aceptada. Quiero saber el código más corto para cada idioma.


1
La pregunta es pedir los índices (indexados en 1) de los caracteres \, / y X en las imágenes. No es una mala pregunta per se, pero carece de explicación.
Arfie

Si está dispuesto a proporcionar una explicación breve y clara de lo que desea, probablemente volveremos a abrir esto, ya que no es un mal desafío. A partir de ahora, no está muy claro
Sr. Xcoder

He votado para volver a abrir, aunque es posible que también desee mover las imágenes ascii fuera del área de ejemplos para evitar confusiones. Al principio no estaba seguro si tenía que producirlos también (pero entiendo que el resultado deseado es solo la lista de índices)
Arfie

77
¿Importa el orden?
Sr. Xcoder

99
FWIW Creo que hacer que el pedido sea irrelevante podría generar golfs más interesantes ...
Jonathan Allan

Respuestas:



7

JavaScript (ES6), 48 bytes

Emite una lista de enteros separados por guiones como una cadena.

f=(n,k=n*n)=>--k?f(n,k)+(k%~-n&&k%-~n?'':~k):'1'

Formateado y comentado

f = (n, k = n * n) => // given n and starting with k = n²
  --k ?               // decrement k; if it does not equal zero:
    f(n, k) + (       //   return the result of a recursive call followed by:
      k % ~-n &&      //     if both k % (n - 1) and
      k % -~n ?       //             k % (n + 1) are non-zero:
        ''            //       an empty string
      :               //     else:
        ~k            //       -(k + 1) (instantly coerced to a string)
    )                 //   end of iteration
  :                   // else:
    '1'               //   return '1' and stop recursion

Casos de prueba


Buena solución, utilizando los signos como separadores. ¿Podrías usar bitwsie &para guardar un byte?
Shaggy

@ Shaggy No, eso no funcionaría. Por ejemplo: 4%3y 4%5no tienen 1 bit en común, pero ambos no son cero.
Arnauld

Sí, solo lo probé n=5y descubrí que no funcionaría.
Shaggy

k%~-n&&k%-~nDeberia trabajar. buen truco con el separador!
Titus

@Titus No es que realmente importe cuando se trata de golf, pero ... sí, eso podría ser un poco más legible. :-) (actualizado)
Arnauld

7

R , 38 35 34 38 bytes

3 bytes guardados cuando recordé la existencia de la whichfunción ..., 1 byte guardado gracias a @Rift

d=diag(n<-scan());which(d|d[n:1,])

+4 bytes para el argumento ec=Tcuando se llama como un programa completo porsource()

Pruébalo en línea!

Explicación:

n<-scan()            # take input
d=diag(n);           # create an identity matrix (ones on diagonal, zeros elsewhere)
d|d[n:1,]            # coerce d to logical and combine (OR) with a flipped version
which([d|d[n:1,]])   # Find indices for T values in the logical expression above

1
-1 byted=diag(n<-scan());which(d|d[n:1,])
Grieta

Al ejecutar esto como un programa completo ( source), esto no imprime nada. Tienes que llamar cat. Ver esta publicación en meta .
JAD

@JarkoDubbeldam ¡Bastante justo! Siempre había trabajado sobre la base de que proporciona resultados válidos en TIO, nunca consideré realmente los requisitos de ser un "programa completo".
user2390246

¡Aunque no planeo volver y editar todas mis respuestas anteriores para solucionar esto!
user2390246

Es un poco vago, debido a que el entorno de consola de R y los fragmentos de código son la forma principal de usarlo. Siéntase libre de compartir ideas sobre ese metahilo que he vinculado. No ha recibido tanta información.
JAD


5

Octava , 41 37 bytes

Por cierto, esto también funciona en MATLAB. Sin funcionalidad furtiva de Octave específica :)

@(x)unique([x:x-1:x^2-1;1:x+1:x*x+1])

Pruébalo en línea!

Explicación:

En lugar de crear una matriz cuadrada y encontrar las dos diagonales, pensé que preferiría calcular las diagonales directamente. ¡Esto fue 17 bytes más corto! =)

@(x)                                   % Anonymous function that takes 'x' as input
    unique(...                   ...)  % unique gives the unique elements, sorted
           [x:x-1:x^2-1                % The anti-diagonal (is that the correct word?)
                       ;               % New row
                        1:x+1:x*x+1])  % The regular diagonal

Esto es lo que parece, sin unique:

ans =    
    6   11   16   21   26   31
    1    8   15   22   29   36

Sí, probablemente debería haber cambiado el orden de las diagonales para hacerlo más amigable con los humanos.


5

MATL , 6 bytes

XytP+f

Pruébalo en línea!

Explicación

El mismo enfoque que mi respuesta Octave.

Considere la entrada 3como un ejemplo.

Xy   % Implicit input. Identity matrix of that size
     % STACK: [1 0 0;
               0 1 0;
               0 0 1]
t    % Duplicate
     % STACK: [1 0 0
               0 1 0
               0 0 1],
              [1 0 0
               0 1 0
               0 0 1]
P    % Flip vertically
     % STACK: [1 0 0
               0 1 0
               0 0 1],
              [0 0 1
               0 1 0
               1 0 0]
+    % Add
     % STACK: [1 0 1
               0 2 0
               1 0 1]
f    % Linear indices of nonzero entries. Implicit display  
     % STACK:[1; 3; 5; 7; 9]

La indexación lineal es la columna mayor , basada en 1. Para obtener más información, consulte el fragmento de longitud 12 aquí .


¿Qué se supone que significa "transposición"?
Erik the Outgolfer

@EriktheOutgolfer Lo siento, mi mal. tes duplicado, no se transpone. Además, he agregado un ejemplo resuelto
Luis Mendo el

¡Increíble! Me llevaría dos vueltas si quiero lograr esto.
mr5

@LuisMendo sospechaba que sí, porque transponer una matriz de identidad no tiene sentido ... hmm, logré guardar un byte con su algoritmo.
Erik the Outgolfer


4

Octava, 68 54 bytes

¡Gracias a @Stewie Griffin por guardar 14 bytes!

@(x)unique([diag(m=reshape(1:x^2,x,x)),diag(flip(m))])

Pruébalo en línea!

MATLAB, 68 bytes

x=input('');m=reshape([1:x*x],x,x);unique([diag(m) diag(flipud(m))])

Explicación:

@(x)                               % Anonymous function
m=reshape([1:x*x],x,x);            % Create a vector from 1 to x^2 and
                                   % reshape it into an x*x matrix.
diag(m)                            % Find the values on the diagonal.
diag(flip(m))                      % Flip the matrix upside down and
                                   % find the values on the diagonal.
unique([])                         % Place the values from both diagonals
                                   % into a vector and remove duplicates.

@LuisMendo Gracias, Jimi es mi favorito.
Steadybox

4

Mathematica, 42 bytes

Union@Flatten@Table[{i,#+1-i}+i#-#,{i,#}]&

Pruébalo en línea!

@KellyLowder lo jugó hasta ..

Mathematica, 37 bytes

##&@@@Table[{i-#,1-i}+i#,{i,#}]⋃{}&

y @alephalpha tiró la mesa!

Mathematica, 34 bytes

Union@@Range[{1,#},#^2,{#+1,#-1}]&

##&@@@Table[{i-#,1-i}+i#,{i,#}]⋃{}& es 5 bytes más corto
Kelly Lowder

Union@@Range[{1,#},#^2,{#+1,#-1}]&
alephalpha




2

C # (.NET Core) , 97 83 bytes

f=>{var s="[";for(int i=0;i<n*n-1;)s+=i%-~n<1|i++%~-n<1?i+",":"";return s+n*n+"]";}

Pruébalo en línea!

El cambio aquí se basa en el cambio entre números para encontrar. Los dos turnos que comienzan en 0 son n-1y n+1, por lo tanto n=5, si , los números para n-1sería 0,4,8,12,16,20y para n+1sería 0,6,12,18,24. Combinando estos y dando 1-indexación (en lugar de 0-indexación) da 1,5,7,9,13,17,19,21,25. El desplazamiento desde nse logra utilizando la negación bit a bit (operación de complemento bit a bit), donde ~-n==n-1y -~n==n+1.

Versión antigua

f=>{var s="[";for(int i=0;i<n*n-1;i++)s+=(i/n!=i%n&&n-1-i/n!=i%n?"":i+1+",");return s+$"{n*n}]";}

Pruébalo en línea!

Este enfoque utiliza los índices de columna y fila para determinar si los números están en las diagonales. i/nda el índice de la fila y i%nda el índice de la columna.

Devolviendo solo la matriz de números

Si se considera que construir solo la matriz de números cuenta para el costo de bytes, entonces se podría hacer lo siguiente, según la sugerencia de Dennis.Verweij ( using System.Linq;agrega 18 bytes adicionales):

C # (.NET Core) , 66 + 18 = 84 bytes

x=>Enumerable.Range(1,x*x).Where(v=>~-v%~-x<1|~-v%-~x<1).ToArray()

Pruébalo en línea!


puedes reducir el código deshaciéndote del extra &. El extra &está ahí solo para romper la comparación si la primera entrada es falsa MSDN
Dennis.Verweij

de hecho, puedes tener 92 bytes usando Linq ¡ Pruébalo en línea!
Dennis.Verweij

@ Dennis.Verweij Neat, no estaba seguro de cuánto podría cambiar al encabezado o pie de página en TIO. Jugaré con el mío.
Ayb4btu

debe recordar incluir 18 bytes para la referencia a linq (usando System.Linq;) que es desafortunado, pero cómo funciona: S
Dennis.Verweij

Ah ok Pero eso no es necesario using System;? (¿Asumo que envolverlo en un namespace System.Linqno es válido?)
Ayb4btu

2

Javascript, 73 63 bytes

versión antigua

n=>[...Array(y=n*n).keys(),y].filter(x=>(--x/n|0)==x%n||(x/n|0)==n-x%n-1)

Guardado 10 bytes gracias a @Shaggy

n=>[...Array(n*n)].map((_,y)=>y+1).filter(x=>!(--x%-~n&&x%~-n))

Primera vez jugando al golf! Espero no haberlo estropeado demasiado.


Bienvenido a PPCG :) Una solución similar a la que estaba trabajando (solo la mía está indexada en 0). Es posible que pueda guardar algunos bytes utilizando lo siguiente en su filterfunción: !(--x%(n+1)&&x%(n-1))y creando su matriz de esta manera:[...Array(n*n+1).keys()]
Shaggy

@ Shaggy Gracias! ¡Intentaré mejorar la respuesta con su sugerencia tan pronto como llegue a casa del trabajo!
Marco Lepore

De nada. Por cierto: " es un poco más corto que crear un [1...n*n]rango conArray(n*n).fill().map((x,i)=>i+1) " - [...Array(n*n)].map((_,y)=>y+1)es una forma más corta de hacerlo, para referencia futura.
Shaggy

Hice un poco más y terminé con esto por 56 bytes:n=>[...Array(n*n+1).keys()].filter(x=>!(--x%-~n&&x%~-n))
Shaggy

@Shaggy Probé tu última versión pero generaría un cero extra para f (1) yf (2), aunque funciona con un rango [1 ... n * n], así que utilicé la forma en que me mostraste en el comentario anterior ¿O tal vez me equivoqué de alguna manera?
Marco Lepore


1

Perl 5 , 56 + 1 (-n) = 57 bytes

!(($_+1+$_/$,)%$,&&$_%($,+1))&&say++$_ for 0..($,=$_)**2

Pruébalo en línea!


¿No debería `-n` ser +3?
sergiol

1
No. La línea de comando asumida es perl -e. La línea de comando para este ejemplo sería perl -ne. Esa es una diferencia de +1.
Xcali


1

Japt , 16 bytes

Parece que no puede hacerlo mejor que esto, pero estoy seguro de que es posible. Tuve que sacrificar 2 bytes por el requisito innecesario de que usáramos 1 indexación.

²õ f@´XvUÉ ªXvUÄ

Pruébalo



0

PHP, 56 54 + 1 bytes

+1 byte para -Rbandera

for(;$z**.5<$n=$argn;$z++)$z%-~$n&&$z%~-$n||print~+$z;

imprime números precedidos por guiones. Ejecutar como tubería -nRo probarlo en línea .

requiere PHP 5.6 o posterior para el **operador.
Agregue un byte para PHP anterior: Reemplace ;$z**.5<$n=$argncon $z=$argn;$z<$n*$n.


0

Ruby, 45 bytes

->n{(n*n).times{|i|i%-~n>0&&i%~-n>0||p(i+1)}}

Funciona internamente como cero indexado. comprueba si imódulo n+1o n-1es 0, si es así imprime i+1.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.