Координати самовизначення


27

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

Деякі приклади, якщо моє пояснення було заплутаним.

n = 1

["1"]

n = 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
    • Якщо ваш вихід нетиповий, обов'язково поясніть формат.
  • Це тому найкоротше рішення на кожній мові виграє!

Пісочниця (видалено)
Jo King

У мене були проблеми з написанням цього в Haskell, перш ніж я зрозумів, що система типу робить це неможливим.
Пшеничний майстер

@CatWizard: Ви завжди можете визначити нову структуру даних, щоб обійти це, наприклад. data L a = L [L a] | E a.
ბიმო


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

Відповіді:



10

Python 3 , 56 байт

f=lambda n,*l:len(l)//n*l or[f(n,*l,k)for k in range(n)]

Спробуйте в Інтернеті!

Містер Xcoder врятував 2 байти, перейшовши на Python 3 для розпакування зірки.


3
Якщо ви перейдете на Python ≥3,5, він f=lambda n,*l:len(l)//n*l or[f(n,*l,k)for k in range(n)]працює на 56 байт.
Містер Xcoder


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дійсний?
Ерік Аутгольфер

@EriktheOutgolfer Я добре з виходом на 1
Jo King

@JoKing Але в цьому випадку немає "чітких чітких маркерів для початку масиву, кінця масиву". Ви хочете відредагувати питання? (багато відповідей насправді не містять їх)
Ерік Вихідний,

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 Тепер, коли я переглянув ваше рішення "підрахунок у різних базах", я думаю, що підхід досить інший, що ви повинні додати його як інший пост самостійно. Це дуже приємне рішення.
Йона

Jonah, @cole спасибі
FrownyFrog

5

МАТЛАБ, 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

Виводить х в кінці, щоб дати рішення

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

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


4
Ласкаво просимо до PPCG!
Shaggy

Я думаю, ви можете замінити 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,"");}

Спробуйте це в Інтернеті

Безумовно

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)масив елементів може зберігатися в ОЗП!


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.