एक बहुआयामी सरणी का सूचकांक


28

निचले स्तर की भाषाएँ, जैसे C और C ++ में वास्तव में बहुआयामी सरणियों की कोई अवधारणा नहीं है। (वैक्टर और गतिशील सरणियों के अलावा) जब आप एक बहुआयामी सरणी बनाते हैं

int foo[5][10];

यह वास्तव में सिंटैक्टिक शुगर है । C जो वास्तव में करता है वह 5 * 10 तत्वों का एक एकल सन्निहित सरणी बनाता है । यह

foo[4][2]

सिंटैक्टिक शुगर भी है। यह वास्तव में तत्व को संदर्भित करता है

4 * 10 + 2

या, 42 वाँ तत्व। सामान्य तौर पर, [a][b]सरणी में तत्व का सूचकांक foo[x][y]होता है

a * y + b

यही अवधारणा 3 डी सरणियों पर लागू होती है। यदि हमारे पास है foo[x][y][z]और हम तत्व [a][b][c]तक पहुँचते हैं तो हम वास्तव में पहुँच वाले तत्व हैं:

a * y * z + b * z + c

यह अवधारणा एन -डायमेंशनल एरेज़ पर लागू होती है । यदि हमारे पास आयामों के साथ एक सरणी है D1, D2, D3 ... Dnऔर हम तत्व S1, S2, S3 ... Snको एक्सेस करते हैं तो सूत्र है

(S1 * D2 * D3 ... * Dn) + (S2 * D3 * D4 ... * Dn) + (S3 * D4 ... * Dn) ... + (Sn-1 * Dn) + Sn

चुनौती

आपको एक प्रोग्राम या फ़ंक्शन लिखना होगा जो उपरोक्त सूत्र के अनुसार बहुआयामी सरणी के सूचकांक की गणना करता है। इनपुट दो ऐरे होंगे। पहला सरणी आयाम है, और दूसरा सरणी सूचकांकों है। इन दो सरणियों की लंबाई हमेशा बराबर और कम से कम 1 होगी।

आप सुरक्षित रूप से मान सकते हैं कि सरणियों में प्रत्येक संख्या एक गैर-नकारात्मक पूर्णांक होगी। आप यह भी मान सकते हैं कि आपको 0आयाम सरणी में नहीं मिलेगा , हालांकि सूचकांकों में 0 हो सकता है। आप यह भी मान सकते हैं कि सूचकांक आयामों से बड़ा नहीं होगा।

परीक्षण 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

4
तो यह 0-आधारित अनुक्रमण है, सही है? क्या हम अपनी पसंद की भाषा के लिए अधिक प्राकृतिक होने पर 1-आधारित अनुक्रमणिका का उपयोग कर सकते हैं?
एलेक्स ए

@AlexA। हाँ, यह स्वीकार्य है।
DJMcMayhem

11
दरअसल, सी 'वास्तव में क्या करता है' टाइप के पांच तत्वों का एक एकल सन्निहित सरणी बनाता है int[10]


1
@Hurkyl हाँ, लेकिन उस सरणी में सभी पूर्णांक अभी भी सन्निहित हैं। यह सिर्फ शब्दार्थ है।
DJMcMayhem

जवाबों:


60

एपीएल, 1 बाइट

इसे TryAPL पर टेस्ट करें ।


21
हां इसी तरह। हमें विजेता मिल गया। बाकी सब अब घर जा सकते हैं।
DJMcMayhem

3
क्यों ... यह काम क्यों करता है? o_O
एलेक्स ए

10
@AlexA। एक बहुआयामी सरणी अनुक्रमण अनिवार्य रूप से मिश्रित आधार रूपांतरण है।
डेनिस

21
ओह, देखो, गोल्फ खेलते समय एक छेद!
निधि मोनिका का मुकदमा

8
ज्यादातर समय मैं यहां मौज-मस्ती के लिए आता हूं। फिर ऐसे समय होते हैं जब मैं गलती से गहन अंतर्दृष्टि प्राप्त कर
लेता हूं

11

जे, 2 बाइट्स

#.

जहां एपीएल है, वहां जे है! एक प्रकार का। आयामों को बाएं arg और index को right arg के रूप में लेता है। "एक बहुआयामी सरणी अनुक्रमण अनिवार्य रूप से मिश्रित आधार रूपांतरण है।"


11

जावास्क्रिप्ट (ईएस 6), 34 बाइट्स

(d,a)=>a.reduce((r,i,j)=>r*d[j]+i)

निश्चित रूप reduceसे बेहतर होना चाहिए map


7

पायथन, 43 बाइट्स

f=lambda x,y:x>[]and y.pop()+x.pop()*f(x,y)

Ideone पर इसका परीक्षण करें ।


15
न केवल डेनिस ठोस रूप से हम सभी को रोमांचित करता है, बल्कि वह इसे हर
DJMcMayhem

7

जेली , 7 6 बाइट्स

Ṇ;żḅ@/

इसे ऑनलाइन आज़माएं! या सभी परीक्षण मामलों को सत्यापित करें

यह काम किस प्रकार करता है

Ṇ;żḅ@/  Main link. Arguments: D (list of dimensions), I (list of indices)

Ṇ       Yield 0, the logical NOT of D.
  ż     Zip D with I.
        If D = [10, 10, 4, 62, 7] and I = [1, 2, 3, 4, 5], this yields
        [[10, 1], [10, 2], [4, 3], [62, 4], [7, 5]].
 ;      Concatenate, yielding [0, [10, 1], [10, 2], [4, 3], [62, 4], [7, 5]].
   ḅ@/  Reduce by swapped base conversion to integer.
        [10, 1] in base    0 is    0 × 10 + 1 = 1.
        [10, 2] in base    1 is    1 × 10 + 2 = 12.
        [ 4, 3] in base   12 is   12 ×  4 + 3 = 51.
        [62, 4] in base   51 is   51 × 62 + 4 = 3166.
        [ 7, 5] in base 3166 is 3166 ×  7 + 5 = 22167.


5

MATL , 9 बाइट्स

PiPZ}N$X]

यह 1-आधारित अनुक्रमण (अब चुनौती द्वारा अनुमत) का उपयोग करता है, जो MATL में स्वाभाविक पसंद है।

चुनौती में परीक्षण के मामलों की तुलना करने के लिए, 1इनपुट इंडेक्स वेक्टर में प्रत्येक प्रविष्टि में जोड़ें , और 1आउटपुट से घटाएं ।

इसे ऑनलाइन आज़माएं!

व्याख्या

कोड बिलिन X]फ़ंक्शन पर आधारित है , जो एकल, रैखिक सूचकांक (जैसे मैटलैब या ऑक्टेव के sub2indफ़ंक्शन) के लिए बहुआयामी सूचकांकों को परिवर्तित करता है ।

P      % Take dimension vector implicitly. Reverse
iP     % Take vector of indices. Reverse
Z}     % Split vector into its elements
N$X]   % Convert indices to linear index (`sub2ind` function). Implicitly display


5

MATL , 11 बाइट्स

4L)1hPYpP*s

मूल चुनौती के रूप में, यह 0-आधारित अनुक्रमण का उपयोग करता है।

इसे ऑनलाइन आज़माएं!

व्याख्या

कोड आवश्यक गुणन और परिवर्धन को स्पष्ट रूप से करता है।

4L)    % Take first input array implicitly. Remove its first entry
1h     % Append a 1
PYpP   % Cumulative product from right to left
*      % Take second input array implicitly. Multiply the two arrays element-wise
s      % Sum of resulting array. Implicitly display

4

पायथन, 85 बाइट्स

lambda a,b:sum(b[i]*eval('*'.join(str(n)for n in a[i+1:])or'1')for i in range(len(a)))

मैं शायद अपने बट बेहतर अजगर गोल्फरों द्वारा वहाँ से बाहर निकाल दिया जाएगा।



4

हास्केल, 34 बाइट्स

a#b=sum$zipWith(*)(0:b)$scanr(*)1a

प्रयोग उदाहरण: [10,10,4,62,7] # [1,2,3,4,5]-> 22167

यह काम किस प्रकार करता है:

      scanr(*)1a  -- build partial products of the first parameter from the right,
                  -- starting with 1, e.g. [173600,17360,1736,434,7,1]
    (0:b)         -- prepend 0 to second parameter, e.g. [0,1,2,3,4,5]
  zipWith(*)      -- multiply both lists elementwise, e.g. [0,17360,3472,1302,28,5]
sum               -- calculate sum

4

सी ++, 66 बाइट्स

एक त्वरित मैक्रो:

#include<stdio.h>
#define F(d,i) int x d;printf("%d",&x i-(int*)x)

जैसे उपयोग करें:

int main(){
    F([5][1][10], [3][0][7]);
}

यह नियमों का एक दुरुपयोग हो सकता है। दिए गए आकार के साथ एक सरणी बनाता है, चेक की तुलना में यह देखने के लिए कि दिए गए इंडेक्स सूचक को कितनी दूर तक खींचते हैं। STDOUT में आउटपुट।

यह बहुत गंदा लगता है ... लेकिन मैं सिर्फ इस तथ्य से प्यार करता हूं कि यह वैध है।


3

गणितज्ञ, 27 बाइट्स

#~FromDigits~MixedRadix@#2&

एक अनाम फ़ंक्शन जो सूचकांकों की सूची को पहले तर्क के रूप में लेता है और दूसरे आयामों की सूची को। डेनिस के एपीएल जवाब के रूप में एक ही अवलोकन के आधार पर कि सूचकांक की गणना वास्तव में सिर्फ एक मिश्रित-आधार रूपांतरण है।


3

ऑक्टेव, 58 54 बाइट्स

@AlexA को धन्यवाद। उनके सुझाव के लिए, जिसने 4 बाइट्स निकाले

@(d,i)reshape(1:prod(d),flip(d))(num2cell(flip(i)){:})

इनपुट और आउटपुट 1-आधारित हैं। परीक्षण मामलों के साथ तुलना करने के लिए, 1इनपुट में प्रत्येक प्रविष्टि को जोड़ें और 1आउटपुट से घटाएं ।

यह एक अनाम फ़ंक्शन है। इसे कॉल करने के लिए, इसे एक वैरिएबल पर असाइन करें।

इसे यहाँ आज़माएँ

व्याख्या

यह वास्तव में बहुआयामी सरणी का निर्माण करके काम करता है (reshape(...) ), मूल्यों से भर 1, 2... रेखीय क्रम में ( 1:prod(d)), और फिर बहुआयामी सूचकांक के साथ का अनुक्रमण corrresponding मूल्य मिलता है।

अनुक्रमणिका को इनपुट बहुआयामी सूचकांक iको सेल सरणी ( num2cell(...)) में परिवर्तित करके और फिर अल्पविराम से अलग सूची ( {:}) में किया जाता है।

flipC से अष्टक तक आयामों के क्रम को अनुकूलित करने के लिए दो संक्रियाओं की आवश्यकता है।


पुनर्वसन के पास कोष्ठक की दूसरी जोड़ी क्यों नहीं होती है जो गैर-संश्लिष्ट होती है?
अब्राहम

@ Agawa001 क्या आपके बाद दूसरी जोड़ी का मतलब है reshape? यह मतलाब में गैर-वाक्य्यात्मक है, लेकिन ऑक्टेव में स्वीकार किया जाता है। यह सूचकांक के रूप में काम करता है
लुइस मेंडू

अष्ट सप्तक !! आत्मज्ञान के लिए मतलूब, था, के की तुलना में बेहतर और अधिक एर्गोनोमिक होना चाहिए।
अब्रद्धम

@ Agawa001 यह कुछ भ्रम की स्थिति भी पैदा कर सकता है , हालांकि
लुइस मेंडू

उदाहरण कोड में अनाम कार्यों के लिए एक टिप: मैं @(...) ...अपने कोड की पहली पंक्ति में उपयोग करता हूं, उसके बाद f = ans;दूसरा। यह रिपोर्ट करने के लिए बाइट्स की संख्या के बराबर पहली पंक्ति की लंबाई बनाता है।
BERS

3

सीजेएम, 7 बाइट्स

0q~z+:b

इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

0        e# Push 0 on the stack.
 q       e# Read and push all input, e.g., "[[10 10 4 62 7] [1 2 3 4 5]]".
  ~      e# Eval, pushing [[10 10 4 62 7] [1 2 3 4 5]].
   z     e# Zip, pushing [[10 1] [10 2] [4 3] [62 4] [7 5]].
    +    e# Concatenate, pushing [0 [10 1] [10 2] [4 3] [62 4] [7 5]]
     :b  e# Reduce by base conversion.
         e# [10 1] in base    0 is    0 * 10 + 1 = 1.
         e# [10 2] in base    1 is    1 * 10 + 2 = 12.
         e# [ 4 3] in base   12 is   12 *  4 + 3 = 51.
         e# [62 4] in base   51 is   51 * 62 + 4 = 3166.
         e# [ 7 5] in base 3166 is 3166 *  7 + 5 = 22167.

हमें एक मौका दें, डेनिस! : D
हाइपरएनुट्रिनो

2

हास्केल, 47 बाइट्स

दो समान लंबाई वाले समाधान:

s(a:b)(x:y)=a*product y:s b y
s _ _=[]
(sum.).s

जैसे कहा जाता है: ((sum.).s)[4,2][5,10]

यहाँ एक infix संस्करण है:

(a:b)&(x:y)=a*product y:b&y
_ & _=[]
(sum.).(&)

2

सप्टक, 47 / 43 /31 बाइट्स

@(d,i)sub2ind(flip(d),num2cell(flip(i+1)){:})-1

इसका परीक्षण यहां करें

यह कहते हुए कि, जैसा कि एक टिप्पणी में पूछा गया था , 1-आधारित अनुक्रमण को ओके कहा गया था जब यह प्रयोग की जा रही भाषा के लिए स्वाभाविक है। इस स्थिति में, हम 4 बाइट्स बचा सकते हैं:

@(d,i)sub2ind(flip(d),num2cell(flip(i)){:})

सादृश्य में, मैं तर्क देता हूं कि यदि कोड का उद्देश्य एक सरणी को रैखिक रूप से अनुक्रमित करना है उस भाषा के भीतर करना है, तो MATLAB / ऑक्टेव के कॉलम के प्रमुख ऑर्डर के लिए पूरे फ़्लिपिंग और लेखा आवश्यक नहीं होना चाहिए। उस स्थिति में, मेरा समाधान बन जाता है

@(d,i)sub2ind(d,num2cell(i){:})

परीक्षण है कि यहाँ एक


नमस्कार, और PPCG में आपका स्वागत है! बहुत बढ़िया जवाब!
NoOneIsHere

1

गणितज्ञ, 47 बाइट्स

Fold[Last@#2#+First@#2&,First@#,Rest/@{##}]&

(यूनिकोड U + F3C7, या है \[Transpose]।) इसके लिए, मैंने अभिव्यक्ति को D n ( D n -1 ( n ( D 3 ( D 2 S 1 + S 2 ) + S ) के रूप में लिखा है। 3 ) ⋯) + एस एन -1 ) + एस एन । बस Foldदोनों सूचियों पर कार्य करते हैं।


1

दरअसल, 13 बाइट्स

;pX╗lr`╜tπ`M*

इसे ऑनलाइन आज़माएं!

यह कार्यक्रम पहले इनपुट के रूप में सूचकांकों की सूची और दूसरे इनपुट के रूप में आयामों की सूची लेता है।

स्पष्टीकरण:

;pX╗lr`╜tπ`M*
;pX╗            push dims[1:] to reg0
    lr`   `M    map: for n in range(len(dims)):
       ╜tπ        push product of last n values in reg0
            *   dot product of indices and map result

1

रैकेट 76 बाइट्स

(λ(l i(s 0))(if(null? i)s(f(cdr l)(cdr i)(+ s(*(car i)(apply *(cdr l)))))))

Ungolfed:

(define f
  (λ (ll il (sum 0))
    (if (null? il)
        sum
        (f (rest ll)
           (rest il)
           (+ sum
              (* (first il)
                 (apply * (rest ll))))))))

परिक्षण:

(f '(5 10) '(4 2))
(f '(10 10 4 62 7) '(1 2 3 4 5))
(f '(5 1 10) '(3 0 7))

आउटपुट:

42
22167
37

0

सी #, 73 बाइट्स

d=>i=>{int n=d.Length,x=0,y=1;for(;n>0;){x+=y*i[--n];y*=d[n];}return x;};

परीक्षण मामलों के साथ पूरा कार्यक्रम:

using System;

namespace IndexOfAMultidimensionalArray
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int[],Func<int[],int>>f= d=>i=>{int n=d.Length,x=0,y=1;for(;n>0;){x+=y*i[--n];y*=d[n];}return x;};

            int[] dimensions, indices;
            dimensions =new int[]{5, 10};
            indices=new int[]{4,2};
            Console.WriteLine(f(dimensions)(indices));      //42

            dimensions=new int[]{10, 10, 4, 62, 7};
            indices=new int[]{1, 2, 3, 4, 5};
            Console.WriteLine(f(dimensions)(indices));      //22167

            dimensions=new int[]{5, 1, 10};
            indices=new int[]{3, 0, 7};
            Console.WriteLine(f(dimensions)(indices));      //37

            dimensions=new int[]{6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
            indices=new int[]{3, 1, 5, 5, 3, 0, 5, 2, 5, 4};
            Console.WriteLine(f(dimensions)(indices));      //33570178
        }
    }
}

0

पर्ल 6, 39 बाइट्स

->\d,\i{sum i.map:{[×] $_,|d[++$ ..*]}}

यहाँ एक भोली गोल्फ, बस एक अनाम उप निचोड़।

पर्ल 6 में एक अनाम राज्य चर है $जो लूप में एक काउंटर बनाने के लिए उपयोगी है (जैसे, पोस्ट-इन्क्रीमेंट $++या पूर्व-इंक्रीमेंट का उपयोग करके ++$)। मैं एक नक्शे के अंदर आयाम सरणी स्लाइस के शुरुआती सूचकांक को बढ़ाने के लिए इस राज्य चर को बढ़ाता हूं।

यहां उप-सूचियों को बनाने वाला एक अनगॉल्ड फंक्शन है

sub md-index(@dim, @idx) {
    @idx.map(-> $i { $i, |@dim[++$ .. *] })
}
say md-index([10, 10, 4, 62, 7], [1, 2, 3, 4, 5]);
# OUTPUT: ((1 10 4 62 7) (2 4 62 7) (3 62 7) (4 7) (5))

फिर यह गुणन ( ×) ऑपरेटर के साथ उप-सूचियों को कम करने और sumपरिणामों को निगाने की बात है।

sub md-index(@dim, @idx) {
    @idx.map(-> $i { [×] $i, |@dim[++$ .. *] }).sum
}
say md-index([10, 10, 4, 62, 7], [1, 2, 3, 4, 5]);
# OUTPUT: 22167

0

पर्ल, 71 बाइट्स

sub{$s+=$_[1][-$_]*($p*=$_[0][1-$_])for($p=$_[0][$s=0]=1)..@{$_[0]};$s}

Ungolfed:

sub {
    my $s = 0;
    my $p = 1;

    $_[0]->[0] = 1;
    for (1 .. @{$_[1]}) {
        $p *= $_[0]->[1 - $_];
        $s += $_[1]->[-$_] * $p;
    }

    return $s;
}

0

सी ++ 17, 133 115 बाइट्स

-18 उपयोग के लिए बाइट्स auto...

template<int d,int ...D>struct M{int f(int s){return s;}int f(int s,auto...S){return(s*...*D)+M<D...>().f(S...);}};

Ungolfed:

template <int d,int ...D> //extract first dimension
struct M{
 int f(int s){return s;} //base case for Sn
 int f(int s, auto... S) { //extract first index 
  return (s*...*D)+M<D...>().f(S...); 
  //S_i * D_(i+1) * D(i+2) * ... + recursive without first dimension and first index
 }
};

उपयोग:

M<5,10>().f(4,2)
M<10,10,4,62,7>().f(1,2,3,4,5)

वैकल्पिक, केवल कार्य, 116 बाइट्स

#define R return
#define A auto
A f(A d){R[](A s){R s;};}A f(A d,A...D){R[=](A s,A...S){R(s*...*D)+f(D...)(S...);};}

Ungolfed:

auto f(auto d){
  return [](auto s){
   return s;
  };
}
auto f(auto d, auto...D){
  return [=](auto s, auto...S){
    return (s*...*D)+f(D...)(S...);
  };
}

उपयोग:

f(5,10)(4,2)
f(10,10,10)(4,3,2)
f(10,10,4,62,7)(1,2,3,4,5)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.