Выходные диагональные позиции меня в квадрате


18

Для заданного числа nвыведите упорядоченный список индексов на основе 1, попадающих на одну из диагоналей n*nквадратной матрицы.

Пример:

Для ввода 3:

Квадрат должен быть:

1 2 3
4 5 6
7 8 9

Теперь мы выбираем все индексы, представленные \, /или X( #или недиагональные позиции отклоняются)

\ # /
# X #
/ # \

Выход должен быть:

[1,3,5,7,9]

Тестовые случаи:

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]

Там не будет принятого ответа. Я хочу знать самый короткий код для каждого языка.


1
Вопрос состоит в том, чтобы задавать (1-индексированные) индексы символов \, / и X на изображениях. Неплохой вопрос как таковой, но не имеющий объяснения.
Арфи

Если вы готовы дать краткое и четкое объяснение того, что вы хотите, мы, вероятно, вновь откроем это, поскольку это не плохой вызов. На данный момент, это просто очень неясно
г-н Xcoder

Я проголосовал за повторное открытие, хотя вы также можете переместить изображения ascii из области примеров, чтобы избежать путаницы. Сначала я не был уверен, должен ли я их производить (но я понимаю, что требуемый результат - это только список индексов)
Арфи

7
Имеет ли значение заказ?
г-н Xcoder

9
FWIW Я думаю, что заказ не имеет значения, может сделать для более интересных гольфов ...
Джонатан Аллан

Ответы:



7

JavaScript (ES6), 48 байт

Выводит разделенный дефисом список целых чисел в виде строки.

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

Отформатировано и прокомментировано

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

Контрольные примеры


Хороший обходной путь, используя знаки в качестве разделителей. Не могли бы вы использовать bitwsie &для сохранения байта?
Лохматый

@ Шэгги Нет, это не сработает. Например: 4%3и не 4%5имеют 1-битного общего, но оба ненулевые.
Arnauld

Да, просто проверил это n=5и заметил, что это не сработает.
Лохматый

k%~-n&&k%-~nдолжно сработать. хороший трюк с разделителем!
Титус

@ Titus Не то, чтобы это действительно имело значение, когда дело доходит до игры в гольф, но ... да, это может быть немного более читабельным. :-) (обновлено)
Arnauld

7

R , 38 35 34 38 байт

3 байта сохранены, когда я вспомнил о существовании whichфункции ..., 1 байт сохранен благодаря @Rift

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

+4 байта для аргумента ec=Tпри вызове полной программыsource()

Попробуйте онлайн!

Объяснение:

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 байтd=diag(n<-scan());which(d|d[n:1,])
Rift

При запуске в качестве полной программы ( source) это ничего не печатает. Вы должны позвонить cat. Смотрите этот пост на мета .
JAD

@JarkoDubbeldam Достаточно справедливо! Я всегда работал на том основании, что он дает достоверный вывод на TIO, никогда не задумывался над тем, чтобы быть «полной программой».
user2390246

Хотя я не планирую возвращаться и редактировать все мои старые ответы, чтобы это исправить!
user2390246

Это немного расплывчато, потому что консольное окружение R и фрагменты кода являются основным способом его использования. Не стесняйтесь делиться мнениями о той мета-нити, которую я связал. Он не получил столько информации.
JAD


5

Октава , 41 37 байт

Это работает в MATLAB тоже кстати. Никакого подлого октавского специфического функционала :)

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

Попробуйте онлайн!

Объяснение:

Вместо того чтобы создать квадратную матрицу и найти две диагонали, я решил вместо этого вычислить диагонали напрямую. Это было на 17 байт короче! знак равно

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

Вот как это выглядит без unique:

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

Да, наверное, мне следовало изменить порядок диагоналей, чтобы сделать его более удобным для человека.


5

MATL , 6 байтов

XytP+f

Попробуйте онлайн!

объяснение

Тот же подход, что и в моем ответе от Octave.

Рассмотрим ввод 3в качестве примера.

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]

Линейное индексирование является главным по столбцу , основано на 1. Для получения дополнительной информации см. Фрагмент длины 12 здесь .


Что значит «транспонировать»?
Эрик Outgolfer

@EriktheOutgolfer Извините, мой плохой. tявляется дубликатом, а не транспонировать. Также я добавил отработанный пример
Луис Мендо

Удивительный! Мне понадобится две петли, если я хочу это сделать.
mr5

@ LuisMendo Я так и подозревал, потому что транспонировать матрицу тождеств не имеет смысла ... хм, мне удалось сохранить байт с помощью вашего алгоритма.
Эрик Outgolfer


4

Октава, 68 54 байта

Спасибо @Stewie Griffin за сохранение 14 байтов!

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

Попробуйте онлайн!

MATLAB, 68 байт

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

Объяснение:

@(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 Спасибо, Джими мой любимый.
Steadybox

4

Mathematica, 42 байта

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

Попробуйте онлайн!

@KellyLowder играл в гольф до ...

Mathematica, 37 байт

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

и @alephalpha выбросил стол!

Mathematica, 34 байта

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

##&@@@Table[{i-#,1-i}+i#,{i,#}]⋃{}&на 5 байт короче
Келли Лоудер

Union@@Range[{1,#},#^2,{#+1,#-1}]&
алефальфа




2

C # (.NET Core) , 97 83 байта

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

Попробуйте онлайн!

Изменение здесь основано на сдвиге между числами, чтобы найти. Две смены, начинающиеся с 0, n-1и n+1, поэтому, если n=5бы числа для n-1были бы 0,4,8,12,16,20и для n+1были бы 0,6,12,18,24. Объединяя их и давая 1-индексацию (вместо 0-индексации), дает 1,5,7,9,13,17,19,21,25. Смещение от nдостигается с помощью побитового отрицания (операция побитового дополнения), где ~-n==n-1и -~n==n+1.

Старая версия

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

Попробуйте онлайн!

Этот подход использует индексы столбцов и строк для определения того, находятся ли числа на диагонали. i/nдает индекс строки и i%nдает индекс столбца.

Возврат только числового массива

Если считается, что построение только массива чисел учитывается в байтовой стоимости, то можно сделать следующее, основываясь на предложении Dennis.Verweij ( using System.Linq;добавляет дополнительные 18 байтов):

C # (.NET Core) , 66 + 18 = 84 байта

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

Попробуйте онлайн!


Вы можете уменьшить код, избавившись от лишнего &. Дополнительное &есть только для того, чтобы прервать сравнение, если первый вход ложный MSDN
Dennis.Verweij

на самом деле вы можете иметь 92 байта, используя Linq Попробуйте онлайн!
Dennis.Verweij

@ Dennis.Verweij Аккуратно, я не был уверен, насколько я мог бы перейти к верхнему или нижнему колонтитулам в TIO. Я поиграю с моим.
Ayb4btu

Вы должны не забыть включить 18 байтов для ссылки на linq (используя System.Linq;), что, к сожалению, но как это работает: S
Dennis.Verweij

Ах хорошо. Но это не обязательно для using System;? (Я предполагаю, что завернуть это в namespace System.Linqнедопустимо?)
Ayb4btu

2

Javascript, 73 63 байта

старая версия

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

Сохранено 10 байтов благодаря @Shaggy

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

Первый раз в гольф! Надеюсь, я не слишком испортил это.


Добро пожаловать в PPCG :) Решение, похожее на то, над которым я работал (только мое 0-проиндексировано). Возможно, вы сможете сэкономить несколько байтов, используя в своей filterфункции следующее: !(--x%(n+1)&&x%(n-1))и создав свой массив следующим образом:[...Array(n*n+1).keys()]
Shaggy

@ Shaggy Спасибо! Я постараюсь улучшить ответ с вашим предложением, как только я вернусь с работы!
Марко Лепор

Пожалуйста. Кстати, « это немного короче, чем создание [1...n*n]диапазона с помощьюArray(n*n).fill().map((x,i)=>i+1) » - [...Array(n*n)].map((_,y)=>y+1)это более короткий способ сделать это для дальнейшего использования.
Лохматый

Сделал немного больше и закончил с этим для 56 байтов:n=>[...Array(n*n+1).keys()].filter(x=>!(--x%-~n&&x%~-n))
Shaggy

@ Shaggy Я попробовал вашу последнюю версию, но она выдает дополнительный ноль для f (1) и f (2), она работает с диапазоном [1 ... n * n], поэтому я использовал способ, который вы показали мне в предыдущий комментарий Или, может, я все испортил?
Марко Лепор


1

Perl 5 , 56 + 1 (-n) = 57 байт

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

Попробуйте онлайн!


Не должно быть `-n` +3?
sergiol

1
Предполагаемая командная строка perl -e . Командная строка для этого примера будет perl -ne. Это разница +1.
Xcali


1

Japt , 16 байт

Кажется, не может быть лучше, чем это, но я уверен, что это возможно. Пришлось пожертвовать 2 байта за ненужное требование, чтобы мы использовали 1-индексирование.

²õ f@´XvUÉ ªXvUÄ

Проверь это



0

PHP, 56 54 + 1 байт

+1 байт за -Rфлаг

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

печатает числа, начинающиеся с тире. Выполнить как трубу с -nRили попробуйте онлайн .

требует PHP 5.6 или более поздней версии для **оператора.
Добавьте один байт для старого PHP: Замените ;$z**.5<$n=$argnна $z=$argn;$z<$n*$n.


0

Рубин, 45 байт

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

Работает внутри с нулями. проверяет, по iмодулю n+1или n-10, если это так, печатает i+1.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.