乗算で並べ替え


34

正の整数のリストを指定したプログラムまたは関数を作成して、各要素に可能な限り最小の正の整数を乗算して、厳密に増加するリストを作成する必要があります。

たとえば、入力が

5 4 12 1 3

乗算は

5*1=5 4*2=8 12*1=12 1*13=13 3*5=15

出力は増加するリストになります

5 8 12 13 15

入力

  • 少なくとも1つの要素を含む正の整数のリスト

出力

  • 正の整数のリスト

9 => 9
1 2 => 1 2
2 1 => 2 3
7 3 => 7 9
1 1 1 1 => 1 2 3 4
5 4 12 1 3 => 5 8 12 13 15
3 3 3 8 16 => 3 6 9 16 32
6 5 4 3 2 1 => 6 10 12 15 16 17
9 4 6 6 5 78 12 88 => 9 12 18 24 25 78 84 88
8 9 41 5 12 3 5 6 => 8 9 41 45 48 51 55 60
15 8 12 47 22 15 4 66 72 15 3 4 => 15 16 24 47 66 75 76 132 144 150 153 156

これはコードゴルフであるため、最短のプログラムまたは機能が優先されます。

楽しい事実:入力の出力の最後N, N-1, ... ,1(N+1)th要素は、シーケンスA007952の要素のようです。証拠が見つかった場合は、ゴルフの回答に含めるか、コメントとして投稿してください。


誰もまだその証拠に基づいていますか?
コナークラーク

回答:


20

ゼリー6 5 バイト

:‘×µ\

@Dennisが目を覚まして私を打ち負かす前に、 最初のゼリーの回答オンラインでお試しください!

説明

:          Integer division, m//n
 ‘         Increment, (m//n+1)
  ×        Multiply, (m//n+1)*n
   µ       Turn the previous links into a new monadic chain
    \      Accumulate on the array

-1バイトの@Dennisに感謝します。


4
:‘×µ\バイトを保存します。
デニス

20
@デニスああ、彼が目を覚ました
デニスヴァン

9

JavaScript(ES6)、28

編集 @Patrick Robertsが示唆するpように、初期化されていないパラメーターになります。同じバイト数ですが、グローバル変数の使用は避けてください

(a,p)=>a.map(n=>p=n*-~(p/n))

テスト

f=(a,p)=>a.map(n=>p=n*-~(p/n))

console.log=x=>O.textContent+=x+'\n'

;[
[[9], [ 9]],
[[1, 2], [ 1, 2]],
[[2, 1], [ 2, 3]],
[[7, 3], [ 7, 9]],
[[1, 1, 1, 1], [ 1, 2, 3, 4]],
[[5, 4, 12, 1, 3], [ 5, 8, 12, 13, 15]],
[[3, 3, 3, 8, 16], [ 3, 6, 9, 16, 32]],
[[6, 5, 4, 3, 2, 1], [ 6, 10, 12, 15, 16, 17]],
[[9, 4, 6, 6, 5, 78, 12, 88], [ 9, 12, 18, 24, 25, 78, 84, 88]],
[[8, 9, 41, 5, 12, 3, 5, 6], [ 8, 9, 41, 45, 48, 51, 55, 60]],
[[15, 8, 12, 47, 22, 15, 4, 66, 72, 15, 3, 4], [ 15, 16, 24, 47, 66, 75, 76, 132, 144, 150, 153, 156]]
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i),ok=(k+'')==(r+'')
  console.log(i + ' => ' + r + (ok?' OK':'FAIL expecting '+x))
})
<pre id=O></pre>


私が答えでやったように、モジュロを使うことで数バイト節約できると思います。
アロス

p = 0をスキップできませんか?複数のリストで複数実行する必要がありますが、質問は1つのリストのみです
チャーリーウィン

1
@CharlieWynn変数を初期化しないと、未定義の変数に対してエラーが発生します。偶然に変数がすでに存在する場合(Webページの環境で簡単に発生する可能性があります)、値が間違っている可能性があります。
edc65

@ edc65確かに、pはこのページで既に定義されています!
チャーリーウィン

1
@PatrickRobertsがもう一度考えて、私はまだグローバルを避けることができました:f=a=>a.map(n=>a+=n-a%n,a=0)。で、upvote arossように私は私をしておこうので、しかし、それは私のアルゴリズム(愚かな私)はありません
edc65

6

Python 2、67 64バイト

最初にコードゴルフをお試しください。ヒントをいただければ幸いです。

def m(l):
 for x in range(1,len(l)):l[x]*=l[x-1]/l[x]+1
 print l

こんにちは、私はあなたが(Windowsを使用して)各2バイトとしてラインリターンをカウントしていると思いますが、このサイトでは各ラインリターンをシングルバイトとしてカウントします。したがって、実際のスコアは65バイトです。(コードが不明な場合は、mothereff.in / byte-counterにコピーして貼り付けることができます。)また、別のバイトを保存するprint l代わりに行うこともできreturn lます。良くやった!
-mathmandan

おかげで、私はラインリターンについて知りませんでした。これが、常に異なるバイトカウントを常に持っている理由を説明しています。そして、印刷すれば十分であり、リストを返す必要がないとは考えていませんでした。
タロニュ

問題ない!ところで、「ヒントは大歓迎です」と述べたので、codegolf.stackexchange.com / questions / 54 /…を閲覧することに興味があるかもしれません。楽しい!
-mathmandan

5

PHP、55 46 42 41バイト

ISO 8859-1エンコードを使用します。

for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;

次のように実行します(-d美学のためにのみ追加):

php -d error_reporting=30709 -r 'for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;' 10 10 8
  • Ismael Miguelに1バイトthxを保存しました。
  • フロアの代わりにモジュロを使用して8バイトを節約
  • Ismael Miguelに4バイトthxを保存しました(foreachの代わりに)
  • を使用してスペースを生成することにより、バイトを保存しました。

私は、置き換えることができると思います$a+0+$a。また、入力にが決してないと想定0できるため、$a+0&&printを単にに置き換えることができます+$a&print。実際、$a&printPHP でも使用できます"0" == 0 == 0.0 == false。ただしecho、単に使用する場合は必要ないかもしれません。
イスマエルミゲル

バイナリandは(論理的ではなく)動作せず、このようにエコー動作しません。CLIから入力を取得しているため、最初の引数は-であり、ゼロを出力する代わりにキャッチします。試してくださいphp -r 'print_r($argv);' foo。ただし、最初の提案であるthxで1バイトを保存しました。
アロス

1
どうfor(;$a=$argv[++$i];)echo$l+=$a-$l%$a,' ';?長さは42バイトで、最初の要素をスキップします。
イスマエルミゲル

素敵なもの、thx @IsmaelMiguel
アロス

どういたしまして。本当に奇妙になりたい場合は、スペースをa^Aに置き換えることができますが、それはあまりにも多くの警告を流します(警告は無視できます)。バイトカウントは変更されませんが、見た目は異なります。
イスマエルミゲル

4

ハスケル(30 28 25バイト)

scanl1(\x y->y*div x y+y)

拡張版

f :: Integral n => [n] -> [n]
f xs = scanl1 increaseOnDemand xs
 where
   increaseOnDemand :: Integral n => n -> n -> n
   increaseOnDemand acc next = next * (1 + acc `div` next)

説明

scanl1リストを折りたたみ、すべての中間値を別のリストに蓄積できます。これはの特殊化でscanl、次のタイプがあります。

scanl  :: (acc  -> elem -> acc)  -> acc -> [elem] -> [acc]
scanl1 :: (elem -> elem -> elem) ->        [elem] -> [elem]

scanl1 f (x:xs) = scanl f x xs

したがって、必要なのは、リストの最後の要素(acc拡張バージョン)と処理したい要素(拡張バージョン)の2つを取りnext、適切な数値を返す適切な関数だけです。

アキュムレータを次のアキ​​ュムレータで除算し、結果をフローリングすることにより、この数値を簡単に導出できます。divそれの世話をします。その後、1リストを実際に増やしていることを確認するために追加する必要があります(最終的にはになりません0)。


関数に名前を付ける必要はありません。また、( ... )with $ ...を置き換えることができ、省略可能な最後の改行をカウントしたと思います:scanl1$\x y->y*div x y+y、24バイト。
ニミ

@nimi:本当ですか?式は重要ですか?とはいえ、演算子として解析され、後に1つのスペースが必要になるため、(...)vs $でバイトを保存しません。$\ $
ゼータ

名前のない関数はデフォルトで許可されてscanl1(...)おり、名前のない関数です。$():に関して、あなたは正しい、私の間違い。
-nimi

4

C ++、 63 60 57バイト

void s(int*f,int*e){for(int c=*f;++f!=e;c=*f+=c/ *f**f);}

与えられた範囲内で動作し[first, last)ます。元々はテンプレートバリアントとして記述されていましたが、それよりも長くなりました。

template<class T>void s(T f,T e){for(auto c=*f;++f!=e;c=*f+=c/ *f**f);}

拡張版

template <class ForwardIterator>
void sort(ForwardIterator first, ForwardIterator last){
    auto previous = *first;

    for(++first; first != last; ++first){
        auto & current = *first;
        current += current * (current / previous);
        previous = current;
    }
}

3

CJam、13バイト

q~{\_p1$/)*}*

CJamスタイルのリストとして入力します。出力は改行で区切られます。

ここでテストしてください。

説明

q~    e# Read and evaluate input.
{     e# Fold this block over the list (i.e. "foreach except first")...
  \   e#   Swap with previous value.
  _p  e#   Duplicate and print previous value.
  1$  e#   Copy current value.
  /   e#   Integer division.
  )*  e#   Increment and multiply current value by the result.
}*

最終値はスタックに残り、最後に自動的に印刷されます。


3

Mathematica 36 32バイト

 #2(Floor[#1/#2]+1)&~FoldList~#&

テスト

#2(Floor[#1/#2]+1)&~FoldList~#& /@ {{5, 4, 12, 1, 3}, 
   {15, 8, 12, 47, 22, 15, 4, 66, 72, 15, 3, 4}}
(* {{5, 8, 12, 13, 15}, {15, 16, 24, 47, 66, 75, 76, 132, 144, 
  150, 153, 156}} *)

3

Perl、17 + 3 = 20バイト

$p=$_*=$==1+$p/$_

必要-p-lフラグ:

$ perl -ple'$p=$_*=$==1+$p/$_' <<< $'15\n8\n12\n47\n22\n15\n4\n66\n72\n15\n3\n4'
15
16
24
47
66
75
76
132
144
150
153
156

説明:

# '-p' reads each line into $_ and auto print
# '-l' chomp off newline on input and also inserts a new line when printing
# When assigning a number to `$=` it will automatic be truncated to an integer
# * Added newlines for each assignment 
$p=
  $_*=
    $==
      1+$p/$_

3

Python(3.5)、63 62バイト

def f(a):
 r=[0]
 for i in a:r+=i*(r[-1]//i+1),
 return r[1:]

テスト

>>> print('\n'.join([str(i)+' => '+str(f(i)) for i in [[9],[1,2],[2,1],[7,3],[1,1,1,1],[5,4,12,1,3],[3,3,3,8,16],[6,5,4,3,2,1],[9,4,6,6,5,78,12,88],[8,9,41,5,12,3,5,6],[15,8,12,47,22,15,4,66,72,15,3,4]]]))
[9] => [9]
[1, 2] => [1, 2]
[2, 1] => [2, 3]
[7, 3] => [7, 9]
[1, 1, 1, 1] => [1, 2, 3, 4]
[5, 4, 12, 1, 3] => [5, 8, 12, 13, 15]
[3, 3, 3, 8, 16] => [3, 6, 9, 16, 32]
[6, 5, 4, 3, 2, 1] => [6, 10, 12, 15, 16, 17]
[9, 4, 6, 6, 5, 78, 12, 88] => [9, 12, 18, 24, 25, 78, 84, 88]
[8, 9, 41, 5, 12, 3, 5, 6] => [8, 9, 41, 45, 48, 51, 55, 60]
[15, 8, 12, 47, 22, 15, 4, 66, 72, 15, 3, 4] => [15, 16, 24, 47, 66, 75, 76, 132, 144, 150, 153, 156]

以前のソリューション

いくつかの再帰的な解決策がありますが、より大きい

(68 bytes) f=lambda a,i=0:[i,*f(a[1:],a[0]*(i//a[0]+1))][i==0:]if a!=[]else[i]
(64 bytes) f=lambda a,i=0:a>[]and[i,*f(a[1:],a[0]*(i//a[0]+1))][i<1:]or[i]

また、の代わりにr+=[…]、次を使用できますr+=…,
チョイス

私は定義されたとき、私は変更を加えることなく、@Cyoce r=[0]デフォルトパラメータでr非ローカルになる
エルワン・

あなたが正しい、私はPythonがデフォルトのパラメータをどのように処理したか忘れました。もう一方のヒントも機能するはずです
チョイス

@Cyoceはい、ヒントをありがとう
Erwan

3

Brachylog、12バイト

{≤.;?%0∧}ᵐ<₁

各変数を数値で乗算しようとすると、0または1ではなく2で乗算しようとすると不思議になります。

説明

{       }ᵐ          --  Map each number
 ≤.                 --      to a number greater or equal to the original
  .;?%0             --      and a multiple of the original
       ∧            --      no more constraints
          <₁        --  so that the list is strictly increasing

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


2

Brachylog、54バイト

:_{h_.|[L:T],LhH,(T_,IH;0:$Ie*H=:T>I),Lb:I:1&:[I]rc.}.

説明

:_{...}.                § Call sub-predicate 1 with [Input, []] as input. Unify its output
                        § with the output of the main predicate


§ Sub-predicate 1

h_.                     § If the first element of the input is an empty list, unify the
                        § output with the empty list
|                       § Else
[L:T],LhH,              § Input = [L,T], first element of L is H
    (T_,IH              §     If T is the empty list, I = H
    ;                   §     Else
    0:$Ie*H=:T>I),      §     Enumerate integers between 0 and +inf, stop and unify the
                        §     enumerated integer with I only if I*H > T
Lb:I:1&                 § Call sub-predicate 1 with input [L minus its first element, I]
:[I]rc.                 § Unify the output of the sub-predicate with
                        § [I|Output of the recursive call]

2

Pyth、11

t.u*Yh/NYQ0

テストスイート

累積リデュースを実行します。リデュースは、から始まるすべての中間値を返します0。入力には正の整数のみが含まれることが保証されているため、これは問題ありません。各ステップで、古い値を取得し1、それを新しい値で割ってadd し、新しい値で乗算します。


2

C、79バイト

p;main(x,v)char**v;{for(;*++v;printf("%d ",p=((x+p-1)/x+!(p%x))*x))x=atoi(*v);}

非ゴルフ

p; /* previous value */

main(x,v) char**v;
{
    /* While arguments, print out x such that x[i] > x[i-1] */
    for(;*++v; printf("%d ", p = ((x+p-1)/x + !(p%x)) * x))
        x = atoi(*v);
}

動作しませんp=p/x*x+xか?
ニール

@ニールええ、それはうまくいくでしょう。間違いなくこれを考え直した:)
コールキャメロン

2

PowerShell、26バイト

$args[0]|%{($l+=$_-$l%$_)}

> .\sort-by-multiplying.ps1 @(6,5,4,3,2,1)介して、入力を明示的な配列として受け取ります$args[0]

次に、でforループし|%{...}、各反復でmagicを実行します。(私はそれを見つけたので@arossに小道具いや、冗談では、我々は他の回答と同じモジュロトリックを使う最初)。

カプセル化された括弧(...)は、算術演算の結果がパイプラインに置かれ、したがって出力されることを保証します。これらを省略した場合、$l変数は実行の終了後にガベージコレクションされるため、何も出力されません。

PS C:\Tools\Scripts\golfing> .\sort-by-multiplying.ps1 @(8,9,1,5,4)
8
9
10
15
16


1

05AB1E、11バイト

コード:

R`[=sŽDŠ/ò*

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

説明:

R            # Reverse input
 `           # Flatten the list
  [          # While loop
   =         # Print the last item
    s        # Swap the last two items
     Ž       # If the stack is empty, break
      D      # Duplicate top of the stack
       Š     # Pop a,b,c and push c,a,b
        /    # Divide a / b
         ò   # Inclusive round up
          *  # Multiply the last two items

CP-1252エンコードを使用します。


1

Minkolang 0.15、17バイト

nd1+?.z0c:1+*d$zN

ここで試してみてください!

説明

nd                   Take number from input and duplicate it
  1+                 Add 1
    ?.               Stop if top of stack is 0 (i.e., when n => -1 because input is empty).
      z              Push value from register
       0c            Copy first item on stack
         :           Pop b,a and push a//b
          1+         Add 1
            *        Multiply
             d$z     Duplicate and store in register
                N    Output as number

基本的に、レジスタは昇順リストの最新のメンバーを保持し、これを入力で除算して増分し、次のメンバーの乗数を取得します。Minkolangのコードフィールドのトロイダル機能は、()or []ループを必要とせずに水平方向にループすることを意味します。


1

Brachylog、21バイト

l~lCℕ₁ᵐ≤ᵛ~+?&;Cz≜×ᵐ<₁

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

入力値の合計を次のように使用します 上限を係数Cの。5または6を超える入力リストの長さ(値の合計に応じて)でTIOでタイムアウトがかなり遅くなります。しかし、タイムアウトしないように、小さな値を持つ最大3つの要素の小さなリストを必要とする私のオリジナルバージョンほど遅くはありません。

21バイト

l~l.&+^₂⟦₁⊇.;?z/ᵐℕ₁ᵐ∧

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




0

Oracle SQL 11.2、210バイト

WITH v AS(SELECT TO_NUMBER(COLUMN_VALUE)a,rownum i FROM XMLTABLE(('"'||REPLACE(:1,' ','","')||'"'))),c(p,n)AS(SELECT a,2 FROM v WHERE i=1UNION ALL SELECT a*CEIL((p+.1)/a),n+1 FROM c,v WHERE i=n)SELECT p FROM c;

ゴルフをしていない

WITH v AS                                           
(
  SELECT TO_NUMBER(COLUMN_VALUE)a, rownum i            -- Convert the input string into rows 
  FROM   XMLTABLE(('"'||REPLACE(:1,' ','","')||'"'))   -- using space as the separator between elements
)
, c(p,n) AS                        
(
  SELECT a, 2 FROM v WHERE i=1                         -- Initialize the recursive view
  UNION ALL 
  SELECT a*CEIL((p+.1)/a),n+1 FROM c,v WHERE i=n       -- Compute the value for the nth element
)
SELECT p FROM c;

0

Chezスキーム(140バイト)

ゴルフバージョン:

(define(f l)(define(g l p m)(cond((null? l)l)((<(*(car l)m)(+ p 1))(g l p(+ m 1)))(else(cons(*(car l)m)(g(cdr l)(* m(car l))1)))))(g l 0 1))

非ゴルフバージョン:

(define(f l)
  (define(g l p m)
    (cond
      ((null? l) l)
      ((< (* (car l) m) (+ p 1)) (g l p (+ m 1)))
      (else (cons (* (car l) m) (g (cdr l) (* m (car l)) 1)))
    )
  )
  (g l 0 1)
)

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


* m(car l)することができます*(car l)m
ジョナサンフレッチ

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