Bir bölgeyi eğimine göre sınıflandırma


16

Tanımlar

K inci boyutu bir kare matrisin halka , N , 1 ≤ k ≤ tavan (N / 2) elemanları ile oluşturulan listesidir k inci ve (N-k + 1) inci satırlar ve sütunlar, ancak olmadan ilk ve son k-1 elemanları.

Misal:

Matris:

1 2 3 4 5
6 7 8 9 1
8 7 6 5 4
3 2 1 9 8
7 6 5 4 3

Halkalarda sınırlandırılmış:

+ ------------------- +
| 1 2 3 4 5 |
| + ----------- + |
| 6 | 7 8 9 | 1 |
| | + --- + | |
| 8 | 7 | 6 | 5 | 4 |
| | + --- + | |
| 3 | 2 1 9 | 8 |
| + ----------- + |
| 7 6 5 4 3 |
+ ------------------- +

Yukarıdakilerin ilk halkası 1,2,3,4,5,1,4,8,3,4,5,6,7,3,8,6, ikincisi 7,8,9,5,9,1,2,7ve üçüncüsü 6.

Bir K ile N (Bu zorluğun amacıyla) pozitif tamsayılar matris:

  • İçbükey tüm tam sayı ise k inci halkası üzerinde daha kesin olarak büyüktür (k + 1) inci halka, k arasında bir tam sayı olduğu 1 ve N (birinci halka üzerinde olanlardır ki, saniye daha büyüktür sırayla üçüncü vb. Misal:

    4 5 6 4 7 -> çünkü 4,5,6,4,7,4,8,5,5,4,6,5,9,5,5,4'ün hepsi
    4 3 2 2 4 3,2,2,3,2,3,3,2'den herhangi biri, hepsi 1'den yüksek
    5 2 1 3 8
    5 3 3 2 5
    9 5 6 4 5
    
  • matristeki tüm tamsayılar eşitse düz . Başka bir örnek (belki de gereksiz):

    2 2 2 2
    2 2 2 2
    2 2 2 2
    2 2 2 2
    
  • konveks tüm tam sayı ise k inci halka kesinlikle düşük üzerinde daha farklı (k + 1) inci halka, k arasında bir tam sayı olduğu 1 ve N (birinci halka üzerinde uygun ve söz konusu ikinci üzerinde bu, daha düşük sırayla üçüncü gibi olanlardan daha düşük). Misal:

    1 2 1 -> çünkü 1 ve 2'nin her ikisi de 6'dan düşük
    2 6 2
    1 2 1
    
  • matris yukarıdaki kriterlerden herhangi birini karşılamıyorsa karıştırılır . Misal:

    3 3 3 3 3
    3 2 2 2 3
    3 2 3 2 3
    3 2 2 2 3
    3 3 3 3 3
    

Meydan okuma

En az 3 büyüklüğünde pozitif tamsayılardan oluşan bir kare matris verildiğinde , yukarıdaki tanımlara göre sınıflandırın. Yani, matrisin içbükey, düz, dışbükey veya karışık olmasına bağlı olarak dört farklı tutarlı değerden birini çıktılayın.

Herhangi rekabet edebilir programlama dili ve giriş almak ve herhangi içinden çıktı sağlayabilir standart yöntemle O notu alırken ve herhangi makul bir biçimde bu boşluklar varsayılan olarak yasaktır. Bu , bu nedenle her dil için en kısa gönderme (bayt cinsinden) kazanır.

Test senaryoları

İşte aralarından seçim yapabileceğiniz bir dizi örnek - Her kategoriden 6 tane seçtim.

İçbükey

[[3, 3, 3], [3, 1, 3], [3, 3, 3]]
[[2, 3, 4], [5, 1, 6], [7, 8, 9]]
[[19, 34, 45], [34, 12, 14], [13, 13, 13]]
[[3, 4, 3, 4], [4, 2, 1, 3], [3, 1, 2, 4], [4, 3, 4, 3]]
[[4, 5, 6, 4, 7], [4, 3, 2, 2, 4], [5, 2, 1, 3, 8], [5, 3, 3, 2, 5], [9, 5, 6, 4, 5]]
[[7, 7, 7, 7, 7], [7, 6, 6, 6, 7], [7, 6, 5, 6, 7], [7, 6, 6, 6, 7], [7, 7, 7, 7, 7]]

Düz

[[1, 1, 1], [1, 1, 1], [1, 1, 1]]
[[2, 2, 2], [2, 2, 2], [2, 2, 2]]
[[8, 8, 8], [8, 8, 8], [8, 8, 8]]
[[120, 120, 120], [120, 120, 120], [120, 120, 120]]
[[10, 10, 10, 10], [10, 10, 10, 10], [10, 10, 10, 10], [10, 10, 10, 10]]
[[5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5]]

dışbükey

[[1, 2, 1], [2, 6, 2], [1, 2, 1]]
[[1, 1, 1], [1, 2, 1], [1, 1, 1]]
[[19, 34, 45], [34, 76, 14], [13, 6, 13]]
[[3, 3, 3, 3], [3, 4, 4, 3], [3, 4, 4, 3], [3, 3, 3, 3]]
[[192, 19, 8, 6], [48, 324, 434, 29], [56, 292, 334, 8], [3, 4, 23, 23]]
[[291, 48, 7, 5], [47, 324, 454, 30], [58, 292, 374, 4], [9, 2, 53, 291]]

Karışık

[[1, 2, 3], [4, 5, 9], [6, 7, 8]]
[[10, 14, 21], [100, 8, 3], [29, 2, 19]]
[[5, 5, 5, 5], [5, 4, 4, 5], [5, 4, 6, 5], [5, 5, 5, 5]]
[[3, 3, 3, 3], [3, 1, 2, 3], [3, 3, 2, 3], [3, 3, 3, 3]]
[[12, 14, 15, 16], [12, 18, 18, 16], [12, 11, 11, 16], [12, 14, 15, 16]]
[[5, 5, 5, 5, 5], [5, 4, 4, 4, 5], [5, 4, 6, 4, 5], [5, 4, 4, 4, 5], [5, 5, 5, 5, 5]]

Bu sorun önceden Sandbox'ta yayınlanmıştır . Orada değerli geribildirimler verenler için teşekkürler.
Bay Xcoder

2
Çocuk, çeşitli dillerde tüm bu test
senaryolarını

@ngm Zaten bir tane olmadığımızı düşünmeye cesaret etme ! : P
Bay Xcoder

Yanıtlar:


5

Java (JDK 10) , 247 232 220 bayt

x->{int i=0,j=x.length,k,m,M,p=0,P=0,r=0;for(;i<j;){for(M=m=x[k=i][--j];k<=j;)for(int q:new int[]{x[i][k],x[j][k],x[k][i],x[k++][j]}){m=m<q?m:q;M=M<q?q:M;}r=i++>0?(k=P<m?3:p>M?1:P==m?2:4)*r!=r*r?4:k:0;p=m;P=M;}return r;}

Çevrimiçi deneyin!

Çıktılar:

  • 1 "içbükey" için
  • 2 "düz" için
  • 3 "dışbükey" için
  • 4 "karışık" için

Ungolfed:

x -> { // lambda that takes in the input int[][]
  int i = 0, // index of right bound of ring
      j = x.length, // index of left bound of ring
      k, // index of row-column-pair in ring
      m, // minimum of ring
      M, // maximum of ring
      p = 0, // minimum of previous ring
      P = 0, // maximum of previous ring
      r = 0; // result
  for (; i < j; ) { // iterate the rings from outside inwards
    // set both min and max to be to top right corner of the ring (and sneakily set some loop variables to save space)
    for (M = m = x[k = i][--j]; k <= j; ) // iterate the row-column pairs of the ring from top-right to bottom-left
      for (int q : new int[] {x[i][k], x[j][k], x[k][i], x[k++][j]}) { // iterate all of the cells at this row-column pair (and sneakily increment the loop variable k)
        // find new minimum and maximum
        m = m < q ? m : q;
        M = M < q ? q : M;
      }
    r = // set the result to be...
      i++ > 0 ? // if this is not the first ring... (and sneakily increment the loop variable i)
              // if the new result does not match the old result...
              (k = P < m ? // recycling k here as a temp variable to store the new result, computing the result by comparing the old and new mins/maxes
                         3
                         : p > M ?
                                 1
                                 : P == m ? 
                                          2
                                          : 4) * r != r * r ? // multiplying by r here when comparing because we want to avoid treating the case where r = 0 (unset) as if r is different from k
                                                            4 // set the result to "mixed"
                                                            : k // otherwise set the result to the new result
              : 0; // if this is the first ring just set the result to 0
    // set the old ring mins/maxes to be the current ones
    p = m; 
    P = M;
  }
  return r; // return the result
}

5

Jöle ,  18 17  16 bayt

Bu çabanın dışarıda golf oynama potansiyeli olduğuna inanıyorum

L‘HạŒỤṀ€IṠQṢ«FE$

Tamsayıların listesini döndüren sayıların listesini kabul eden monadik bir bağlantı:

Concave ->  [0, 0]
Flat    ->  [-1, 0, 1]
Convex  ->  [-1, 0]
Mixed   ->  [-1, 0, 0]

Çevrimiçi deneyin! Veya test takımına bakın .

L‘Hdaha az verimli ancak atomik olarak daha kısa olanla değiştirilebilir JÆm.

Nasıl?

L‘HạŒỤṀ€IṠQṢ«FE$ - Link: list of (equal length) lists of numbers
L                - length
 ‘               - increment
  H              - halve
                 -   = middle 1-based index (in both dimensions as the input is square)
    ŒỤ           - sort multi-dimensional indices by their corresponding values
                 -   = a list of pairs of 1-based indexes
   ạ             - absolute difference (vectorises)
                 -   = list of [verticalDistanceToMiddle, horizontalDistanceToMiddle] pairs
      Ṁ€         - maximum of €ach
                 -   each = N/2-k (i.e. 0 as middle ring and N/2 as outermost)
        I        - incremental deltas (e.g. [3,2,2,3,1]->[3-2,2-2,3-2,1-3]=[-1,0,1,-2])
         Ṡ       - sign (mapping -n:-1; 0:0; and +n:1)
          Q      - de-duplicate
           Ṣ     - sort
                 -   = concave:[0, 1]; convex:[-1, 0]; flatOrMixed:[-1, 0, 1]
               $ - last two links as a monad
             F   -   flatten
              E  -   all equal? (1 if flat otherwise 0)
            «    - minimum (vectorises)
                 -   = concave:[0, 0]; convex:[-1, 0]; mixed:[-1, 0, 0]; flat:[-1, 0, 1]

5

Piton 2 , 219 216 189 176 bayt

def g(M):A=[sorted((M[1:]and M.pop(0))+M.pop()+[i.pop(j)for j in[0,-1]for i in M])for k in M[::2]];S={cmp(x[j],y[~j])for x,y in zip(A,A[1:])for j in[0,-1]};return len(S)<2and S

Çevrimiçi deneyin!

Çıktılar set([1]), set([0]), set([-1]),veya Falsesırasıyla içbükey, düz, dışbükey veya karışık.

Thx for: Ovs tarafından yapılan birkaç optimizasyondan 27 bayt . Ve sonra başka 13 sonradan bayt.

Liste kavraması A(ovs nedeniyle), her bir halkanın sıralanan öğelerinin bir listesini oluşturur.

Daha sonra, bitişik halkalar arasındaki maxve mindeğerlerini A'daki her bir sıralanmış listenin 0th ve -1th öğelerine bakarak karşılaştırırız. Örneğin, örneğin, her dış halkanın Miçbükey minolması durumunda max, bir sonraki en içteki halkanınkinden daha büyük olması gerektiğini unutmayın . ; ve sonra maxher bir dış halkanın bir minsonraki en içteki halkanınkinden daha büyük olacağını izler .

Eğer Miçbükey, düz veya dışbükey olan, bu grubu min/maxkarşılaştırmaları sadece 1 elemanına sahip olacaktır {-1, 0, 1}; karıştırılırsa, iki veya daha fazla eleman olacaktır.


@ovs: Bu oldukça col; Başka bir baytı bir liste kavrayışına dönüştürerek kurtardım (ve bunun diğer benzer zorluklar için çok yararlı bir teknik olabileceğini düşünerek).
Chas Brown

Belki de liste kavrayışını kısaltmanın bir yolu var, ancak bir while döngüsü hala daha kısa görünüyor: while M:k=M[0]+M[-1];M=M[1:-1];A+=sorted(k+[i.pop(j)for j in[0,-1]for i in M]),(174 bayt)
ovs

@ovs: ,A=()Bayt sayımınızdan çıkarıldınız ...
Chas Brown

Ben 174 bayt ileA=()
ovs

Ah! Özür dilerim, yanlış anladım. Bu formun geçti önceki sürümünde, farklıdır: while M: A+= (some expression).
Chas Brown


4

JavaScript (ES6), 168 bayt

İadeler:

  • -1 daire için
  • 0 karışık için
  • 1 dışbükey için
  • 2 içbükey için
f=(a,k=w=~-a.length/2,p,P,i,m,M,y=w)=>k<0?i%4%3-!i:a.map(r=>r.map(v=>Y|(X=k*k-x*x--)<0&&X|Y<0||(m=v>m?m:v,M=v<M?M:v),x=w,Y=k*k-y*y--))|f(a,k-1,m,M,i|M-m<<2|2*(M<p)|m>P)

Çevrimiçi deneyin!

Nasıl?

Her zilde minimum ve maksimum

Her bir halkada minimum m ve maksimum M'yi hesaplıyoruz .

Her eksendeki matrisin merkezinden kare mesafesini hesaplayarak bir hücrenin belirli bir halka üzerinde olup olmadığını test ediyoruz. Mutlak değeri almak da işe yarayabilir, ancak kare alma daha kısadır.

De bir hücre (x, y) bulunur , n -inci halka aşağıdaki formül ise (en dış bir başlayarak 0 endeksli) yanlış :

((Y != 0) or (X < 0)) and ((X != 0) or (Y < 0))

nerede:

  • X = k² - (x - w) ²
  • Y = k² - (y - w) ²
  • w = (uzunluk - 1) / 2
  • k = w - n

Örnek: 6x6 matrisin 2. halkasındaki hücre (1, 2) mi?

  | 0 1 2 3 4 5   w = (6 - 1) / 2 = 2.5
--+------------   (x, y) --> ( x-w,  y-w) --> ((x-w)²,(y-w)²)
0 | 0 0 0 0 0 0   (1, 2) --> (-1.5, -0.5) --> (  2.25,   0.5)
1 | 0 1 1 1 1 0   
2 | 0[1]0 0 1 0   k = w - 1 = 1.5
3 | 0 1 0 0 1 0   k² = 2.25
4 | 0 1 1 1 1 0   X = 2.25 - 2.25 = 0 / Y = 2.25 - 0.5 = 1.75
5 | 0 0 0 0 0 0   ((X != 0) or (Y < 0)) is false, so (1,2) is on the ring

Bayraklar

Her yinelemenin sonunda, m ve M'yi önceki halkanın minimum p ve maksimum P ile karşılaştırır ve bayrak değişkenini i buna göre güncelleriz :

  • i |= 1Eğer m> P
  • i |= 2Eğer M <p
  • M! = m ise i'nin daha yüksek bitlerini ayarladık

İşlemin sonunda, i'nin son değerini aşağıdaki gibi dönüştürürüz :

i % 4  // isolate the 2 least significant bits (for convex and concave)
% 3    // convert 3 to 0 (for mixed)
- !i   // subtract 1 if i = 0 (for flat)

4

K (ngn / k) , 100 71 69 bayt

{$[1=#?,/a:(,/x)@.=i&|i:&/!2##x;;(&/m>1_M,0)-&/(m:&/'a)>-1_0,M:|/'a]}

Çevrimiçi deneyin!

döndürür 1= içbükey, ::= düz, -1= dışbükey, 0= karışık

(k ::cinsinden eksik değerler için yer tutucu olarak kullanılır)


OK kullanarak farklı bir strateji:&/1_`{&/+(y>|/x;y<&/x;,/x=/:y)}':(,/*:'(|+:)\)'-1_(-1_1_+-1_1_)\
zgrep

@zgrep güzel! :) İsterseniz ayrı bir cevap olarak yayınlamaktan ve benimkinden fikirler almaktan çekinmeyin - örneğin, halkalara ayrılmam daha kısa görünüyor, ancak henüz
OK'de


Ooh, bu çok düzgün bir halka yarışı! Bunu sevdim.
zgrep


1

C ++ 17 (gcc) , 411 bayt

#import<map>
#define R return
#define T(f,s)X p,c;for(auto&e:r){c=e.second;if(p.a&&!p.f(c)){s;}p=c;}R
using I=int;struct X{I a=0;I z=0;I f(I n){R!a||n<a?a=n:0,n>z?z=n:0;}I
l(X x){R z<x.a;}I g(X x){R a>x.z;}I e(X x){R a==z&a==x.a&z==x.z;}};I
N(I i,I j,I s){i*=s-i;j*=s-j;R i<j?i:j;}auto C=[](auto&&m){I
s=size(m),i=-1,j;std::map<I,X>r;for(;++i<s;)for(j=-1;++j<s;)r[N(i,j,s-1)].f(m[i][j]);T(g,T(l,T(e,R 0)3)2)1;};

Yeni bir yüksek puan! (en azından gönderme sırasında) Ah, biraz şık, ama yine de C ++.

Çevrimiçi deneyin!

Lambda a Calır std::vector<std::vector<int>>ve içbükey için 1, dışbükey için 2, düz için 3 veya karışık için 0 döndürür.

Açıklayıcı tanımlayıcılar, yorumlar, R-> returnve I-> intyazılmış vb. İle kodun daha okunaklı bir versiyonu :

#include <map>

// Abbreviation for golfing. Spelled out below.
#define R return

// Macro to test whether all pairs of consecutive Ranges in `rings`
// satisfy a condition.
// func: a member function of Range taking a second Range.
// stmts: a sequence of statements to execute if the condition is
//        not satisfied. The statements should always return.
//        May be missing the final semicolon.
// Expands to a statement, then the return keyword.
// The value after the macro will be returned if all pairs of Ranges
// satisfy the test.
#define TEST(func, stmts)                                     \
    Range prev, curr;                                         \
    for (auto& elem : rings) {                                \
        curr = elem.second;                                   \
        // The first time through, prev.a==0; skip the test.  \
        if (prev.a && !prev.func(curr))                       \
        { stmts; }                                            \
        prev = curr;                                          \
    }                                                         \
    return

// Abbreviation for golfing. Spelled out below.
using I = int;

// A range of positive integers.
// A default-constructed Range is "invalid" and has a==0 && z==0.
struct Range
{
    int a = 0;
    int z = 0;
    // Add a number to the range, initializing or expanding.
    // The return value is meaningless (but I is shorter than void for golfing).
    int add(int n) {
        return !a||n<a ? a=n : 0, n>z ? z=n : 0;
        /* That is:
        // If invalid or n less than previous min, set a.
        if (a==0 || n<a)
            a = n;
        // If invalid (z==0) or n greater than previous max, set z.
        if (n>z)
            z = n;
        return dummy_value;
        */
    }

    // Test if all numbers in this Range are strictly less than
    // all numbers in Range x.
    int less(Range x)
    { return z < x.a; }

    // Test if all numbers in this Range are strictly greater than
    // all numbers in Range x.
    int greater(Range x)
    { return a > x.z; }

    // Test if both this Range and x represent the same single number.
    int equal(Range x)
    { return a==z && a==x.a && z==x.z; }
};

// Given indices into a square matrix, returns a value which is
// constant on each ring and increases from the first ring toward the
// center.
// i, j: matrix indices
// max: maximum matrix index, so that 0<=i && i<=max && 0<=j && j<=max
int RingIndex(int i, int j, int max)
{
    // i*(max-i) is zero at the edges and increases toward max/2.0.
    i *= max - i;
    j *= max - j;
    // The minimum of these values determines the ring.
    return i < j ? i : j;
}

// Takes a container of containers of elements convertible to int.
// Must represent a square matrix with positive integer values.
// Argument-dependent lookup on the outer container must include
// namespace std, and both container types must have operator[] to
// get an element.  (So std::vector or std::array would work.)
// Returns:
//   1 for a concave matrix
//   2 for a convex matrix
//   3 for a flat matrix
//   0 for a mixed matrix
auto C /*Classify*/ = [](auto&& mat)
{
    int mat_size=size(mat), i=-1, j;
    std::map<int, Range> rings;

    // Populate rings with the range of values in each ring.
    for (; ++i<mat_size;)
        for (j=-1; ++j<mat_size;)
            rings[RingIndex(i, j, mat_size-1)].add(mat[i][j]);

    // Nested macros expand to
    // Range prev, curr; for ... if (...) {
    //   Range prev, curr; for ... if (...) {
    //     Range prev, curr; for ... if (...) {
    //       return 0;
    //     } return 3;
    //   } return 2;
    // } return 1
    // Note each scope declares its own prev and curr which hide
    // outer declarations.
    TEST(greater, TEST(less, TEST(equal, return 0) 3) 2) 1;
};

1
`` Şık '' demek ne demek istediğini ifade ediyor sanmıyorum
sadece ASCII-
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.