以下の形式を最小バイトで印刷するにはどうすればよいですか?


20

この課題は、これに触発され、現在削除された質問です。


入力として正の整数Nを取り、以下のパターンに従う数値1 .. N 2の行列を出力します。

最初の行に1 .. Nを入力し、最後の行(行番号N)に(N + 1).. 2Nを入力してから、2番目の行に(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はい、デフォルトで許可されています。
マーティンエンダー

1
タイトルは削除された質問から取られていると思いますが、あまり検索できないので(だまされやすい人を見つけるためなど)、より良い質問に変更できますか?
user202729

1
「出力形式は柔軟です」ので、行から行に番号が付けられた1次元配列を出力できますか?(例:)1 2 3 7 8 9 4 5 6出力形式は柔軟ですか?
オリビエグレゴワール

4
APLソリューションは、おそらく古いペルシャ楔形文字の単一の文字です。
マーク

回答:


7

05AB1E13 8バイト

Rodのおかげで5バイト節約

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

ルビー、53バ​​イト

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

説明:

最初にすべての数値を単一の配列に入れてから、反復ごとに1行スキップして配列をスライスします。最初の(n / 2 + n%2)反復の後、スキップするものは何もありません。その後、残りのすべての行を後方に取得します。

オンラインでお試しください!



4

JavaScript、68バイト

@ user71546によって調整された3バイトの編集を編集

最初に、明らかなルート従ってください。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...)で終了しますが、STDOUTではなくSTDERRにあります。

説明:

最初の行は、単にコピーをNレジスタに保存します。

2行目は、出力行から1を減算しN、これに乗算しN、それをスタックの一番下まで回転させてから、スタック全体を反転させることにより、各出力行のオフセットを構築します。スタックの一番上の数値が0に達すると、スタックは次のようになります(例ではを使用N=5)。

5 15 20 10 0 0

3行目0は、スタックの先頭から重複を破棄します。

4行目は、スタックの最上部をインクリメントし、そのコピーを出力します。次いで、これをMODを取られN、これは空白や改行を印刷すべきかどうかを決定するために使用され、スタックの最上部を廃棄する必要がある場合-印刷最後の番号である場合x、次いで、x mod N == 0その出力行の終わりに達したことを示します。1+空のスタックで実行されると実行が終了し、終了エラーがスローされます。

前のバージョン

これは、実行を終了するために空のスタックを明示的にチェックし、-vフラグの使用のために3バイトも含めていました。

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

オンラインでお試しください!


このメタによると、フラグをバイトカウントに追加しなくなったため、フラグを使用するように指定するだけで十分です。
エミグナ

@Emigna O_Oはそれをありがとう!よろしく
ソク


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
次の位置を変更することで3バイトを保存できますj++102バイト
ケビンクルーイッセン

1
そして、もう1バイトn-i/2-1n+~i/2 101
ケビンクルーッセン

@KevinCruijssenありがとう!完全にゴルフされたものではなく、どういうわけか生のバージョンを投稿しました。私の間違い、最初の問題は取り組まれましたが、2番目の問題は取り組まれませんでした。しかし、あなたはそれらを書いたので、あなた
オリビエグレゴワール

注:どういうわけか1次元配列が受け入れられる場合、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;}
オリビエグレゴワール

2

JavaScript(ES6)、69 68バイト

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

まあ、投稿する前にアウトゴルフされましたが、とにかくここにあります。編集:@KevinCruijssenのおかげで1バイトを保存しました。


n+n-i-1n+n+~i-1バイトの可能性があるため、他のJavaScriptの回答とつま先でやり直します。:)
ケビンクルーイッセン

@KevinCruijssen本当にありがとう!
ニール

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

スタックス、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

R70 59 47バイト

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

オンラインでお試しください!

4バイトのゴルフをしてくれたRobin Ryderに感謝します。

マトリックスを返します。matrixを順番に作成します(例[[1 2 3] [4 5 6] [7 8 9]]:)、次に行を再配置します。


を避けて66バイトrbind
ロビンライダー

@RobinRyder 59バイト -モバイルでは、後で編集します
ジュゼッペ


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長さもまったく同じです...さまざまなオプションを試しましたか、それとも偶然ですか?
ウィーグリフィン

@StewieGriffinこの場合、whileループは同じ長さなので、両方の方法で試しました。ただし、多くのdo ... until場合while ... end、よりも1バイト短くなります。
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つのインデックスを交互に配置して配列を埋めます。1つは上から始まり、もう1つは下から始まります。一番上の行のインデックスは0から始まり、2行ごとに増加します。最下行のインデックスはn-1から始まり、2行ごとにデクリメントされます。

ゴルフをしていない:

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つの改行をカウントしない 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):逆に、奇数の[1 ... n]場合nは用語を削除します(行の数が奇数になるため、最初の用語を1回だけ印刷します)。私はちょうどできるはずのようです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)ビットが必要だと言っていますか?しかし、とにかくそれが入力であり、intwhere sizeof(int) == 4(ほとんどのシステム)を扱っているため、入力に関係なく一定のバイト数が使用されます。
ジャスティン




弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.