Самоидентифицирующиеся координаты


27

Напишите программу или функцию, которая, учитывая целое число n, создает массив с nизмерениями nдлины, где каждый элемент является идентификатором своих собственных координат. То есть, начиная с одного массива, заполняйте его nмассивами, каждый из которых содержит nбольше массивов, вплоть до глубины n-1. Элементами самых глубоких массивов являются координаты, описывающие, где они находятся в полном массиве.

Несколько примеров на случай, если мое объяснение сбивает с толку.

n = 1

["1"]

п = 2

[
 ["11", "12"],
 ["21", "22"]
]

n = 3

[
  [
    ["111","112","113"],
    ["121","122","123"],
    ["131","132","133"]
  ],
  [
    ["211","212","213"],
    ["221","222","223"],
    ["231","232","233"]
  ],
  [
    ["311","312","313"],
    ["321","322","323"],
    ["331","332","333"]
  ]
]

Здесь «321» означает, что это 1-й элемент 2-го элемента 3-го массива.

Правила:

  • Координаты и измерение ( n) могут быть проиндексированы либо 0, либо 1
  • Вы можете предположить, что nэто одна цифра, ниже 10 для обоих вариантов индексирования, чтобы предотвратить неоднозначные результаты
  • IO гибкий.
    • В частности, координаты могут быть массивами, строками и т. Д., Если они свободны. "321" => [3,2,1]
    • Выходные данные могут быть целыми числами в базе 10 с или без начальных нулей.
    • Координаты могут быть в обратном порядке, если вы хотите, если это не противоречит. "321" => "123"
    • Вывод не обязательно должен быть структурой массива на вашем языке. Пока есть четкие четкие маркеры для начала массива, конца массива и для разделения элементов.
    • Выход для n=1может быть просто 1
    • Если ваш вывод нетипичен, обязательно объясните формат.
  • Это поэтому выигрывает самое короткое решение на каждом языке!


У меня были проблемы с написанием этого на Хаскеле, прежде чем я понял, что система типов делает это невозможным.
Пшеничный волшебник

@CatWizard: вы всегда можете определить новую структуру данных, чтобы обойти это, например. data L a = L [L a] | E a,
მოიმო


1
@ToddSewell У вас не может быть функции, тип которой зависит от ввода. Эта функция может иметь тип Int -> [String]или Int -> [[String]]и так далее, в зависимости от того, что является вводом
H.PWiz

Ответы:





6

J , 18 байт

,"1/^:(]{:)~@,.@i.

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

Итеративное решение, нет встроенного декартова произведения. Вот как выглядит пик J.

                       input                                    2
                i.     range                                 0, 1
             ,.@       reshape each element
                       into a one-dimensional array        [0],[1]   (A)
    ^:(]{:)            (input−1) times...             (1 iteration)
,"1/       ~@             prepend the contents of each 1d array in A    |
                          to every 1d array from the previous iteration,|  
                          assembling the results for each A[n] into     |!CANTEXPLAINTHIS!
                          a larger array                                |
                                                         [ [0,0],       |
                                                           [0,1] ],     |
                                                         [ [1,0],       |
                                                           [1,1] ]      |

Сначала большое количество байтов меня оттолкнуло, но это действительно прекрасно. J
Иона

6

Желе , 8 7 байт

ṗ³s³$³¡

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

объяснение

Используйте аргумент 2 в качестве примера.

ṗ³s³$³¡   
ṗ        Cartesian power with power
 ³       2 (the argument). Autoranges the left arg.
         Yields [[1,1],[1,2],[2,1],[2,2]]
    $³¡  Do 2 times:
  s³     Split into segments of length 2. 
         This last step molds the array of indices into the proper shape.

Если бы ¡он не менялся, это правильный аргумент для итераций для диад, тогда это было бы 4 байта:ṗs³¡


Это похоже на полную программу для меня. Вы уверены, что вывод (STDOUT) для 1действителен?
Эрик Outgolfer

@EriktheOutgolfer Я в порядке с выходом для 1
Джо Кинг

@JoKing Но, в этом случае, нет «четких четких маркеров начала массива, конца массива». Хотите отредактировать вопрос? (многие ответы на самом деле не содержат их)
Эрик Outgolfer

5

J, 13 байт

[:{[;/@$,:@i.

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

Интересно, что это намного дольше, чем ответ APL (хотя это может быть моей неспособностью увидеть лучший перевод)

объяснение

[: { [ ;/@$ ,:@i.


     [                NB. the argument
            ,:@i.     NB. range 0..arg, considered as one item: ,: is "itemize" 
          $           NB. repeat the right range the left number of times
       ;/@            NB. and then put boxes around them. so, eg, if we had
                      NB. an arg of 3, now we have the list of boxes 
                      NB. [0 1 2][0 1 2][0 1 2]
[: {                  NB. { is "Catalog", it creates the cartesian product
                      NB. in exactly the format we desire.


@FrownyFrog Использование ловушки, чтобы избежать #.inv, очень умно, +1.
Коул

@FrownyFrog Теперь, когда я посмотрел на ваше решение «подсчитать в разных базах», я думаю, что подход достаточно отличается, поэтому вы должны добавить его в качестве другого поста самостоятельно. Это очень хорошее решение.
Иона

Иона, спасибо @cole
FrownyFrog

5

MATLAB, 92 89 55 байтов

У меня есть другой ответ, перечитав правила соревнования, но я оставлю предыдущую попытку ниже, так как на нее по-прежнему интересно смотреть.

reshape(string(dec2base(0:n^n-1,n+(n<2))),[~(1:n)+n 1])

объяснение

                        0:n^n-1                        % [0,1,...,n^n-1]
               dec2base(       ,n+(n<2))               % Put into base n (base 2 if n=1)
        string(                         )              % Convert to strings
                                          [~(1:n)+n 1] % Dimension array [n,n,...,n] (length n)
reshape(                                 ,            )% Use dim array to reshape

Это выводит n-мерный массив строк, которые проиндексированы 0.

Предыдущий ответ (89 байт)

Мой первый гольф! Это, вероятно, может быть уменьшено больше, но я думал, что выложу то, что у меня есть.

x=(1:n)';for d=2:n;y=((1:n)*10^(d-1));o=[];for p=1:nnz(y);o=cat(d,o,(x+y(p)));end;x=o end

объяснение

x=(1:n)';                       % Create array x=[1,2,...n]'
for d=2:n                       % d for dimension
    y=((1:n)*10^(d-1));         % Creates an array for each d where
                                %   y=[10,20,30,...] for n=2
                                %   y=[100,200,...] for n=3 etc.
    o=[];                       % o for output
    for p=1:nnz(y)              % For each value of y
        o=cat(d,...             % Concatenate in the dth dimension:
            o,...               % - The current output
            x+y(p));            % - The sum of
                                %   - The array from the last dimension
                                %   - The current value in y (e.g. 100)
    end
    x=o                         % Send the output to x for the next loop
end

Вывод x в конце, чтобы дать решение

Как и в других сообщениях MATLAB, выходные данные представляют собой n-мерный массив, за исключением того, что для отображения координат используются числа. Он работает для любого значения, хотя из-за плохих циклов в MATLAB он начинает значительно замедляться около n = 8.

Изменить: -2 байта благодаря Луису Мендо. Также убрана последняя точка с запятой для вывода на печать.


4
Добро пожаловать в PPCG!
Мохнатый

Я думаю, что вы можете заменить length, nnzчтобы сохранить несколько байтов. Кроме того, согласно правилам PPCG, код должен генерировать некоторый фактический вывод, обычно отображая его в STDOUT (недостаточно, чтобы вывод был сохранен в переменной), или это должна быть функция, которая возвращает вывод
Луис Мендо

5

Ржавчина ,201 176 167 166 154 байта

enum L{S(String),L(Vec<L>)}fn
h(n:u8,d:u8,s:&str)->L{if
d<1{L::S(s.into())}else{L::L((0..n).map(|i|h(n,d-1,&format!("{}{}",s,i))).collect())}}|n|h(n,n,"")

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

Тип вывода является типом суммы с двумя вариантами, поскольку язык строго типизирован. Это может быть либо Lтип списка, содержащий этот тип суммы, либо Sтип результата (строка). Результат может выглядеть так.

L::L([
 L::L([ L::S("00"), L::S("01") ]),
 L::L([ L::S("10"), L::S("11") ]),
])

Также переформатирован с использованием rustfmt:

enum L {
    S(String),
    L(Vec<L>),
}
fn h(n: u8, d: u8, s: &str) -> L {
    if d < 1 {
        L::S(s.into())
    } else {
        L::L(
            (0..n)
                .map(|i| h(n, d - 1, &format!("{}{}", s, i)))
                .collect(),
        )
    }
}
|n| h(n, n, "")

4

R , 102 байта

function(n,m=array(T,rep(n,n)))`if`(n<2,'1',{m[]=apply(which(m,T)[,`[<-`(1:n,1:2,2:1)],1,toString);m})

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

  • 1-индексированный, обратный
  • к сожалению, R хранит матрицу за столбцом, в противном случае мы можем уменьшить размер до 73 байт.
  • -9 байтов сохранено благодаря предложению @Giuseppe использовать whichиндексирование массива

Ваш 76-байтовый ответ может быть 73 байта, как я его реализовал перед проверкой, чтобы увидеть, был ли уже ответ R. Вы могли бы изменить некоторые подходы, хотя? Не совсем уверен.
Джузеппе

1
@Giuseppe: индексирование массивов which- это то, что я искал, спасибо! Сохранено 9 байт
digEmAll

4

Java 10, 144 байта

Решение - метод f. Это производит строковое представление массива.

String h(int n,int d,String s){if(d<1)return s;var r="[";for(int i=0;i++<n;)r+=h(n,d-1,s+i)+",";return r+"]";}String f(int n){return h(n,n,"");}

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

Ungolfed

String h(int n, int d, String s) {
    if (d < 1)
        return s;
    var r = "[";
    for (int i = 0; i++ < n;)
        r += h(n, d - 1, s + i) + ",";
    return r + "]";
}
String f(int n) {
    return h(n, n, "");
}

Подтверждения


1
В Java 10 вы можете заменить Object[]на var. Кроме того, я думаю, что этот elseблок не нужен, как у вас returnв ifблоке.
Конрад Боровски



3

MATLAB, 116 108 104 байта

Я чувствую, что должен быть более короткий способ сделать это, учитывая склонность MATLAB к многомерным матрицам ... Спасибо Луису за 4 байта из-за некоторой краткости

a=~(1:n)+n;c=cell(1,n);[c{:}]=ind2sub(a,1:n^n);reshape(arrayfun(@(varargin)[varargin{:}],c{:},'un',0),a)

объяснение

% For using twice, define the array of dimension sizes [n, n, .., n]
a=~(1:n)+n;
% To group variable number of outputs from ind2sub into a cell array
c=cell(1,n);   
% Convert linear indices to self-describing coordinates
[c{:}]=ind2sub(a,1:n^n);     
% reshape to make it the n-dimensional array
% arrayfun to loop over the numerous ind2sub outputs simultaneously
% varargin and {:} usage to account for various numbers of inputs
reshape(arrayfun(@(varargin)[varargin{:}],c{:},'uni',0),a)

Выходными данными является n-мерный массив ячеек, где каждый элемент является массивом значений координат. Работает для любого nбез двусмысленности из-за числового вывода массива, при условии, что n^(n+1)массив элементов может быть сохранен в RAM!


3

Древесный уголь , 26 байт

Nθ≔EXθθ⪫⪪◧⍘ιθθ ¦0υFθ≔⪪υθυυ

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

Nθ

Вход n.

≔EXθθ⪫⪪◧⍘ιθθ ¦0υ

Генерация всех nⁿ n-значных чисел в базе n.

Fθ≔⪪υθυ

Разделите их nраз в n-мерный массив, где каждое измерение имеет размер n.

υ

Распечатать массив. Формат вывода по умолчанию - каждый элемент в отдельной строке, затем каждый блок nстрок заканчивается пустой строкой, затем каждый блок nблоков nстрок заканчивается второй пустой строкой, и так далее, вплоть до n-1пустых строк на верхнем уровне. ,


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