Języki niższego poziomu, takie jak C i C ++, w rzeczywistości nie mają pojęcia tablic wielowymiarowych. (Inne niż wektory i tablice dynamiczne) Gdy tworzysz tablicę wielowymiarową za pomocą
int foo[5][10];
To właściwie tylko cukier syntaktyczny . To, co tak naprawdę robi C, to utworzenie pojedynczej ciągłej tablicy 5 * 10 elementów. To
foo[4][2]
jest także cukrem syntaktycznym. To naprawdę odnosi się do elementu w
4 * 10 + 2
lub 42 element. Ogólnie rzecz biorąc, indeks elementu [a][b]
w tablicy foo[x][y]
wynosi
a * y + b
Ta sama koncepcja dotyczy tablic 3d. Jeśli mamy foo[x][y][z]
i uzyskujemy dostęp do elementu [a][b][c]
, to naprawdę uzyskujemy dostęp do elementu:
a * y * z + b * z + c
Ta koncepcja dotyczy tablic n- wymiarowych. Jeśli mamy tablicę z wymiarami D1, D2, D3 ... Dn
i uzyskujemy dostęp do elementu, S1, S2, S3 ... Sn
formuła jest następująca
(S1 * D2 * D3 ... * Dn) + (S2 * D3 * D4 ... * Dn) + (S3 * D4 ... * Dn) ... + (Sn-1 * Dn) + Sn
Wyzwanie
Musisz napisać program lub funkcję, która oblicza indeks tablicy wielowymiarowej zgodnie z powyższą formułą. Dane wejściowe będą mieć dwie tablice. Pierwsza tablica to wymiary, a druga tablica to indeksy. Długość tych dwóch tablic będzie zawsze równa i co najmniej 1.
Możesz bezpiecznie założyć, że każda liczba w tablicach będzie nieujemną liczbą całkowitą. Możesz również założyć, że nie dostaniesz się 0
do tablicy wymiarów, chociaż 0
może być w indeksach. Możesz również założyć, że indeksy nie będą większe niż wymiary.
Przetestuj IO
Dimensions: [5, 10]
Indices: [4, 2]
Output: 42
Dimensions: [10, 10, 4, 62, 7]
Indices: [1, 2, 3, 4, 5]
Output: 22167
Dimensions: [5, 1, 10]
Indices: [3, 0, 7]
Output: 37
Dimensions: [6, 6, 6, 6, 6, 6, 6, 6, 6, 6]
Indices: [3, 1, 5, 5, 3, 0, 5, 2, 5, 4]
Output: 33570178
źródło
int[10]
.Odpowiedzi:
APL, 1 bajt
Przetestuj na TryAPL .
źródło
J, 2 bajty
Tam, gdzie jest APL, tam jest J! Rodzaj. Przyjmuje wymiary jako lewy arg i indeksuje jako prawy arg. „Indeksowanie tablicy wielowymiarowej jest zasadniczo mieszaną konwersją zasad”.
źródło
JavaScript (ES6), 34 bajty
Z pewnością
reduce
musi być lepszy niżmap
.źródło
Python, 43 bajty
Przetestuj na Ideone .
źródło
Galaretka ,
76 bajtówWypróbuj online! lub zweryfikuj wszystkie przypadki testowe .
Jak to działa
źródło
Pyth, 10 bajtów
Wypróbuj online: pakiet demonstracyjny lub testowy
Zastosowanie metody Hornera do obliczenia indeksu.
źródło
MATL , 9 bajtów
Wykorzystuje to indeksowanie 1 (teraz dozwolone przez wyzwanie), co jest naturalnym wyborem w MATL.
Aby porównać z przypadkami testowymi w wyzwaniu, dodaj
1
do każdego wpisu w wektorze indeksu wejściowego i odejmij1
od wyniku.Wypróbuj online!
Wyjaśnienie
Kod oparty jest na wbudowanej
X]
funkcji, która konwertuje wskaźniki wielowymiarowe na pojedynczy, liniowy indeks (taki jaksub2ind
funkcja Matlaba lub Octave'a ).źródło
Julia,
2927 bajtówWypróbuj online!
źródło
MATL , 11 bajtów
Korzysta z indeksowania opartego na 0, tak jak w oryginalnym wyzwaniu.
Wypróbuj online!
Wyjaśnienie
Kod wyraźnie wykonuje wymagane pomnożenia i uzupełnienia.
źródło
Python, 85 bajtów
Prawdopodobnie uda mi się skopać tyłek lepszym golfistom pythonowym.
źródło
Python 3.5, 69
Przetestuj tutaj
źródło
Haskell, 34 bajty
Przykład użycia:
[10,10,4,62,7] # [1,2,3,4,5]
->22167
.Jak to działa:
źródło
C ++, 66 bajtów
Szybkie makro:
Użyj jak:
Może to być trochę nadużycie zasad. Tworzy tablicę o podanym rozmiarze, a następnie sprawdza, jak daleko dane indeksy przesunęły wskaźnik. Wyjścia do STDOUT.
To takie brudne ... Ale uwielbiam fakt, że to jest ważne.
źródło
Mathematica, 27 bajtów
Nienazwana funkcja, która przyjmuje listę indeksów jako pierwszy argument, a listę wymiarów jako drugi. Bazując na tej samej obserwacji, co odpowiedź APL Dennisa, obliczenie indeksu jest tak naprawdę tylko konwersją o mieszanej podstawie.
źródło
Oktawa,
5854 bajtówDzięki @AlexA. za jego sugestię, która usunęła 4 bajty
Wejścia i wyjścia są oparte na 1. Aby porównać z przypadkami testowymi, dodaj
1
ot każdego wpisu na wejściu i odejmij1
od wyniku.To anonimowa funkcja. Aby go wywołać, przypisz go do zmiennej.
Wypróbuj tutaj .
Wyjaśnienie
To działa przez rzeczywiście buduje wielowymiarowy array (
reshape(...)
), wypełnioną wartościami1
,2
... w porządku liniowego (1:prod(d)
), a następnie indeksowanie z indeksem wielowymiarowej uzyskać wartość corrresponding.Indeksowanie odbywa się poprzez konwersję wejściowego indeksu wielowymiarowego
i
na tablicę komórek (num2cell(...)
), a następnie na listę oddzieloną przecinkami ({:}
).Dwie
flip
operacje są potrzebne do dostosowania kolejności wymiarów od C do Octave.źródło
reshape
? To nie jest składniowe w Matlabie, ale zaakceptowane w Octave. Działa jako indeks@(...) ...
w pierwszym wierszu mojego kodu, a następnief = ans;
w drugim. To sprawia, że długość pierwszego wiersza jest równa liczbie bajtów do zgłoszenia.CJam, 7 bajtów
Wypróbuj online!
Jak to działa
źródło
Haskell, 47 bajtów
Dwa rozwiązania o równej długości:
Nazywane tak:
((sum.).s)[4,2][5,10]
.Oto wersja poprawki:
źródło
Oktawy,
47/43/31 bajtów@(d,i)sub2ind(flip(d),num2cell(flip(i+1)){:})-1
Sprawdź to tutaj .
Powiedziawszy to, zgodnie z pytaniem w komentarzu , indeksowanie 1 było powiedziane, że jest OK, gdy jest to naturalne dla używanego języka. W takim przypadku możemy zapisać 4 bajty:
@(d,i)sub2ind(flip(d),num2cell(flip(i)){:})
Analogicznie twierdzę, że jeśli celem kodu jest liniowe indeksowanie tablicy w tym języku , całe odwracanie i uwzględnianie głównego porządku kolumny MATLAB / Octave również nie powinno być konieczne. W takim przypadku moje rozwiązanie staje się
@(d,i)sub2ind(d,num2cell(i){:})
Przetestuj tutaj .
źródło
Mathematica, 47 bajtów
(Unicode to U + F3C7 lub
\[Transpose]
.) W tym celu przepisałem wyrażenie jako D n ( D n -1 (⋯ ( D 3 ( D 2 S 1 + S 2 ) + S 3 ) ⋯) + S n -1 ) + S n . Jest tylkoFold
funkcja na obu listach.źródło
Właściwie 13 bajtów
Wypróbuj online!
Ten program przyjmuje listę wskaźników jako pierwsze dane wejściowe, a listę wymiarów jako drugie dane wejściowe.
Wyjaśnienie:
źródło
Rakieta 76 bajtów
Nie golfowany:
Testowanie:
Wydajność:
źródło
C #, 73 bajty
Pełny program z przypadkami testowymi:
źródło
Perl 6, 39 bajtów
Raczej naiwny golf, po prostu zniszczył anonimowy okręt podwodny.
Perl 6 ma anonimową zmienną stanu,
$
która jest przydatna do tworzenia licznika w pętli (np. Przy użyciu przyrostu$++
lub przyrostu++$
). Wstępnie zwiększam tę zmienną stanu, aby zwiększać indeks początkowy wycinka tablicy wymiarów wewnątrz mapy.Oto niepoznana funkcja, która tworzy listy podrzędne
Następnie wystarczy ograniczyć listę podrzędną za pomocą
×
operatora mnożenia ( ) isum
wprowadzić wyniki.źródło
Perl, 71 bajtów
Nie golfowany:
źródło
C ++ 17,
133115 bajtów-18 bajtów do użycia
auto...
Nie golfowany:
Stosowanie:
Alternatywnie, tylko funkcje, 116 bajtów
Nie golfowany:
Stosowanie:
źródło