連続する奇数の合計


24

関連する 課題を尋ねてきた、この1は、独自の質問を正当化するのに異なっています。


チャレンジ

正の整数を指定すると、その合計が指定された整数である連続した正の奇数整数の最長シーケンスを返します。そのようなシーケンスが存在しない場合、偽の値を返す、例外をスローするなど、言語にとって意味のある方法でエラーを報告できます。

テストケース

  1-> [1]
  2-> []
  3-> [3]
  4-> [1、3]
  5-> [5]
  6-> []
  9-> [1、3、5]([9]は有効な答えではないことに注意してください)
 15-> [3、5、7]
104-> [23、25、27、29]([51、53]は​​有効な答えではないことに注意してください)

得点

これはであるため、各言語の最短の回答が優先されます。


2
解決策がない場合、私のプログラムは永遠に実行できますか?
デニス

非常に関連しています。いくつかの偶数がこの数字で表現できないという事実は、それがだまされないようにするかもしれません。
-ETHproductions

6
15は[-1、1、3、5、7]を与えることはできませんか?正の値のみが許可されている場合は、そうする必要があります。
XNOR

2
@ЕвгенийНовиков17をスキップしました
kalsowerus

1
@kalsowerusはい。I誤解言葉「連続した」
ЕвгенийНовиков

回答:


11

Haskell、67 65 63 62 58バイト

ジュリアン・ウルフのおかげで4バイト節約

f x=[[2*n+1,2*n+3..2*m]|n<-[0..x],m<-[n..x],m^2-n^2==x]!!0

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

数値が2つの正方形の差として表現できるかどうかを確認しますm^2-n^2。その後、連続する奇数のリストを作成できます[2n+1,2n+3...2m-1]。最小値nが選択されているため、最も長いリストが出力されることに注意してください


7
ダウン投票:特に新しいユーザーをダウン投票する場合、理由を示すコメントを追加すると、より友好的かつ建設的になります。
ジョナサンアラン

1
私は何かが欠けていない限り、あなただけに上がっていくことにより、4つのバイトを保存することができますx両方のためにnm
ジュリアンウルフ

あなたが知っているように、あなたが答えを編集したときに、ダウン票はコミュニティユーザーによって自動的にキャストされました。これはバグだと思います。(CC @JonathanAllan)
デニス

ああ、それはそれらの一つでした。
ジョナサンアラン

9

パイソン266の 62バイト

f=lambda n,k=0,*r:n-sum(r)and f(n,k+1,*range(k%n|1,k/n,2))or r

解決策がない場合は、RuntimeErrorで終了します(最大再帰深度を超過)。

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


1
入力値が十分に高いが、解決策がある場合、これはRuntimeErrorになりますか?
Okx

再帰制限が十分に高くない場合、および/またはスタックが十分に大きくない場合、はい。ただし、物理的な制限を無視するのが一般的です(たとえば、Cの回答は32ビット整数に対してのみ機能する必要があります)。
デニス

9

ゼリー 11  10 バイト

-1デニスへのバイトおかげで(の暗黙の範囲の建物を使用する-置き換えるRm2ẆẆḤ’

ẆḤ’S_¥Ðḟ⁸Ṫ

可能な場合、または0そうでない場合、被加数のリストを返すモナドリンク。

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

どうやって?

ẆḤ’S_¥Ðḟ⁸Ṫ - Link: number, n
Ẇ          - all sublists (implicit range of input) note: ordered by increasing length
           -                i.e. [[1], [2], [3], ..., [1,2], [2,3], ..., [1,2,3], ...]]
 Ḥ         - double              [[2], [4], [6], ..., [2,4], [4,6], ..., [2,4,6], ...]]
  ’        - decrement           [[1], [3], [5], ..., [1,3], [3,5], ..., [1,2,5], ...]]
        ⁸  - link's left argument, n
      Ðḟ   - filter out items for which the following yields a truthy value:
     ¥     -   last two links as a dyad:
   S       -     sum
    _      -     subtract the right from the left = sum - n
         Ṫ - tail (last and hence longest such run)

1
ẆḤ’バイトを保存します。
デニス

8

JavaScript(ES7)、87 86 85 81バイト

整数のコンマ区切りリストを返します0。ソリューションが存在しない場合。

n=>(g=(s,k,x=n+s)=>(x**.5|0)**2-x?k>n?0:g(s+k,k+2):(n-=k)?k+','+g(-n,k+2):k)(0,1)

どうやって?

最初にx = n + sが別の完全な正方形であるような最小の完全な正方形sを探します。

sが存在する場合、nは2つの完全な正方形x-sであり、連続する奇数の2つのシーケンスの差として記述できます。次に、結果のリストを作成します。

例:

以下のためのN = 104

我々見つけるS =11²= 121れ満たすX = N + S = 225 =15²

次に:

15²= 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21 + 23 + 25 + 27 +
2911²= 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21
104 =15²-11²= 23 + 25 + 27 + 29


3
待って、それn^2が最初のn奇数の合計に常に等しいことを私に言っていますか?おもしろい
スキッズデフ

2
@Mayube 本当に
アーナルド


7

05AB1E9 8バイト

エミグナのおかげで-1バイト

ÅÉŒʒOQ}н

説明:

ÅÉ           Generate a list of odd numbers up to, and including, the input
  Π         Substrings
   ʒ         Only keep values
    O          where the sum
     Q         equals the input
       }     End
             For 9, the result would look like this:
             [[1, 3, 5], [9]]
        н    Get the first value

無効な入力では、何も出力しません。

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


ʒOQ}DO¹QÏバイトを保存する代わりに。
エミナ

それが...混乱してきた可能性があるので、@JonathanAllanドキュメントは、「ムラ」と言う
エリックOutgolfer

1
@JonathanAllan小さな間違い。一定。
Okx

6

ハスケル61 60バイト

1バイトを削る@maple_shaftに感謝します

f n=[k|r<-[1,3..],s<-[r,r+2..n],k<-[[r,r+2..s]],sum k==n]!!0

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

最長の実行は常に最小の番号から始まる実行になるという事実を使用します。

総当たり攻撃の代わりに算術を使って何かをしたかったのですkfromInteger、殺すようです。


[1,3..n][1,3..]
-maple_shaft

1
ヘルパー関数を使用して7バイトを保存できますr?n=[r,r+2..n]オンラインでお試しください!
Ørjanヨハンセン

4

Python、67バイト

f=lambda n,R=[1]:n-sum(R)and f(n,[R+[R[-1]+2],R[1:]][sum(R)>n])or R

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

前の連続した合計チャレンジからの回答をコピーし、に変更し+1ました+2。誰がゴルフのコードが非常にモジュール化できることを知っていましたか?

奇妙に単純な戦略:R目的の合計で間隔を検索します。

  • 合計が小さすぎる場合は、間隔の右端を2つ上にシフトし、その上に次の数字2を追加します。
  • 合計が大きすぎる場合は、最小の要素を削除して左端をシフトアップします
  • 合計が正しい場合、を出力しますR

間隔の下端は増加するだけなので、短い間隔の前に長い間隔が見つかります。可能な間隔が見つからない場合、IndexErrorで終了します。


4

JavaScript(ES6)、65 64バイト

f=(a,i=1)=>a>i?(c=f(a-i,i+=2))[0]==i?[i-2,...c]:f(a,i):a<i?0:[i]

解決策がある場合は配列を返し、解決策がない場合は0を返します。

これは、この問題に対する非常に非効率的でありながらゴルフのような解決策です。

これは、使用した最初のソリューションを検索a-iし、i=1それが再帰的なスタックをアップ動作しない場合でも、。そのソリューションがで始まらない場合、and i+2を使用して最初のソリューションを再帰的に検索します。ai+2

非ゴルフ

f=(a,i=1)=>
  a > i ? 
    (c = f(a - i, i += 2))[0] == i ? 
      [i-2, ...c] : 
      f(a, i) :
  a < i ? 
    0 :
    [i]

テストケース:

これがどれほど非効率かという考えについては、 f(104)みると、69,535の再帰呼び出しが必要なです。スタックの深さが51レベルを超えないため、スタックオーバーフローの問題はありません。

このソリューションにf(200)は、スタックが99レベルの深さで、860 万の再帰呼び出しが必要です。(その解決策は[11,13,15,17,19,21,23,25,27,29]です。)

実行中のプログラムの視覚的表現は次のとおりです。


3

パイソン2.7、109の 108 97バイト

アウトゴルファーのエリックに感謝します。

これは私の最初のコードゴルフです!

def f(N):
 for n in range(N):
    x=(n*n+N)**.5-n
    if x%1==0:return[2*(k+n)+1for k in range(int(x))]

使い方

私はよく知られているアイデンティティを使用しました 1 + 3 + 5 + ... + (2n - 1) = n²

のケースを取る 15

15 = 3 + 5 + 7 = (1 + 2) + (3 + 2) + (5 + 2) = (1 + 3 + 5) + 3×2 = 3² + 3×2

一般に、から始まるx個の用語がある場合2n + 1

(2n + 1) + (2n + 3) + (2n + 5) ... (2n + (2x-1))


等しい 2nx + x²

場合N、入力整数であり、問題は最大の発見に減少xするように

x² + 2nx - N = 0

それは解のある二次方程式です

x = sqrt(n² + N) - n

最長のシーケンスは、最大のシーケンスですx。プログラムn0to から反復し、それが整数であることがNわかるとx、リストを作成して(2n + 1) + (2n + 3) + (2n + 5) ... (2n + (2x-1))返します。



@EriktheOutgolferは、おかげで、私は(=タブを使用して忘れてしまった
dark32

3

Python 3、190 81バイト

def c(q,l,i):
    if sum(l)0:
        l.append(i)
        return c(q,l,i+2)
    elif sum(l)>q:
        l.pop(0)
        return c(q,l,i)
    else:
        print(l)
c(q,[1],1)

c=lambda q,l=[1]:c(q,l+[l[-1]+2])if(sum(l)<q)*l else c(q,l[1:])if sum(l)>q else l

@ovsと@ musicman523に感謝


4
インデントを削除するだけで、 122バイトまで減らすことができます。コードをさらに短くしたい場合は、Pythonでのゴルフのヒントをご覧ください。
-ovs

3
呼び出しは、これは、Pythonの3で実行されないprint括弧が欠落しています
musicman523

2
再帰呼び出しでl.append(i)使用するだけで削除できl+[i]ます。再帰呼び出しでl.pop(0)使用l[1:]して削除できます。c代わりにキーワード引数を使用して、一番下のへの呼び出しを削除できます。>02行目で削除できます。最後に、三項形式を使用してifand elseステートメントを式に変更できます。これにより、ラムダ式として92バイトになります。オンラインでお試しください!
musicman523

1
@ musicman523の提案に基づいて、条件を短縮iし、合計で81バイトにまで減らすことができます
ovs

に変更sum(l)>q elseq<sum(l)elseて1バイト節約できると思います。
ザカリー

2

QBIC、47バイト

{_Cg=q┘q=q+2~g>:|_Xp\?g,[q,a,2|?b,┘g=g+b~g=a|_X

これは合計が1になるまで1からすべての奇数を数えようとしますn。合格した場合n、ループをリセットし、1から3に増やして再試行します。ループの開始時にnumberの場合、0を出力して終了します> n

説明

{       Do infinitely
_C      Clear the screen (we basically print every run of odd numbers, but clear out everything that doesn't sum up to n)
g=q     Set g to the first num of this cycle (q starts as 1 in QBIC)    
┘       (Syntatcic linebreak)
q=q+2   Raise q to the next odd number, this sets up both the next outer loop as well as a coming FOR loop
~g>:|   If we start out with a number > n (read as 'a' from the cmd line)
_Xp     THEN quit, printing 0 (the value of the number var 'p')
\       ELSE
[q,a,2| FOR b = q, b <= n, b+=2
?b,┘    PRINT b followed by a tab
g=g+b   Add 'b' to running total 'g'
~g=a|   and if that lands us on 'n'
_X      QUIT (printing nothing: everything is already printed)

1

R、90バイト

f=function(x,y=1)'if'(length(w<-which(cumsum(r<-y:x*2-1)==x)),r[1:w],'if'(y>x,0,f(x,y+1)))

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

奇数のシーケンスに変換されたy:xのシーケンスの累積和をテストする再帰関数を使用します。yは、xを超えるまで再帰ごとに増分されます。ターゲットに合計される最初のシーケンスが返されます。


1

Python 2、89バイト

lambda n,r=range:[v for v in[r(1,n+1,2)[i:j]for i in r(n)for j in r(n+1)]if sum(v)==n][0]

正の整数を取りn、結果が存在する場合は結果を返し、IndexErrorそれ以外の場合は結果を返す、名前のない関数。

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

関連するすべての奇数番号のリストを作成r(1,n+1,2)しているがrange(start=1, stop=n+1, step=2)、それからスライスして、関連するすべてのサブスライス(プラスいくつかの空のもの)を作成i包括するjと排他的[i:j]横切っi[0、n)を 使用r(n)し、j[0、n]を使用してr(n+1)(空のものを場合i>=jまたはi)範囲外です。で正しい合計を持つものをフィルターしif sum(v)==nます; は、を使用して最初の(したがって最長の)そのようなスライスを返します[0]




1

PHP、73バイト

解決策は無限ループではありません

for($e=-1;$s-$i=$argn;)$s+=$s<$i?$n[]=$e+=2:-array_shift($n);print_r($n);

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

PHP、83バイト

解決策なしで何も印刷しない

すべての入力mod 4 == 2には解がありません

for($e=-1;($i=$argn)%4-2&&$s-$i;)$s+=$s<$i?$n[]=$e+=2:-array_shift($n);print_r($n);

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


解決できない入力の検出に失敗する
タイタス

@Titusは...固定
イェルクHülsermann

0

パイソン2122の 121 119 115バイト

musicman523のおかげで-1バイト。ステップ編のおかげで-4バイト。

def f(n,R=range):r=R(1,n,2);print[i for w in R(1,len(r)+1)for i in[r[j:j+w]for j in R(len(r)-w+1)]if sum(i)==n][-1]

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


1
これは関数として1バイト短くなります。オンラインでお試しください!
musicman523

再定義する場合はバイトを節約しrangeオンライン
スティーブン

これは1で失敗します。
デニス

0

Python 3、93バイト

lambda n,r=range:[[*r(s,e+1,2)]for s in r(1,n+1,2)for e in r(s,n+1,2)if(s+e)*(2+e-s)==4*n][0]

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

私がやった特別なことは、それ(s+e)*(2+e-s)==4*nがに等しいことsum(range(s,e+1,2))==nであり、同じサイズであるにもかかわらずr=range、前者をifステートメントの近くに配置できることに注目したことです。


0

Python 3、185バイト

def f(s):
  d={k:v for k,v in{a:(1-a+((a-1)**2+4*s)**(.5))/2 for a in range(1,s,2)}.items()if int(v)==v};m=max(d.keys(), key=(lambda k: d[k]));return list(range(int(m),int(m+2*d[m]),2))

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


これがどのように機能するかについては、単純なブルートフォース検索よりも少しエレガントなソリューションを探しました。算術シーケンスの合計の式を再配置し、2次式を適用(1-a+((a-1)**2+4*s)**(.5))/2して、コードに表示される式を取得しました。式が計算するのは、必要な合計sと算術シーケンスの最初の項が与えられると、シーケンスaの長さです。これらの長さは、キーとして最初の用語の値として辞書に保存されます。

次に、すべての非整数値は無効なシーケンスを表すため、辞書から削除されます。そこから、最大値はで識別されmax(d.keys(), key=(lambda k: d[k]))、その位置とその長さでの奇数のシーケンスはで作成されlist(range(int(m),int(m+2*d[m]),2))ます。


あなたが何かを見たら、私はこれをゴルフする助けを探しています。私は、自明でないアルゴリズムでどれだけうまくできるかを見ることにもっと興味がありました。私の答えは、最高のPythonソリューションのほぼ2倍です。


これは機能しますか?repl.it/JTt7(177バイト)
ザカリー

0

Mathematica、56バイト

Last@Cases[Subsequences@Table[n,{n,1,#,2}],x_/;Tr@x==#]&

Function最初の引数付き#Table[n,{n,1,#,2}]以下の正の奇数のリストを計算し#ます。Subsequencesそのリストのすべてのサブシーケンスを、長さの順に並べて返します。次に、Caseswhichマッチx_/;Tr@x==#xつまり、合計Tr@xがinputと等しくなるようなシーケンスを取ります#。次に、そのLastようなシーケンスを取ります。


0

JavaScript(ES6)、72バイト

n=>(g=s=>s?s>0?g(s-(u+=2)):g(s+l,l+=2):u-l?l+' '+g(s,l+=2):u)(n-1,l=u=1)

スペースで区切られた奇数の文字列を返すか、無効な入力でスローします。(適切な場合は空の)配列を返す84バイトバージョン:

n=>n%4-2?(g=s=>s?s>0?g(s-(u+=2)):g(s+l,l+=2):u-l?[l,...g(s,l+=2)]:[u])(n-1,l=u=1):[]

説明:再帰を使用していくつかのバイトを保存できたことを除いて、@ Cabbie407の連続整数の和に対するawkソリューションに大まかに基づいています。



0

C#(.NET Core)、129バイト

(i)=>{int s,j,b=1,e=3;for(;;){var o="";s=0;for(j=b;j<e;j+=2){s+=j;o+=j+" ";}if(s==i)return o;s=s<i?e+=2:b+=2;if(b==e)return"";}};

スペースで区切られた文字列で数値を出力します(他の文字は単にを変更する必要があります" ")。ソリューションなしの入力は空の文字列を返します(ただし、エラーなしで永久に実行することがソリューションなしを示す有効な方法である場合、17バイトを削除することで節約できますif(b==e)return"";)。

アルゴリズムは次のとおりです。

  1. [1]で開始
  2. 合計がターゲットに等しい場合、リストを返します
  3. 合計が目標よりも少ない場合は、次の奇数を追加します
  4. 合計が目標よりも大きい場合、最初のアイテムを削除します
  5. リストが空の場合、それを返します
  6. 2から繰り返す

あなたは書くことができます(i)=>ようi=>
aloisdgが復活モニカ言う

0

C ++、157-> 147バイト


DJMcMayhemのおかげで-10バイト

応答がない場合は0を返し、そうでない場合は1を返します

印刷する最後の行が答えです

int f(int n){for(int i=1;;i+=2){int v=0;for(int k=i;;k+=2){v+=k;std::cout<<k<<" ";if(v==n)return 1;if(v>n)break;}if(i>n)return 0;std::cout<<"\n";}}

なし:

int f(int n)
{
    for (int i = 1;; i += 2)
    {
        int v = 0;
        for (int k = i;; k += 2)
        {
            v += k;
            std::cout << k << " ";
            if (v == n)
                return 1;
            if (v > n)
                break;

        }
        if (i > n)
            return 0;
        std::cout << "\n";
    }
}

これは私の最初のコードゴルフです^^


int関数にして0または1を返した場合、バイトを節約できます。また、int v=0;代わりに行うこともできます。また、int v;....v=0;出力改行を区切るstd::cout<<k<<"\n";と、2番目の改行をすべて削除してから削除できます
DJMcMayhem

私は最後のrecomendationをした場合、それはすべての単一の番号に新しい行を印刷するだろうが、私は別々の番号グループにしたいが、とにかく-10バイトに感謝
SeeSoftware

0

Kotlin、152バイト

fun f(a:Double){var n=Math.sqrt(a).toInt()+1;var x=0;while(n-->0){if(((a/n)-n)%2==0.0){x=((a/n)-n).toInt()+1;while(n-->0){println(x.toString());x+=2}}}}

オンラインで試してみてください(4〜5秒待ってください、コンパイラは遅いです)

非ゴルフ

fun f(a: Double){
    var n=Math.sqrt(a).toInt()+1;
    var x=0;

    while(n-->0){
        if(((a/n)-n)%2==0.0){
            x=((a/n)-n).toInt()+1;

            while(n-->0){
                println(x.toString());
                x+=2;
            }

        }
    }
}

0

Excel VBA、139バイト

Subn予想される整数型の入力を受け取り、連続する奇数の最長シーケンスをセルに報告するルーチン[A1]

Sub a(n)
For i=1To n Step 2
s=0
For j=i To n Step 2
s=s+j
If s=n Then:For k=i To j-1 Step 2:r=r &k &"+":Next:[A1]=r &j:End
Next j,i
End Sub
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.