เรียงลำดับรายการเป็นเมทริกซ์น้อยที่สุด


18

รับรายการที่ไม่เรียงลำดับของจำนวนเต็มบวกที่ไม่ซ้ำกันอย่างเคร่งครัดโดยเรียงลำดับลงในเมทริกซ์ 2D รายการป้อนข้อมูลที่รับประกันได้ว่าจะมีความยาวคอมโพสิตซึ่งหมายความว่าเมทริกซ์ที่ส่งออกไม่จำเป็นต้องเป็นตาราง แต่มีขนาดที่มีn x mn,m > 1

"Minimally sort" ที่นี่หมายถึงสิ่งต่อไปนี้:

  • เรียงลำดับรายการตามลำดับจากน้อยไปหามาก
  • กระชับเมทริกซ์เอาต์พุตให้มากที่สุด - ลดผลรวมของมิติของเมทริกซ์ (ตัวอย่างเช่นสำหรับ20องค์ประกอบอินพุตเช่นอินพุตต้องใช้เมทริกซ์เอาท์พุท5x4หรือ4x5เมทริกซ์และไม่ใช่ก2x10)
  • กระชับจำนวนที่เรียงแล้วไปทางซ้ายบนของเมทริกซ์ให้มากที่สุดเริ่มต้นด้วยองค์ประกอบแรกในรายการที่เรียงลำดับ
  • นี่อาจเป็นวิธีการเรียงลำดับรายการจากนั้นก็แบ่งมันตามแนวต้านของเส้นทแยงมุมเริ่มจากด้านซ้ายบน

ตัวอย่าง:

สำหรับอินพุต1..20เอาต์พุตเป็นเมทริกซ์ 5x4 หรือ 4x5 ดังนี้:

 1  2  4  7 11
 3  5  8 12 15
 6  9 13 16 18
10 14 17 19 20

 1  2  4  7
 3  5  8 11
 6  9 12 15
10 13 16 18
14 17 19 20

สำหรับอินพุต[3, 5, 12, 9, 6, 11]เอาต์พุตคือ 2x3 หรือ 3x2 ดังต่อไปนี้

3  5  9
6 11 12

 3  5
 6  9
11 12

สำหรับอินพุต[14, 20, 200, 33, 12, 1, 7, 99, 58]เอาต์พุตคือ 3x3 ดังต่อไปนี้

 1   7  14
12  20  58
33  99 200

สำหรับอินพุต1..10เอาต์พุตควรเป็น 2x5 หรือ 5x2 ดังนี้

1 2 4 6  8
3 5 7 9 10

1  2
3  4
5  6
7  8
9 10

สำหรับอินพุต[5, 9, 33, 65, 12, 7, 80, 42, 48, 30, 11, 57, 69, 92, 91]เอาต์พุตคือ 5x3 หรือ 3x5 ดังต่อไปนี้

 5  7 11 33 57
 9 12 42 65 80
30 48 69 91 92

 5  7 11
 9 12 33
30 42 57
48 65 80
69 91 92

กฎระเบียบ

  • การป้อนข้อมูลสามารถใช้เพื่อให้พอดีกับประเภทจำนวนเต็มในภาษาของคุณ
  • อินพุตและเอาต์พุตจะได้รับโดยวิธีการที่สะดวกใด
  • ยอมรับได้ทั้งโปรแกรมหรือฟังก์ชั่น หากฟังก์ชั่นคุณสามารถส่งคืนผลลัพธ์มากกว่าการพิมพ์
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • นี่คือเพื่อให้ใช้กฎการเล่นกอล์ฟตามปกติทั้งหมดและรหัสที่สั้นที่สุด (เป็นไบต์) ชนะ

1
โอ้ว้าวเป็นคำที่ฉันไม่เคยเห็นมาก่อนตั้งแต่พีชคณิตเชิงเส้น มองข้ามได้ง่าย ขอโทษด้วย.
Magic Octopus Urn

@LuisMendo เพิ่ม15กรณีทดสอบองค์ประกอบ
AdmBorkBork

คำตอบ:


10

เยลลี่ , 24 22 20 ไบต์

pS€ỤỤs
LÆDżṚ$SÞḢç/ịṢ

ลองออนไลน์!

ที่บันทึกไว้ 2 ไบต์ขอบคุณที่ @ โจนาธานอัลลัน

คำอธิบาย

pS€ỤỤs  Helper link. Input: integer a (LHS), integer b (RHS)
p       Cartesian product between [1, 2, ..., a] and [1, 2, ..., b]
 S€     Sum each pair
   Ụ    Grade up
    Ụ   Grade up again (Obtains the rank)
     s  Split into slices of length b

LÆDżṚ$SÞḢç/ịṢ  Main link. Input: list A
L              Length
 ÆD            Divisors
     $         Monadic pair
    Ṛ            Reverse
   ż             Interleave
                 Now contains all pairs [a, b] where a*b = len(A)
      SÞ       Sort by sum
        Ḣ      Head (Select the pair with smallest sum)
         ç/    Call helper link
            Ṣ  Sort A
           ị   Index into sorted(A)

L%J¬TżṚ$-> LÆDżṚ$ควรประหยัดสองฉันคิดว่า
Jonathan Allan

pSÞỤsลิงก์แรกจะกลายเป็น
เดนนิส

4

Python 2 , 160 158 153 151 ไบต์

-2 ไบต์ขอบคุณ Erik the Outgolfer
-2 ไบต์ขอบคุณ Mr. Xcoder

s=sorted(input())
l=len(s)
x=int(l**.5)
while l%x:x+=1
n=1
o=eval(`l/x*[[]]`)
while s:
 for i in range(l/x)[max(0,n-x):n]:o[i]+=s.pop(0),
 n+=1
print o

ลองออนไลน์! หรือลองกรณีทดสอบทั้งหมด


ฉันเชื่อว่าคุณสามารถใช้max(0,n-x)-2 ไบต์
Mr. Xcoder

4

R 110 95 ไบต์

function(x){n=sum(x|1)
X=matrix(x,max(which(!n%%1:n^.5)))
X[order(col(X)+row(X))]=sort(x)
t(X)}

ลองออนไลน์!

มันทำงานอย่างไร

f <- function(x) {
  n <- sum(x|1)                           # length
  p <- max(which(!n%%1:n^.5))             # height of matrix
  X <- matrix(x, p)                       # initialize matrix
  X[order(col(X) + row(X))] <- sort(x)    # filling the matrix using position distance to the top left corner
  t(X)                                    # probably required by OP
}

Giuseppeบันทึกไบต์ 15 (!) ที่ใหญ่โตด้วยเทคนิคต่อไปนี้

  • แทนที่length(x)ด้วยsum(x|1)(-1 ไบต์)
  • floor()ไม่จำเป็นต้องใช้เป็น:รอบลงอย่างไรก็ตาม (-7)
  • ^.5สั้นกว่าsqrt()(-3)
  • ใช้col(X) + row(X)แทนouter(nice!)
  • ไม่สามารถกำจัดสิ่งที่t(X)น่าผิดหวังได้)

โซลูชันดั้งเดิม

function(x){
n=length(x)
p=max(which(!n%%1:floor(sqrt(n))))
X=outer(1:p,1:(n/p),`+`)
X[order(X)]=sort(x)
t(X)}

มันจะดูแฟนซีมากขึ้นด้วยouterการถูกแทนที่ด้วยrow(X)+col(X)แต่นั่นจะต้องเริ่มต้นเอาท์พุทเมทริกซ์Xก่อน

ลองออนไลน์!


2
ดีมาก! คุณสามารถลงไปที่95 bytes
Giuseppe

1
อาจสามารถใช้บางอย่างจากโซลูชันของฉันไปยังความท้าทายที่เกี่ยวข้องเพื่อช่วยได้ที่นี่เช่นกัน
Giuseppe

มันเกี่ยวข้องอย่างแท้จริง วิธีการที่ดีมาก!
Michael M

3

JavaScript (ES6), 172 ไบต์

l=>(n=l.sort((a,b)=>b-a).length,w=l.findIndex((_,i)=>!(i*i<n|n%i)),a=l=>[...Array(l)],r=a(n/w).map(_=>a(w)),a(w+n/w).map((_,x)=>r.map((s,y)=>x-y in s&&(s[x-y]=l.pop()))),r)

คำอธิบาย

l=>(                                // Take a list l as input
 l.sort((a,b)=>b-a),                // Sort it
 n=l.length,                        // Get the length n
 w=l.findIndex((_,i)=>!(i*i<n|n%i)),// Find the first integer w where w >= √n and n % w = 0
 a=l=>[...Array(l)],                // Helper function a
 r=a(n/w).map(_=>a(w)),             // Create the grid r of size w, n/w
 a(w+n/w).map((_,x)=>               // For every x from 0 to w + n/w:
  r.map((s,y)=>                     //  For every row s in r:
   x-y in s&&(                      //   If the index x-y is in s:
    s[x-y]=l.pop()))),              //    Set s[x-y] to the next element of l
 r)                                 // Return r

กรณีทดสอบ


3

Perl 5 , 132 bytes

sub d{$,=0|sqrt(@_=sort{$a-$b}@_);--$,while@_%$,;map{$r++,$c--for@_/$,..$c;$a[$r++][$c--]=$_;$c=++$i,$r=0if$r<0||$c<0||$r>=$,}@_;@a}

ลองออนไลน์!

รูทีนย่อยส่งกลับอาร์เรย์ 2 มิติ ลิงค์ TIO ประกอบด้วยส่วนท้ายของรหัสสำหรับการแสดงผลการทดสอบ


3

ระดับเสียงคู่ , 151 ไบต์

function f(v)n=floor(sqrt(l=nnz(v)));while i=mod(l,n);++n;end;A=nan(m=l/n,n);for k=[1:m 2*m:m:l];do A(k)=sort(v)(++i);until~mod(k+=m-1,m)|k>l;end;A'end

การใช้โครงสร้างวนรอบสามแบบที่แตกต่างกัน

ลองออนไลน์!

คลี่:

function f(v)
    n = floor(sqrt(l=nnz(v)));

    while i = mod(l,n);
        ++n;
    end;

    A = nan(m=l/n, n);

    for k = [1:m 2*m:m:l];
        do
            A(k) = sort(v)(++i);
        until ~mod(k+=m-1, m) | k>l;
    end;

    A'
end

คำตอบที่ดี! ทำไม'ในnnz(v') ต้อง?
Luis Mendo เมื่อ

1
@LuisMendo ขอบคุณ! ปรากฎว่า'ไม่จำเป็นถ้าฉันตัดการแสดงออกช่วงเช่น1:20รอบวงเล็บ ( [1:20]) ที่เว็บไซต์โทร (เพื่อให้มันเป็นเวกเตอร์ที่เกิดขึ้นจริง) เห็นได้ชัดว่าใน Octave ผู้ประกอบการลำไส้ใหญ่ไม่ได้สร้างเวกเตอร์แต่ค่าคงที่ช่วงที่ใช้พื้นที่หน่วยความจำน้อยกว่ามาก ด้วยเหตุผลบางอย่างnnz()ไม่ทำงานกับประเภทนั้น แต่การเปลี่ยนค่าคงที่ช่วงให้เวกเตอร์ดังนั้นจึงทำงานได้กับเครื่องหมายอัญประกาศเดี่ยว 'โทรฟังก์ชั่นที่มีเวกเตอร์ที่เกิดขึ้นจริงขจัดความจำเป็นในการที่
Steadybox

1
ขอบคุณสำหรับคำอธิบาย ฉันไม่รู้ว่าการแสดงออกที่หลากหลายนั้นได้รับการดูแลเป็นพิเศษใน Octave อย่างไรก็ตามความจริงที่ว่ามันไม่ได้สร้างเวกเตอร์สำหรับประสิทธิภาพของหน่วยความจำควรจะโปร่งใสกับโปรแกรมเมอร์ นั่นคือความจริงที่ว่าnnz(1:20)ไม่ทำงานอาจเป็นข้อผิดพลาด ( max(1:20), sum(1:20)ฯลฯมีความถูกต้อง)
Luis Mendo

1
เราควรรายงาน มันอาจจะส่งผลกระทบต่อการทำงานอื่น ๆ nnzกว่า คุณต้องการทำด้วยตัวเองหรือไม่
Luis Mendo

1
รายงานแล้ว มันก็ส่งผลกระทบต่อ MATL; ขณะนี้ได้รับการแก้ไข ขอบคุณที่สังเกตสิ่งนี้!
Luis Mendo

0

Huskขนาด 15 ไบต์

ḟȯΛ≤Σ∂MCP¹→←½ḊL

สิ่งนี้ทำงานโดยใช้กำลังดุร้ายดังนั้นกรณีทดสอบอีกต่อไปอาจหมดเวลา ลองออนไลน์!

คำอธิบาย

ḟȯΛ≤Σ∂MCP¹→←½ḊL  Implicit input, a list of integers x.
              L  Length of x (call it n).
             Ḋ   List of divisors.
            ½    Split at the middle.
          →←     Take last element of first part.
                 This is a divisor d that minimizes d + n/d.
        P¹       List of permutations of x.
      MC         Cut each into slices of length d.
ḟ                Find the first of these matrices that satisfies this:
     ∂            Take anti-diagonals,
    Σ             flatten them,
 ȯΛ≤              check that the result is sorted (each adjacent pair is non-decreasing).


0

JavaScript (ES6), 233 ไบต์

f=s=>{l=s.length;i=Math.sqrt(l)|0;for(;l%++i;);p=(x)=>(x/i|0+x%i)*l+x%i;m=[...Array(l).keys()].sort((x,y)=>p(x)-p(y));return s.sort((a,b)=>a-b).map((x,i)=>m.indexOf(i)).reduce((a,b,d,g)=>!(d%i)?a.concat([g.slice(d,d+i)]):a,[])}

คำอธิบาย

f=s=>{                         // Take array `s` of numbers as input
  l=s.length                   // short-hand for length
  i=Math.sqrt(l)|0             // = Math.floor(Math.sqrt(l))
  for(;l%++i;);                // i = width           
  j=l/i                        // j = height

  p=(x)=>(x/i|0+x%i)*l+x%i     // helper to calculate (sort-of) ~manhattan
                                 // distance (horizontal distance weighted
                                 // slightly stronger), from top-left corner
                                 // to the number x, if numbers 0,...,l are
                                 // arranged left-to-right, top-to-bottom
                                 // in an l=i*j grid

  m=[...Array(l).keys()]         // range array
  .sort((x,y)=>p(x)-p(y)),       // manhatten-sorted, sort-of...

  return s.sort((a,b)=>a-b)      // sort input array by numbers,
    .map((x,i,w)=>w[m.indexOf(i)])    // then apply inverse permutation of the
                                 // range-grid manhatten-sort mapping.
    .reduce(                     // slice result into rows
      (a,b,d,g)=>!(d%i)?a.concat([g.slice(d,d+i)]):a
      ,[]
     )
}

0

Java 10, 199 188 186 ไบต์

a->{int j=a.length,m=0,n,i=0,k=0;for(n=m+=Math.sqrt(j);m*n<j;n=j/++m);var R=new int[m][n];for(java.util.Arrays.sort(a);i<m+n;i++)for(j=0;j<=i;j++)if(i-j<n&j<m)R[j][i-j]=a[k++];return R;}

ลองออนไลน์

ขึ้นอยู่กับคำตอบของฉันที่นี่

คำอธิบาย:

a->{                        // Method with int-array parameter and int-matrix return-type
  int j=a.length,           //  Length of the input-array
      m=0,n,                //  Amount of rows and columns
      i=0,k=0;              //  Index integers
   for(n=m+=Math.sqrt(j);   //  Set both `m` and `n` to floor(√ `j`)
       m*n<j;               //  Loop as long as `m` multiplied by `n` is not `j`
       n=j/++m);            //   Increase `m` by 1 first with `++m`
                            //   and then set `n` to `j` integer-divided by this new `m`
   var R=new int[m][n];     //  Result-matrix of size `m` by `n`
   for(java.util.Arrays.sort(a);
                            //  Sort the input-array
       i<m+n;)              //  Loop as long as `i` is smaller than `m+n`
     for(j=0;j<=i;j++)      //   Inner loop `j` in range [0,`i`]
       if(i-j<n&j<m)        //    If `i-j` is smaller than `n`, and `j` smaller than `m`
                            //    (So basically check if they are still within bounds)
         R[j][i-j]=a[k++];  //     Add the number of the input array at index `k`,
                            //     to the matrix in the current cell at `[j,i-j]`
  return R;}                //  Return the result-matrix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.