Stampa le posizioni diagonali di me al quadrato


18

Dato un numero n, genera un elenco ordinato di indici basati su 1 che ricadono su una delle diagonali di una n*nmatrice quadrata.

Esempio:

Per un input di 3:

La piazza deve essere:

1 2 3
4 5 6
7 8 9

Ora selezioniamo tutti gli indici rappresentati da \, /o X( #o le posizioni non diagonali vengono rifiutate)

\ # /
# X #
/ # \

L'output deve essere:

[1,3,5,7,9]

Casi test:

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]

Non ci sarà una risposta accettata. Voglio sapere il codice più breve per ogni lingua.


1
La domanda è chiedere gli indici (1-indicizzati) dei caratteri \, / e X nelle immagini. Non è una cattiva domanda di per sé, ma manca di spiegazione.
Arfie,

Se sei disposto a fornire una breve e chiara spiegazione di ciò che desideri, probabilmente riapriremo questo, poiché non è una brutta sfida. A partire da ora, non è molto chiaro
Mr. Xcoder

Ho votato per riaprire, anche se potresti anche voler spostare le immagini ASCII fuori dall'area degli esempi per evitare confusione. All'inizio non ero sicuro di dover produrre anche quelli (ma capisco che l'output desiderato è solo l'elenco degli indici)
Arfie

7
L'ordine è importante?
Mr. Xcoder,

9
FWIW Penso che avere un ordine irrilevante potrebbe rendere più interessanti i golf ...
Jonathan Allan,

Risposte:



7

JavaScript (ES6), 48 byte

Emette un elenco di numeri interi separati da trattini come stringa.

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

Formattato e commentato

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

Casi test


Bella soluzione alternativa, usando i segni come separatori. Potresti usare bitwsie &per salvare un byte?
Shaggy,

@Shaggy No, non funzionerebbe. Ad esempio: 4%3e 4%5non hanno 1 bit in comune, ma entrambi sono diversi da zero.
Arnauld,

Sì, l'ho appena provato e ho n=5scoperto che non avrebbe funzionato.
Shaggy,

k%~-n&&k%-~ndovrebbe funzionare. bel trucco con il separatore!
Tito,

@Titus Non è importante quando si tratta di golf, ma ... sì, potrebbe essere leggermente più leggibile. :-) (aggiornato)
Arnauld

7

R , 38 35 34 38 byte

3 byte salvati quando mi sono ricordato dell'esistenza della whichfunzione ..., 1 byte salvato grazie a @Rift

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

+4 byte per l'argomento ec=Tquando chiamato come programma completo dasource()

Provalo online!

Spiegazione:

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,])
Rift

Quando si esegue questo come programma completo ( source) questo non stampa nulla. Devi chiamare cat. Vedi questo post su meta .
JAD

@JarkoDubbeldam Abbastanza giusto! Ho sempre lavorato sulla base del fatto che fornisce un output valido su TIO, non ho mai considerato i requisiti di essere un "programma completo".
user2390246

Anche se non ho intenzione di tornare indietro e modificare tutte le mie vecchie risposte per risolvere questo problema!
user2390246

È un po 'vago, perché l'ambiente console di R e snippet di codice è il modo principale di usarlo. Sentiti libero di condividere approfondimenti su quel meta thread che ho collegato. Non ha ricevuto così tanti input.
JAD


5

Ottava , 41 37 byte

Questo funziona anche in MATLAB a proposito. Nessuna funzionalità specifica di Octave subdola :)

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

Provalo online!

Spiegazione:

Invece di creare una matrice quadrata e trovare le due diagonali, ho pensato invece di calcolare direttamente le diagonali. Questo è stato di 17 byte in meno! =)

@(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

Ecco come appare, senza unique:

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

Sì, probabilmente avrei dovuto invertire l'ordine delle diagonali per renderlo più amico dell'uomo.


5

MATL , 6 byte

XytP+f

Provalo online!

Spiegazione

Stesso approccio della mia risposta Octave.

Considera l'input 3come esempio.

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]

L'indicizzazione lineare è colonna maggiore , basata su 1. Per ulteriori informazioni, consultare lo snippet di lunghezza 12 qui .


Cosa significa "trasporre"?
Erik the Outgolfer,

@EriktheOutgolfer Siamo spiacenti, mio ​​cattivo. tè duplicato, non trasporre. Inoltre, ho aggiunto un esempio elaborato
Luis Mendo,

Sorprendente! Mi servirebbero due cicli se volessi farlo.
5

@LuisMendo lo sospettavo, perché trasporre una matrice di identità non ha senso ... hmm, sono riuscito a salvare un byte con il tuo algoritmo.
Erik the Outgolfer,


4

Ottava, 68 54 byte

Grazie a @Stewie Griffin per aver salvato 14 byte!

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

Provalo online!

MATLAB, 68 byte

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

Spiegazione:

@(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 Grazie, Jimi è il mio preferito.
Steadybox,

4

Mathematica, 42 byte

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

Provalo online!

@KellyLowder ha giocato a golf fino a ..

Mathematica, 37 byte

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

e @alephalpha ha gettato via il tavolo!

Mathematica, 34 byte

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

##&@@@Table[{i-#,1-i}+i#,{i,#}]⋃{}&è più corto di 5 byte
Kelly Lowder il

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




2

C # (.NET Core) , 97 83 byte

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

Provalo online!

Il cambiamento qui si basa sullo spostamento tra i numeri da trovare. I due turni che iniziano da 0 sono n-1e n+1, quindi n=5, se i numeri per n-1sarebbero 0,4,8,12,16,20e per n+1sarebbero 0,6,12,18,24. Combinando questi e dando 1-indicizzazione (invece di 0-indicizzazione) si ottiene 1,5,7,9,13,17,19,21,25. L'offset da nviene ottenuto mediante negazione bit a bit (operazione di complemento bit a bit), dove ~-n==n-1e-~n==n+1 .

Vecchia versione

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

Provalo online!

Questo approccio utilizza gli indici di colonna e riga per determinare se i numeri si trovano sulle diagonali. i/nfornisce l'indice di riga e i%nfornisce l'indice di colonna.

Restituzione solo della matrice numerica

Se si ritiene che la costruzione della sola serie numerica contenga ai fini del costo in byte, è possibile eseguire le seguenti operazioni, in base al suggerimento di Dennis.Verweij (using System.Linq; aggiunge altri 18 byte):

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

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

Provalo online!


puoi ridurre il codice eliminando il costo aggiuntivo &. Il supplemento &è lì solo per interrompere il confronto se il primo input è falso MSDN
Dennis.Verweij

infatti puoi avere 92 byte usando Linq Provalo online!
Dennis.Verweij,

@ Dennis.Verweij Neat, non ero sicuro di quanto potessi passare all'intestazione o al piè di pagina in TIO. Mi divertirò con il mio.
Ayb4btu,

devi ricordare di includere 18 byte per il riferimento a linq (usando System.Linq;) che è sfortunato, ma come funziona: S
Dennis.Verweij

Ah ok. Ma non è necessario using System;? (Suppongo che avvolgerlo in un namespace System.Linqnon sia valido?)
Ayb4btu,

2

Javascript, 73 63 byte

vecchia versione

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

Salvato 10 byte grazie a @Shaggy

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

Prima volta a giocare a golf! spero che non abbia sbagliato troppo.


Benvenuto in PPCG :) Una soluzione simile a quella su cui stavo lavorando (solo la mia è indicizzata 0). Potresti essere in grado di salvare alcuni byte usando quanto segue nella tua filterfunzione: !(--x%(n+1)&&x%(n-1))e creando il tuo array in questo modo:[...Array(n*n+1).keys()]
Shaggy

@Shaggy Grazie! Cercherò di migliorare la risposta con il tuo suggerimento non appena torno a casa dal lavoro!
Marco Lepore,

Prego. A proposito: " è un po 'più breve della creazione di un [1...n*n]intervallo conArray(n*n).fill().map((x,i)=>i+1) " - [...Array(n*n)].map((_,y)=>y+1)è un modo più breve di farlo, per riferimento futuro.
Shaggy,

Ha fatto un po 'di più e ha finito con questo per 56 byte:n=>[...Array(n*n+1).keys()].filter(x=>!(--x%-~n&&x%~-n))
Shaggy,

@Shaggy Ho provato la tua ultima versione ma avrebbe prodotto uno zero in più per f (1) ef (2), funziona con un intervallo [1 ... n * n], quindi ho usato il modo in cui mi hai mostrato commento precedente. O forse ho incasinato in qualche modo?
Marco Lepore


1

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

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

Provalo online!


`-N` non dovrebbe essere +3?
sergiol

1
No. La riga di comando presunta è perl -e. La riga di comando per questo esempio sarebbe perl -ne. Questa è una differenza di +1.
Xcali,


1

Japt , 16 byte

Non riesco a fare di meglio, ma sono sicuro che sia possibile. Ho dovuto sacrificare 2 byte per il requisito inutile che usiamo l'indicizzazione 1.

²õ f@´XvUÉ ªXvUÄ

Provalo



0

PHP, 56 54 + 1 byte

+1 byte per -Rflag

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

stampa i numeri preceduti da trattini. Esegui come pipe -nRo provalo online .

richiede PHP 5.6 o successivo per l' **operatore.
Aggiungi un byte per PHP precedente: sostituisci ;$z**.5<$n=$argncon $z=$argn;$z<$n*$n.


0

Rubino, 45 byte

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

Funziona internamente come zero indicizzato. controlla se imodulo n+1o n-1è 0, in tal caso stampai+1 .

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.