この番号はレーシアンですか?


33

正の整数kは、次の場合、レーシアン数です。

  • ki*i + j*j + i*jfor ij整数として表現できます。

たとえば、最初の正のロジアン数は次のとおりです。1i=1j=0); 3i=j=1); 4i=2j=0); 7i=2j=1); 9i=-3j=3); ... は、特定のに対して一意ではないことiに注意してください。例えば、も用いて生成することができます、。jk9i=3j=0

これらの数値の他の同等の特性は次のとおりです。

  • k表すことができるi*i + j*j + i*jためij負でない整数。(整数の各ペアについてij同じを与える非負整数のペアがありますk

  • k六角形のグリッド上でテッセレーションを形成する一連の連続した六角形があります(k = 4およびの図を参照k = 7)。(この特性のため、これらの数値はモバイルセルラー通信ネットワークに適用されます。)

  • シーケンスのOEISページでその他の特性を参照してください。

チャレンジ

正の整数が与えられた場合、それがレーシアン数あれば真の結果を出力し、そうでなければ偽の結果を出力します。

プログラムまたは関数は1000、データ型の制限まで、または1分未満で入力を処理する必要があります。

コードゴルフ。最短勝。

テストケース

次の数値は、真の結果を出力するはずです。

1, 4, 7, 12, 13, 108, 109, 192, 516, 999

次の数値は偽の結果を出力するはずです。

2, 5, 10, 42, 101, 102, 128, 150, 501, 1000

関連(@PeterTaylorによる)
ルイスメンドー

ブルートフォースアルゴリズムに関する注意:√kを反復する場合、いくつかのバイトcを犠牲にしてアルゴリズムの複雑さをO(n²)からO(n)に減らします。
ロッド

i, j non-negative integersまたは9 (i=-3, j=3)-それはどれですか?
タイタス

1
@タイタスああ、なるほど。整数i、jの各ペアには、同じkを与える非負のペアがあります
ルイスメンドー

回答:


17

ゼリー11 9 バイト

ÆF‘%3,2ḄȦ

オンラインでお試しください!または、すべてのテストケースを確認します

バックグラウンド

バイナリ二次形式に初等結果+ AB + B 2 A 2、著者はLöschian番号に関する以下の定理を証明します。

定理 16.a²+ ab +b²の形式になる非負整数の必要十分条件は、その素因数分解において、形式(6k + 1)ではない 3 以外のすべての素数が偶数になることです。指数。

関連で述べたようにOEISページのすべての整数に一致されているので、01又は2モジュロ3、数3が合同である唯一の素数である0、フォームの全ての数(+ 1 6K)は合同であります1次のように、定理は、代替的に述べることができます。

3 法とする 2に一致する nのすべての素因数が偶数の指数を持つ場合にのみ、非負の整数 n はレーシュアン数です

使い方

ÆF‘%3,2ḄȦ  Main link. Argument: n (integer)

ÆF         Yield the prime factorization of n, as prime-exponent pairs.
  ‘        Increment all primes and exponents, turning primes of the form 3k - 2
           into multiples of 3 and odd exponents into multiples of 2.
   %3,2    Reduce all incremented primes/exponents modulo 3/2.
           n is Löschian if and only if this does not result in a [0, 0] pair.
           Due to Jelly's form of vectorization, this yields [3, 2] if n = 1.
       Ḅ   Unbinary; convert each pair from base 2 to integer.
           Note that [x, y] = [0, 0] if and only if 2x + y = 0.
        Ȧ  All; return 1 if the result contains no zeroes, 0 otherwise.

17

網膜66 63 45 43 36バイト

^()(\1(?<1>.\1))+(\1(.(?(4).\4)))*$

Retinaと言うタイトルにもかかわらず、これは単なるロジスティック数の単項表現を受け入れる単なる.NET正規表現です。

入力999と1000は1秒未満で十分です。

オンラインでお試しください!(最初の行は改行で区切られたテストスイートを有効にし、次の2行は便宜上単項への変換を処理します。)

説明

解決策は、(inputを処理する必要がないため)入力がi*i + j*(i + j)iと非負の場合について記述できる分類に基づいており、これは最初の奇数の整数の合計にすぎjません。これをゴルフすることは、前方参照の興味深い練習でした。0n*nn

「前方参照」とは、参照するグループ内に後方参照を配置することです。もちろん、グループを最初に使用するときは、まだ後方参照するものがないため機能しませんが、これをループに入れると、後方参照は毎回前の反復のキャプチャを取得します。これにより、各反復でより大きなキャプチャを構築できます。これを使用して、三角形の数、正方形、フィボナッチ数などの非常にコンパクトなパターンを作成できます。

例として、二乗が最初のn奇数の整数の合計であるという事実を使用して、次のように二乗入力を一致させることができます。

(^.|..\1)+$

最初の反復では、値がまだない..\1ため\1機能しません。したがって、まず^.、1つの文字をグループにキャプチャし1ます。後続の反復で^.は、アンカーにより一致しなくなりましたが、現在..\1は有効です。前の反復よりも2文字多く一致し、キャプチャを更新します。この方法で、奇数の増加に一致し、各反復後に正方形を取得します。

残念ながら、この手法をそのまま使用することはできません。マッチング後i*ii同様に取得する必要がありjます。これを行うには、単純な(しかし長い)の方法は、マッチングがあるという事実を利用することであるi*i取るi私たちが撮影してきたように、反復をiグループで物事を1バランスグループを使用してこれを抽出することができますが、先ほどi言ったように高価です。

代わりに、この「連続する奇数の整数の合計」を記述する別の方法を見つけましたi。これは、最後にキャプチャグループを生成します。もちろん、i番目の奇数はちょうど2i-1です。これにより、各反復で前方参照を1だけ増加させることができます。これがこの部分です。

^()(\1(?<1>.\1))+

これ()により、空のキャプチャがグループにプッシュされます1(に初期化さiれます0)。これは^.|上記の簡単な解決策とほぼ同等ですが|、この場合の使用は少し複雑です。

次に、メインループがあります(\1(?<1>.\1))\1は前のものiと一致し、(?<1>.\1)グループ1をで更新しi+1ます。新しい に関しては、文字がi一致しました2i-1。まさに必要なもの。

完了したら、いくつかの正方形i*iと一致し、グループは1まだi文字を保持しています。

2番目の部分は、上で示した単純な正方形マッチングに近いものです。1今のところ、後方参照を無視しましょう。

(.(?(4).\1))*

これは、文字列の先頭にいないため(^.|..\4)*利用できないことを除いて、基本的にはと同じ^です。代わりに、.\1既にgroupを使用している場合にのみ追加を一致させるために、条件を使用します4。しかし、実際にはこれはまったく同じです。これは私たちに与えj*jます。

欠落している唯一のものはj*i用語です。計算にはまだ反復が必要j*jであるという事実を利用することで、これと組み合わせます。だから、各反復のために、我々はまた、カーソルを進めると。それをgroupに書き込まないようにする必要があります。これは、一致する連続した奇数を混乱させるためです。それは私達が着く方法です:j*jji\14

(\1(.(?(4).\1)))*

2
これを何度も読めば読むほど、理解しにくくなります。多くの正規表現
ハビエル・ディアス

@JavierDiaz Java正規表現に基づいて、Stack Overflowの前方参照を説明する一連の投稿があります。そこの例はおそらく少し単純です。
マーティンエンダー

13

CJam(16 15バイト)

{mF{~\3%2=&},!}

オンラインデモ

これはブロック(「匿名関数」)であり、スタック上の入力を受け取り、スタック上0または1スタック上に置きます。奇数の多重度を持つ2 mod 3に等しい素因数がない場合、数値はレーシアンであるという特性を使用します。

デニスの1バイトの節約に感謝します。


うわー、素晴らしい特性評価!
ルイスメンドー

6

Python 2、56バイト

lambda n:any(n==i*i%n+i/n*(i/n+i%n)for i in range(2*n*n))

6

Haskell、42バイト

f k=or[k==i*i+j*j+i*j|i<-[0..k],j<-[0..i]]

使用例:f 501-> False

ifrom 0to kおよびjfrom 0toのすべての組み合わせを試行しiます。少なくとも1つの組み合わせが等しいかどうかをor返します。Truek==i*i+j*j+i*j

@flawrは、同じバイトカウントのわずかに異なるバージョンを見つけました。

f k|v<-[0..k]=or[(i+j)^2==k+i*j|i<-v,j<-v]

orcool =)については知りませんでしたが、おそらくこの代替フレーズをゴルフする方法を知っているでしょうf k|v<-[0..k]=or[(i+j)^2==k+i*j|i<-v,j<-v]か?
-flawr

@flawr:いいえ、あなたのバージョンをさらに下にゴルフする方法はわかりません。気にしない場合は、代替バージョンとして回答に追加します。
-nimi

5

Java 8、81バイト

k->{for(int i=0,j;i<=k;i++)for(j=0;j<=k;)if(i*i+j*j+i*j++==k)return 1;return 0;};

シンプルでナイーブな実装。偶然C#と同じコードですが、では->なくを使用しています=>


中括弧と終了を省略できるため、3バイト少なくなります;。くそー!
TheLethalCoder

@TheLethalCoder私は実際にできない、私はミスを犯した-C#と同じバイト数。
ジャスティン

とにかく気分が良くなる:)
TheLethalCoder

これは、陰性iまたはをテストしていないようですj
タイタス


4

ゼリー15 14 13 12 バイト

マイルのおかげで1バイト。

²S+P
‘ṗ2’Ç€i

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

小さいテストケースを確認します

多数(50を超える)をテストする場合のアドバイス:しないでください。

Truthyは正の数です。Falseyはゼロです。

説明

‘ṗ2’Ç€i   main chain, argument: z
‘ṗ2’      generate all pairs of numbers between 0 and z inclusive
    ǀ    apply the helper link to each pair
      i   find the index of z in the result

²S+P   helper link, argument: [x,y] (a pair of numbers)
²      compute [x*x, y*y]
 S     x*x+y*y
  +P   x*x+y*y+x*y

今は縛られています... :-)
ルイスメンドー

ピーターの特性評価を活用すべきか...?
ルイスメンドー

@LuisMendoそれは興味深いように見えますが、それはもっと長くなるようです
リーキー修道女

平らにする必要はないと思います。ヘルパーリンクは既にタプルから整数にマッピングされています。
マイル

@milesそれは賢い、ありがとう。
リーキー修道女


3

MATL14 13バイト

t:0hU&+HM&*+m

オンラインでお試しください!または、すべてのテストケースを確認します

出力1または0

説明

t:    % Implicitly input number k. Duplicate. Generate vector [1 2 ...k]
0h    % Concatenate a 0. Gives [1 2 ... k 0]
U     % Square, element-wise. Gives [1 4 ... k^2 0]
&+    % Sum of all pairs from this vector. Gives a (k+1)×(k+1) matrix
HM    % Push [1 2 ... k 0] again
&*    % Product of all pairs from this vector. Gives a (k+1)×(k+1) matrix
+     % Add the two matrices
m     % True if k is a member of the resulting matrix. Implicitly display

ゴルフゼリーから外れましたか?
リーキー修道女

@LeakyNunそれがどのくらい続くか見てみましょう。コードの説明を少し遅らせるかもしれません:-P
ルイスメンドー

いや。– – – – –
リーキー修道女

あなたの番– – –
リーキー修道女

@LeakyNun Aw :-(説明を追加できるようになりました:-)
ルイス・メンド

3

Python、49バイト

lambda n:0in[(n-3*i*i+0j)**.5%1for i in range(n)]

のOEISで指定された同等の2次形式を使用しn == 3*i*i+j*jます。かどうか確かめるn-3*i*ii平方根を取得し、それが整数である、つまり1を法とする0に等しいことにより、完全な正方形であるを確認します。+0jその負の平方根にエラーを回避するために、複雑な数になります。


3

C(gcc)、71 69バイト

i,j,r;f(n){for(r=i=n+1;i--;)for(j=n;j--;)r*=n!=i*i+j*j+i*j;return!r;}

69バイト:i,j,r;f(n){for(r=i=n+1;i--;)for(j=n;j--;)r*=n!=i*i+j*j+i*j;return!r;}
owacoder

これは、陰性iまたはをテストしていないようですj
タイタス

@Titus質問は、負でないiおよびを指示しjます。
-orlp

ポジティブkですが、そうではiありませんj。例をよく見てください。
タイタス

チャレンジから引用@Titus:kとして表現することができるi*i + j*j + i*jためi, j 、負でない整数。」 あなたは、詳しく見ていきます。
-orlp

2

C#、84 82 81バイト

k=>{for(int i=0,j;i<=k;++i)for(j=0;j<=k;)if(i*i+j*j+i*j++==k)return 1;return 0;};

ナイーブなソリューション。1 =真、0 =偽


2

VBA、68 67バイト

Function L(N):For a=0To N:For b=0To a:L=L+(N=a^2+a*b+b^2):Next b,a

素朴な検索。n= 1000でわずかに減速し始めます。Excelはゼロリターンを偽物として認識し、他のすべてのリターンは真実として認識します。

i> j> = 0が与えられているため、負のiおよびjの調査は必要ないことに注意してください。

(-i)2 +(-i)(-j)+(-j)2 = i 2 + ij + j 2

iおよびjの場合と同じ結果)

(-i)2 +(- i )j + j 2 = i 2 -ij + j 2

i 2 + i(-j)+(-j )2 = i 2 -ij + j 2

(負の場合はどちらでも構いません)、そして

(IJ)2 +(IJ)J + J 2 =(I 2 - 2ij + J 2)+(IJ - J 2)+ J 2 = I 2ij + J 2

また、(ij)jは両方とも非負であるため、負の数を含むレーシアン数の生成は、非負の数を使用して実現できます。


バイトを節約しましたNext:Next-> Next b,aTaylor Scottに感謝します。


これは、陰性iまたはをテストしていないようですj
タイタス

「その他の同等の特性」の最初のポイントを参照してください。すべてのテストケースが正しく表示されることに注意してください。答えに数学的な正当性を追加します(可能な場合)。
ジョファン

すみません、私のせいです。必要ないことを読み直してください。
タイタス

あなたが凝縮することができます@Joffan Next:NextNext b,a
テイラー・スコット

理由は行方不明であることを再び多分あなたのソリューションを見て@Joffan :End Functionソリューションの終わりに
テイラー・スコット

1

Javascript(外部ライブラリを使用-列挙可能)(63バイト)

k=>_.Range(0,k+1).Any(i=>_.Range(0,k+1).Any(j=>i*i+j*j+i*j==k))

ライブラリへのリンク:https : //github.com/mvegh1/Enumerable コードの説明:0〜kの整数範囲を作成し(これを「i」範囲と呼びます)、「i」が特定の述語を満たすかどうかをテストします。その述語は0〜kの範囲を作成し(これを「j」範囲と呼びます)、「j」が特定の述語を満たすかどうかをテストします。その述語はレーシェ式

enter image description here


1

Perl 6の 52の51  50バイト

->\k{?first ->(\i,\j){k==i*i+j*j+i*j},(0..k X 0..k)}
->\k{?grep ->(\i,\j){k==i*i+j*j+i*j},(0..k X 0..k)}

{?grep ->(\i,\j){$_==i*i+j*j+i*j},(0..$_ X 0..$_)}

説明:

{
  # Turn the following into a Bool
  # ( Technically not necessary as a list of 1 or more values is truthy )
  ?

  # find all where the code block returns a truthy value
  grep

  # pointy block that takes one value (list of 2 values)
  # and gives each of the values in it a name
  ->
    $ ( \i, \j )
  {
    # return true if the definition matches
    $_ == i*i + j*j + i*j
  },

  # a list of 2 element lists (possible i and j values)
  ( 0..$_ X 0..$_ )
}

テスト:

use v6.c;
use Test;

my @true = 0, 1, 4, 7, 12, 13, 108, 109, 192, 516, 999;
my @false = 2, 5, 10, 42, 101, 102, 128, 150, 501, 1000;

plan (@true + @false) * 2;

my &is-loeschian = {?grep ->(\i,\j){$_==i*i+j*j+i*j},(0..$_ X 0..$_)}

for |(@true X True), |(@false X False) -> ( $input, $expected ) {
  my ($result,$seconds) = $input.&time-it;
  is $result, $expected, ~$input;
  cmp-ok $seconds, &[<], 60, "in $seconds seconds"
}

sub time-it ( $input ) {
  my $start = now;
  my $result = $input.&is-loeschian;
  my $finish = now;
  return ( $result, $finish - $start )
}
1..42
ok 1 - 0
ok 2 - in 0.00111763 seconds
ok 3 - 1
ok 4 - in 0.00076766 seconds
...
ok 19 - 516
ok 20 - in 0.19629727 seconds
ok 21 - 999
ok 22 - in 0.1126715 seconds
ok 23 - 2
ok 24 - in 0.0013301 seconds
ok 25 - 5
ok 26 - in 0.00186610 seconds
...
ok 37 - 150
ok 38 - in 0.83877554 seconds
ok 39 - 501
ok 40 - in 9.2968558 seconds
ok 41 - 1000
ok 42 - in 37.31434146 seconds

これは、陰性iまたはをテストしていないようですj
タイタス

@Titus (0..$_ X 0..$_)場合は空のリストを生成$_未満である0ので、そこに否定的に確認する必要はありませんiし、j彼らが負になることはありませんので。True正のレーシアン数に対してのみ生成されることになっているので、負の場合に特別なことをする必要はありません。
ブラッドギルバートb2gills

9 = (3*3)+(-3*-3)+(3*-3)は正のレーシアンでi=3, j=-3、しかし、私はすべてのレーシアン数が非負iとを持っていることを忘れましたj。したがって、負の数を探す必要はありません。したがって、実際にはそれらのコメントを削除できます。盗聴して申し訳ありません。私のせい。
タイタス

@Titusはコードを変更して{grep ->(\i,\j){$_==i*i+j*j+i*j},(-$_..$_ X -$_..$_)}(9)結果を((-3,0),(-3,3),(0,-3),(0,3),(3,-3),(3,0))。正直なところ、私はおそらく他の答えからそれを適応させただけでしょう。
ブラッドギルバートb2gills

1

PowerShell v2 +、63 56 55バイト

param($k)(0..$k|%{0..($i=$_)|%{$i*($i+$_)+$_*$_}})-eq$k

入力を受け取り$k、上向きに2回ループし(外側のループ$i = 0 to $k、内側のループ$j = 0 to $i)、各反復でi*i + j*j + i*j(の短縮i*(i+j) + j*j)の結果が生成されます。これらの結果は括弧でカプセル化され、配列としてに渡され-eq$kます。これは、入力に等しい要素のみを選択するフィルターとして機能します。真実の場合はゼロ以外の値(戻り値)を出力し、偽の場合はゼロ(空)を出力します。1000私のマシンで約15秒で処理します。

テストケース

PS C:\Tools\Scripts\golfing> (1,4,7,12,13,108,109,192,516,999|%{.\loeschian-numbers.ps1 $_})-join','
1,4,7,12,13,108,109,192,516,999

PS C:\Tools\Scripts\golfing> (2,5,10,42,101,102,128,150,501,1000|%{.\loeschian-numbers.ps1 $_})-join','

PS C:\Tools\Scripts\golfing>

1

Perl、54 + 1(-nフラグ)= 55バイト

for$i(0..$_){for$j(0..$_){$i*$i+$j*$j+$i*$j-$_?1:say}}

実行する必要性-n-M5.010フラグ:

perl -nE 'for$i(0..$_){for$j(0..$_){$i*$i+$j*$j+$i*$j-$_?1:say}}'

数がレーシアン数である場合、いくつかのものを出力し、それ以外は何も出力しません。

この実装は非常に退屈なので、87バイトの正規表現ベースの目のためだけに別の実装を示します。

perl -pE '$_=(1 x$_)=~/^(.*)(??{$1x(-1+length$1)})(.*)(??{$2x(-1+length$2)})(??{$1x length$2})$/'

バックトラックは多くのメモリを使用するため、これに注意してください。大きすぎる数値をテストしようとしないでください!(特にレーシアンではない数字)


1

Dyalog APL、19 バイト

⊢∊(∘.(×-⍨2*⍨+)⍨0,⍳)

チェックもしk個の ε(I + J)² - IJ、任意の0≤用IJK

     k個
のメンバー
    ∘.のすべての組合せ
        × IJ
        -⍨から減算
        2*⍨の正方形
        + Iプラスjの
    全てについてのI 及び J
    0,前に付加ゼロ
    を通して整数1 K

1000は私のM540では3.3秒かかり、TryAPLではさらに短くなります。


1

Matlab、53 52バイト

n=input('');[a b]=ndgrid(0:n);find((a+b).^2-a.*b==n)

すべての可能性に対するシンプルな検索。
空の配列を偽として出力し、空でないベクトルを真の値として出力します。

すべてゼロの行列を虚偽、非ゼロの行列を真実と考えるとfind47 46バイトのソリューションをもたらす関数を取り除くことができます

n=input('');[a b]=ndgrid(0:n);(a+b).^2-a.*b==n

@flawrのおかげで1バイト節約


1
(a+b).^2-a.*b==n短いです。
-flawr


1

Mathematica、44バイト

MemberQ[(+##)^2-##&@@@0~Range~#~Tuples~2,#]&

入力として整数を取り、Trueまたはを返す名前のない関数False。このコマンド0~Range~#~Tuples~20、入力と入力の間の整数のすべての順序付きペアを作成します#。関数(+##)^2-##&は、引数の合計から引数の積を引いたものの2乗を計算します。2つの引数ijで呼び出されたとき、これはまさにi^2+j^2+ij望みどおりです。そのため、その関数はすべてのタプルで呼び出されMemberQ[...,#]、入力が結果値の1つであるかどうかをチェックします。


1

ASP、39 + 4 = 43バイト

o:-k=I*I+J*J+I*J;I=1..k;J=1..k.:-not o.

出力:kがLoeschianである場合、問題は充足可能です。

回答セットプログラミングは、プロローグに似た論理言語です。ここでは、ポタスコの実装であるclingoを使用します。

入力はパラメーターから取得されます(-ck=長さは4バイトです)。呼び出し例:

clingo -ck=999

出力サンプル:

SATISFIABLE

1000で試した:

clingo -ck=1000

出力サンプル:

UNSATISFIABLE

ブラウザで試してみてください。残念ながら、このメソッドは呼び出しフラグを処理しない#const k=999ため、動作させるために行を追加する必要があります。


未ゴルフ&説明コード:

v(1..k).  % predicate v(X) holds for any X in [1..k]
o:- k=I*I+J*J+I*J ; v(I) ; v(J).  % o holds if k is Loeschian.
:- not o.  % discard models where o doesn't holds (make problem unsatisfiable)

1

PHP、70バイト

for(;$i++<$k=$argv[1];)for($j=$i+1;$j--;)$i*$i+$j*$j+$i*$j-$k?:die(1);

コマンドライン引数から入力を受け取ります。1Loeschian番号の場合は0elseで終了します。
で実行し-nrます。

壊す

for(;$i++<$k=$argv[1];)     # loop $i from 1 to $k
    for($j=$i+1;$j--;)      # loop $j from $i to 0
        $i*$i+$j*$j+$i*$j-$k?   # if $i,$j,$k do not satisfy the equation, do nothing
        :die(1);                # else exit with return code 1
                            # implicit: exit with code 0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.