วิธีการพิมพ์รูปแบบด้านล่างในไบต์ที่น้อยที่สุด?


20

ความท้าทายนี้เป็นแรงบันดาลใจนี้ตอนนี้ลบคำถาม


รับจำนวนเต็มบวกNเป็นอินพุตและส่งออกเมทริกซ์ด้วยตัวเลข1 .. N 2ที่ตามรูปแบบด้านล่าง:

กรอกข้อมูลในแถวแรกด้วย1 .. Nจากนั้นกรอกแถวสุดท้าย (หมายเลขแถวN ) ด้วย(N + 1) .. 2Nจากนั้นกรอกแถวที่สองด้วย(2N + 1) .. 3Nและดำเนินการต่อไปจนกว่าคุณจะได้กรอกข้อมูลครบถ้วนแถวทั้งหมด

รูปแบบผลลัพธ์มีความยืดหยุ่นดังนั้นจึงยอมรับรายการรายการ ฯลฯ

N = 1
1

N = 2
1  2
3  4

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

N = 4
 1  2  3  4
 9 10 11 12
13 14 15 16
 5  6  7  8

N = 5
 1  2  3  4  5
11 12 13 14 15
21 22 23 24 25
16 17 18 19 20
 6  7  8  9 10

ใช้กฎมาตรฐาน คำตอบสั้น ๆ เป็นไบต์ในแต่ละภาษาชนะ คำอธิบายได้รับการสนับสนุนเช่นเคย


รายการได้รับอนุญาตให้ยุติด้วยข้อผิดพลาดตราบใดที่ข้อผิดพลาดนั้นไม่ได้ถูกพิมพ์ไปยัง STDOUT?
Sok

@ ตกลงใช่นั่นเป็นค่าเริ่มต้นที่ได้รับอนุญาต
Martin Ender

1
ฉันเดาว่าชื่อนั้นนำมาจากคำถามที่ถูกลบ แต่เนื่องจากมันไม่สามารถค้นหาได้ (เพื่อค้นหาตัวล่อ ฯลฯ ) คุณสามารถเปลี่ยนเป็นชื่อที่ดีกว่าได้หรือไม่
user202729

1
เนื่องจาก "รูปแบบผลลัพธ์มีความยืดหยุ่น" ฉันสามารถส่งออกอาเรย์แบบหนึ่งมิติด้วยตัวเลขที่เรียงลำดับจากบรรทัดหนึ่งไปอีกบรรทัดได้หรือไม่ (เช่น:) 1 2 3 7 8 9 4 5 6รูปแบบผลลัพธ์ที่ยืดหยุ่นหรือไม่
Olivier Grégoire

4
โซลูชัน APL น่าจะเป็นอักขระตัวเดียวของรูปแบบ Old Persian
ทำเครื่องหมาย

คำตอบ:


7

05AB1E , 13 8 ไบต์

บันทึก 5 ไบต์ขอบคุณRod

nLô«āÉÏ

ลองออนไลน์!

คำอธิบาย

n           # push input^2
 L          # push range [1 ... input^2]
  ô         # split into pieces each the size of the input
   «       # append the reverse of this 2D-list
     ā      # push range [1 ... len(list)]
      É     # check each element for oddness
       Ï    # keep only the elements in the 2D list which are true in this list

5

Ruby , 53 ไบต์

->n{r=*1..n*n;n.times{|x|p r.slice!(r[x*=n]?x:-n,n)}}

คำอธิบาย:

ใส่ตัวเลขทั้งหมดลงในอาร์เรย์เดียวก่อนจากนั้นแบ่งอาร์เรย์ที่ข้ามบรรทัดสำหรับการวนซ้ำแต่ละครั้ง หลังจากการวนซ้ำครั้งแรก (n / 2 + n% 2) ไม่มีสิ่งใดเหลือให้ข้ามได้จากนั้นให้ลากบรรทัดที่เหลือทั้งหมดย้อนหลัง

ลองออนไลน์!



4

JavaScript, 68 ไบต์

แก้ไขการบันทึก 3 ไบต์ซึ่งถูก @ โดยผู้ใช้ @71546

ขั้นแรกให้ลองทำตามเส้นทางที่ชัดเจน: นับจาก 1 และเติมอาร์เรย์จากทั้งสองด้านจากด้านนอกสู่ด้านใน

n=>(v=0,q=[...Array(n)]).map((_,i)=>q[i&1?--n:i/2]=q.map(_=>++v))&&q

ทดสอบ

var F=
n=>(v=0,q=[...Array(n)]).map((_,i)=>q[i&1?--n:i/2]=q.map(_=>++v))&&q

function test() {
  var n=+N.value;
  O.innerHTML = '<tr><td>'
  +F(n).map(r=>r.join('</td><td>')).join('</td></tr><tr><td>')
  +'</td></tr>'
}

test()
#O { margin: 1em }
td { text-align: right }
<input id=N type=number min=1 value=5 oninput='test()'>
<table id=O>



1
@ user71546 ตอนนี้ 68
edc65


3

> <> , 51 + 3 = 54 47 ไบต์

:&v
?!\1-:&:&*}}r:
 ~\
!~>1+::n&:&%:a84*@@?$~o?

ลองออนไลน์!

คาดว่าอินพุตจะอยู่ด้านบนสุดของสแต็กเมื่อโปรแกรมเริ่มต้นโดยใช้-vแฟล็ก เอาต์พุตประกอบด้วยตัวเลขที่ไม่จัดแนวซึ่งคั่นด้วยช่องว่างเดียวและแต่ละบรรทัดถูกคั่นด้วยบรรทัดใหม่หนึ่งบรรทัด ตัวอย่างผลลัพธ์สำหรับN=5:

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

... ตามด้วยบรรทัดใหม่เดียว โปรแกรมยุติการทำงานพร้อมข้อผิดพลาด ( something smells fishy...) แต่อยู่ใน STDERR แทนที่จะเป็น STDOUT

ชี้แจง:

บรรทัดแรกนั้นเก็บสำเนาNไว้ในทะเบียนเท่านั้น

บรรทัดที่สองสร้างออฟเซ็ตสำหรับแต่ละแถวเอาท์พุทโดยการลบ 1 จากการNคูณนี้โดยNหมุนมันไปที่ด้านล่างของสแต็กจากนั้นย้อนกลับสแต็กทั้งหมด เมื่อจำนวนที่อยู่ด้านบนของสแต็คถึง 0 สแต็คควรมีลักษณะเช่นนี้ (ตัวอย่างใช้N=5):

5 15 20 10 0 0

บรรทัดที่สามจะทิ้งสำเนาที่ซ้ำกัน0จากด้านบนของสแต็ก

บรรทัดที่สี่เพิ่มขึ้นด้านบนสุดของสแต็กและส่งสำเนาของมันออกมา นี่คือ mod ที่นำมาใช้Nและสิ่งนี้จะใช้ในการตัดสินใจว่าควรพิมพ์เว้นวรรคหรือบรรทัดใหม่หรือไม่และถ้าส่วนบนสุดของสแต็กควรถูกทิ้ง - หากพิมพ์หมายเลขสุดท้ายxแล้วx mod N == 0แสดงว่าถึงจุดสิ้นสุดของแถวเอาต์พุตนั้นแล้ว . การดำเนินการสิ้นสุดลงเมื่อ1+ถูกดำเนินการบนสแต็กเปล่าโยนข้อผิดพลาดการเลิกจ้าง

รุ่นก่อนหน้า

นี่เป็นการตรวจสอบอย่างชัดเจนสำหรับสแต็กเปล่าเพื่อสิ้นสุดการดำเนินการและฉันยังรวมถึง 3 ไบต์สำหรับการ-vใช้แฟล็ก

:&v
?!\1-:&:&*}}r:
 ~\
!;>1+::n&:&%:a84*@@?$~o?!~l?

ลองออนไลน์!


จากข้อมูลเมตานี้เราไม่ได้เพิ่มค่าสถานะเป็นจำนวนไบต์อีกต่อไปดังนั้นจึงเพียงพอที่คุณจะระบุว่าใช้ค่าสถานะ
Emigna

@Emigna O_O ขอบคุณพระเจ้าสำหรับสิ่งนี้! ขอบคุณสำหรับหัวขึ้น
Sok


2

Java (OpenJDK 9) , 101 ไบต์

n->{int x[][]=new int[n][n],i=0,j;for(;i<n;i++)for(j=0;j<n;)x[i%2<1?i/2:n+~i/2][j]=++j+i*n;return x;}

ลองออนไลน์!

เครดิต


1
คุณสามารถบันทึกสามไบต์โดยเปลี่ยนตำแหน่งของj++: 102 bytes
Kevin Cruijssen

1
และอีกหนึ่งไบต์เปลี่ยนn-i/2-1เป็นn+~i/2 101 ไบต์
Kevin Cruijssen

@KevinCruijssen ขอบคุณ! ฉันโพสต์เวอร์ชั่นดิบไม่ใช่เวอร์ชันที่สมบูรณ์ ความผิดพลาดของฉันปัญหาแรกถูกแก้ไข แต่ไม่ใช่ครั้งที่สอง แต่คุณเขียนให้เครดิตกับคุณ ;-)
Olivier Grégoire

หมายเหตุ: หากยอมรับอาร์เรย์หนึ่งมิติอย่างใดn->{int i=n*n,x[]=new int[i],r;for(;i-->0;x[(r%2<1?r/2:n+~r/2)*n+i%n]=i+1)r=i/n;return x;}
Olivier Grégoire

2

JavaScript (ES6), 69 68 ไบต์

n=>[...Array(n)].map((_,i,a,j=((i*=2)<n?i:n+n+~i)*n)=>a.map(_=>++j))

มันดีกว่าก่อนที่ฉันจะโพสต์ได้ แต่ที่นี่มันอยู่ดี แก้ไข: บันทึกแล้ว 1 ไบต์ขอบคุณ @KevinCruijssen


n+n-i-1สามารถมีn+n+~iขนาด -1 ไบต์ดังนั้นคุณจึงจรดปลายเท้าพร้อมคำตอบ JavaScript อื่น ๆ อีกครั้ง :)
Kevin Cruijssen

@KevinCruijssen ขอบคุณที่ยอดเยี่ยม!
Neil

2

เยลลี่ 10 ไบต์

²ss2Ṛj@/Fs

ลองออนไลน์!

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

²ss2Ṛj@/Fs  Main link. Argument: n

²           Square; yield n².
 s          Split; promote n² to [1, ..., n²] and split it into chuks of length n.
  s2        Split 2; generate all non-overlapping pairs of chunks.
            If n is odd, this leaves a singleton array at the end.
    Ṛ       Reverse the order.
     j@/    Reduce by join with reversed arguments.
            In each step, this places the first and second element of the next pair
            at the top and bottom of the accumulator.
        Fs  Flatten and split to restore the matrix shape.

2

Stax , 10 ไบต์

│æ╘▐⌡r▌═∟Y

เรียกใช้และตรวจแก้จุดบกพร่องออนไลน์

การแสดง ascii ที่สอดคล้องกันของโปรแกรมเดียวกันคือ 12 ตัวอักษร

JRx/r{]+rFmJ

นี่คือวิธีการทำงาน

JR              range [1 .. x^2] where x=input
  x/            split into subarrays of size x
    r           reverse
     {   F      for each subarray, execute block
      ]+r       concat array, and reverse result
          m     for each row, output ...
           J        each subarray joined by spaces


2

R , 70 59 47 ไบต์

function(n)matrix(1:n^2,n,,T)[c(1:n,n:1)*!0:1,]

ลองออนไลน์!

ขอบคุณRobin Ryderสำหรับการเล่นกอล์ฟ 4 ไบต์ซึ่งฉันเล่นกอล์ฟต่อไป

ส่งกลับเมทริกซ์ สร้างmatrixในลำดับเช่น[[1 2 3] [4 5 6] [7 8 9]]จากนั้นจัดเรียงแถว


66 ไบต์rbindโดยหลีกเลี่ยง
Robin Ryder

@RobinRyder 59 ไบต์ - บนอุปกรณ์เคลื่อนที่ดังนั้นฉันจะแก้ไขในภายหลัง
Giuseppe


1

อ็อกเทฟ 102 ไบต์

n=input('');A=B=vec2mat(1:n*n,n);i=j=0;do
B(++i,:)=A(++j,:);if++j<n
B(n-i+1,:)=A(j,:);end;until j>=n
B

ลองออนไลน์!


ดี! ฉันไม่ทราบว่า Octave มีuntilคำสั่งและฉันไม่รู้vec2mat:( น่าเสียดายที่ความยาวเท่ากัน: A=B=vec2mat(1:(n=input(''))*n,n):(
Stewie Griffin

while j++<nยังมีความยาวเท่ากัน ... คุณลองใช้ตัวเลือกที่หลากหลายหรือว่าเป็นเรื่องบังเอิญ?
Stewie Griffin

@StewieGriffin ในกรณีนี้whileลูปมีความยาวเท่ากันฉันลองทั้งสองวิธี มักจะdo ... untilเป็นหนึ่งไบต์สั้นกว่าwhile ... endแม้ว่า
Steadybox

1

C (gcc) , 110 ไบต์

i,c,t,b;f(a,n)int*a;{for(b=n-1;i<n*n;t++,b--){for(c=0;c<n;)a[t*n+c++]=++i;for(c=0;c<n&i<n*n;)a[b*n+c++]=++i;}}

ลองออนไลน์!

เติมอาร์เรย์โดยสลับระหว่าง 2 ดัชนีสำหรับแถวหนึ่งดัชนีเริ่มต้นที่ด้านบนและอีกหนึ่งเริ่มต้นที่ด้านล่าง ดัชนีแถวบนสุดเริ่มต้นที่ 0 และเพิ่มขึ้นทุก 2 แถว ดัชนีแถวล่างเริ่มต้นที่ n-1 และจะลดลงทุก 2 แถว

Ungolfed:

void f(int* a, int n)
{
    //i = value to be written [1,n]; c = column index; t = top row index; b = bottom row index
    for(int i=1, c=0, t=0, b=n-1;
        i <= n*n; //when i = n*n, we have written all the values and we're done
        t++, b--) //t increments every 2 rows, b decrements every 2 rows
    {
        //write out 2 rows per loop

        //first row: fill out row at t
        for(c=0; c<n; c++, i++)
            a[t*n+c]=i;

        //second row: fill out row at b
        //this step will be skipped on the final loop for odd values of n, hence the (i<=n*n) test
        for(c=0; c<n && i<=n*n; c++, i++) 
            a[b*n+c]=i;
    }
}

1

C ++ + ช่วง V3 , 159 ไบต์

#include<range/v3/all.hpp>
using namespace ranges::view;

[](int n){auto r=iota(1,n*n+1)|chunk(n);return concat(r|stride(2),r|reverse|drop(n%2)|stride(2));}

ถ่ายทอดสดบน Wandbox

ไม่นับ 2 newlines หลังusing namespace range::view; พวกเขาอยู่ที่นั่นเพียงเพื่อแยกการนำเข้าจากแลมบ์ดา

ข้อเท็จจริงที่น่าสนใจอย่างไม่น่าเชื่อ: โซลูชันนี้ไม่มีการจัดสรรฮีป มันแก้ปัญหาในO(1)อวกาศ


คำอธิบาย:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n): ทุกnองค์ประกอบเข้าด้วยกันดังนั้น[1 ... n] [n+1 ... 2*n] ...
  3. เรียกได้ว่า r
  4. r | stride(2): ใช้ทุกองค์ประกอบอื่น ๆ : [1 ... n] [2*n+1...] ...
  5. เรียงต่อกันด้วย:
  6. r | reverse | drop(n % 2): reverse จากนั้นให้วาง[1 ... n]คำว่าnเป็นเลขคี่ (จะมีจำนวนแถวคี่และเราต้องการพิมพ์เทอมแรกเพียงครั้งเดียว) ดูเหมือนว่าฉันควรจะสามารถทำได้r | reverse | takeแต่นั่นไม่ได้ด้วยเหตุผลบางอย่าง
  7. stride(2)อีกครั้งใช้องค์ประกอบอื่น ๆ คราวนี้มันกลับด้าน

อ่านเพิ่มเติมและทดสอบได้:

#include <range/v3/all.hpp>
using namespace ranges::view;

auto f(int n)
{
    auto rows = iota(1, n * n + 1)
        | chunk(n);
    return concat(
        rows | stride(2),
        rows
            | reverse
            | drop(n % 2)
            | stride(2));
}

#include <iostream>
int main(int argc, char** argv)
{
    std::cout << "N = " << argc << '\n';
    auto res = f(argc);

    for (auto const& row : res | bounded) {
        for (auto const& elem : row | bounded) {
            std::cout << elem << ' ';
        }
        std::cout << '\n';
    }
}

O (log (n)) สำหรับเก็บอินพุตถ้าวัดด้วยความซับซ้อนของบิต
user202729

@ user202729 ไม่แน่ใจว่าคุณหมายถึงอะไร คุณกำลังบอกว่าสำหรับint nฉันต้องlog(n)บิตเพื่อเก็บอินพุต? แต่นั่นคืออินพุตต่อไปและเรากำลังจัดการกับintที่sizeof(int) == 4(ระบบส่วนใหญ่) ดังนั้นจึงมีจำนวนไบต์คงที่โดยไม่คำนึงถึงอินพุต
Justin




โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.