Urutkan berdasarkan Mengalikan

34

Anda harus menulis sebuah program atau fungsi yang memberikan daftar bilangan bulat positif mengalikan setiap elemen dengan bilangan bulat positif terkecil yang mungkin untuk membuat daftar yang semakin meningkat.

Misalnya jika inputnya adalah

5 4 12 1 3

multiplikasi akan menjadi

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

dan output akan menjadi daftar yang meningkat

5 8 12 13 15

Memasukkan

  • Daftar bilangan bulat positif yang mengandung setidaknya 1 elemen

Keluaran

  • Daftar bilangan bulat positif

Contohnya

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

Ini adalah kode golf sehingga program atau fungsi terpendek menang.

Fakta menyenangkan: elemen terakhir dari input untuk input N, N-1, ... ,1tampaknya menjadi (N+1)thelemen dari urutan A007952 . Jika Anda menemukan bukti, Anda dapat memasukkannya dalam jawaban golf Anda atau mempostingnya sebagai komentar.

randomra
sumber
Adakah yang sudah membuktikan bukti itu?
Connor Clark

Jawaban:

20

Jelly , 6 5 byte

:‘×µ\

Jawaban Jelly pertama sebelum @ Dennis bangun dan mengalahkan saya Cobalah online!

Penjelasan

:          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

Terima kasih kepada @ Dennis untuk -1 byte.

Sp3000
sumber
4
:‘×µ\menghemat satu byte.
Dennis
20
@ Dennis Oh, sial dia bangun
Dennis van Gils
9

JavaScript (ES6), 28

Sunting Seperti yang disarankan oleh @Patrick Roberts, pbisa menjadi parameter yang tidak diinisialisasi. Jumlah byte yang sama tetapi hindari menggunakan variabel global

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

UJI

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>

edc65
sumber
Saya pikir Anda dapat menyimpan beberapa byte dengan menggunakan modulo, sama seperti yang saya lakukan dalam jawaban saya .
aross
Tidak bisakah kamu melewati p = 0? Anda memerlukannya untuk menjalankannya beberapa kali pada beberapa daftar tetapi pertanyaannya hanya untuk satu daftar
Charlie Wynn
1
@CharlieWynn jika Anda tidak menginisialisasi variabel, Anda mendapatkan kesalahan untuk variabel yang tidak ditentukan. Jika kebetulan variabel sudah ada (yang dapat dengan mudah terjadi di lingkungan halaman web), itu bisa memiliki nilai yang salah.
edc65
@ edc65 cukup yakin, p sudah ditentukan di halaman ini!
Charlie Wynn
1
@PatrickRoberts berpikir lagi, aku masih bisa menghindari GLOBALS: f=a=>a.map(n=>a+=n-a%n,a=0). Tapi ini bukan algoritme saya (konyol saya) jadi saya akan tetap milik saya apa adanya dan memperbaiki aross
edc65
6

Python 2, 67 64 byte

Pertama-tama coba kode-golf, jadi tipsnya sangat dihargai.

def m(l):
 for x in range(1,len(l)):l[x]*=l[x-1]/l[x]+1
 print l
Taronyu
sumber
Hai, saya pikir Anda menghitung pengembalian baris masing-masing 2 byte (menggunakan Windows?), Tetapi di situs ini Anda menghitung setiap pengembalian baris sebagai satu byte. Jadi skor Anda sebenarnya 65 byte. (Anda dapat menyalin dan menempelkan kode Anda ke mothereff.in/byte-counter jika Anda tidak yakin.) Selain itu, Anda dapat melakukan print lalih - alih return lmenyimpan byte lain. Pekerjaan yang baik!
mathmandan
Terima kasih, saya tidak tahu tentang pengembalian baris. Itu menjelaskan mengapa saya selalu mendapat jumlah byte yang berbeda. Dan saya bahkan tidak mempertimbangkan, bahwa pencetakan sudah mencukupi dan tidak perlu mengembalikan daftar.
Taronyu
Tidak masalah! BTW, karena Anda menyebutkan bahwa "tips dihargai", Anda mungkin tertarik menelusuri melalui codegolf.stackexchange.com/questions/54/… . Nikmati!
mathmandan
5

PHP, 55 46 42 41 byte

Menggunakan penyandian ISO 8859-1.

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

Jalankan seperti ini ( -dditambahkan hanya untuk estetika):

php -d error_reporting=30709 -r 'for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;' 10 10 8
  • Disimpan 1 byte thx ke Ismael Miguel.
  • Disimpan 8 byte dengan menggunakan modulo bukan lantai
  • Disimpan 4 byte thx ke Ismael Miguel (untuk bukannya foreach)
  • Menyimpan byte dengan menggunakan untuk menghasilkan spasi.
aross
sumber
Saya pikir Anda dapat menggantinya $a+0dengan +$a. Selain itu, Anda dapat mengasumsikan bahwa input tidak akan pernah memiliki 0, jadi, Anda dapat mengganti $a+0&&printdengan hanya +$a&print. Bahkan, Anda bahkan bisa melakukannya $a&print, karena di PHP "0" == 0 == 0.0 == false. Tetapi mungkin tidak diperlukan jika Anda hanya menggunakan echo, saya pikir.
Ismael Miguel
Biner andtidak akan bekerja (sebagai lawan dari logika), juga tidak akan bekerja dengan cara ini. Karena saya mengambil masukan dari CLI, argumen pertama adalah -, yang ingin saya tangkap alih-alih mencetak nol. Coba php -r 'print_r($argv);' foo. Disimpan 1 byte dengan saran pertama Anda, terima kasih.
aross
1
Bagaimana dengan for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,' ';? Panjangnya 42 byte dan melewatkan elemen pertama.
Ismael Miguel
Nice one, thx @IsmaelMiguel
aross
Sama-sama. Jika Anda ingin benar-benar keriting, Anda dapat mengganti spasi dengan a^A, tetapi itu akan menumpahkan terlalu banyak peringatan (peringatan tidak dapat diabaikan). Itu tidak akan mengubah bytecount dengan cara apa pun, tetapi surelly terlihat berbeda.
Ismael Miguel
4

Haskell (30 28 25 byte)

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

Versi yang diperluas

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)

Penjelasan

scanl1memungkinkan Anda untuk melipat daftar dan mengakumulasikan semua nilai antara ke dalam daftar lain. Ini adalah spesialisasi scanl, yang memiliki jenis berikut:

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

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

Oleh karena itu, yang kita butuhkan adalah fungsi yang sesuai yang mengambil dua elemen terakhir dari daftar kami ( accdalam versi yang diperluas) dan yang kami ingin proses ( nextdalam versi yang diperluas) dan mengembalikan nomor yang sesuai.

Kita dapat dengan mudah menurunkan angka ini dengan membagi akumulator melalui yang berikutnya dan mendasarkan hasilnya. divmengurus itu. Setelah itu, kita hanya perlu menambahkan 1untuk memastikan bahwa daftar tersebut benar-benar meningkat (dan kita tidak berakhir dengan 0).

Zeta
sumber
Tidak perlu memberi nama fungsi Anda. Anda juga dapat mengganti ( ... )dengan $ ...dan saya pikir Anda telah menghitung baris baru akhir yang dapat dihilangkan:, scanl1$\x y->y*div x y+y24 byte.
nimi
@nimi: Benarkah? Ekspresi dihitung? Yang sedang berkata, saya tidak menyimpan byte dengan (...)vs $, karena $\ akan diuraikan sebagai operator dan saya akan membutuhkan satu ruang setelah $.
Zeta
fungsi tanpa nama diizinkan secara default dan scanl1(...)merupakan fungsi tanpa nama. Mengenai $vs ().: Anda benar, kesalahan saya.
nimi
4

C ++, 63 60 57 byte

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

Pekerjaan di tempat diberikan rentang [first, last). Awalnya ditulis sebagai varian templat, tapi itu lebih lama:

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

Versi diperpanjang

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;
    }
}
Zeta
sumber
3

CJam, 13 byte

q~{\_p1$/)*}*

Masukan sebagai daftar gaya-CJam. Output dipisahkan linefeed.

Uji di sini.

Penjelasan

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.
}*

Nilai akhir ditinggalkan di tumpukan dan dicetak secara otomatis di akhir.

Martin Ender
sumber
3

Mathematica, 36 32 byte

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

Uji

#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}} *)
Jason B.
sumber
3

Perl, 17 + 3 = 20 byte

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

Membutuhkan -pdan -lmenandai:

$ 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

Penjelasan:

# '-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/$_
andlrc
sumber
3

Python (3.5), 63 62 byte

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

Uji

>>> 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]

Solusi sebelumnya

beberapa solusi rekursif tetapi lebih besar

(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]
Erwan
sumber
Selain itu r+=[…], Anda dapat menggunakanr+=…,
Cyoce
@Cyoce saya melakukan perubahan tetapi ketika saya mendefinisikan r=[0]parameter default rmenjadi nonlocal
Erwan
Anda benar, saya lupa bagaimana Python menangani params default. Tip lainnya harusnya berfungsi
Cyoce
@ Ayo ya berhasil, terima kasih atas tipsnya
Erwan
3

Brachylog , 12 byte

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

Cukup aneh mencoba untuk mengalikan setiap variabel dengan angka akan mulai mencoba mengalikan dengan 2 dan bukan 0 atau 1. Ini tampaknya bekerja dan mengalahkan kedua implementasi Brachylog lainnya

Penjelasan

{       }ᵐ          --  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

Cobalah online!

Kroppeb
sumber
2

Brachylog , 54 byte

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

Penjelasan

:_{...}.                § 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]
Fatalisasi
sumber
2

Pyth, 11

t.u*Yh/NYQ0

Test Suite

Apakah pengurangan kumulatif, pengurangan yang mengembalikan semua nilai perantara, dimulai dengan 0. Karena input dijamin hanya mengandung bilangan bulat positif, ini tidak masalah. Di setiap langkah, kami mengambil nilai lama, membaginya dengan nilai baru dan menambahkan 1, lalu kami mengalikannya dengan nilai baru.

FryAmTheEggman
sumber
2

C, 79 byte

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

Tidak disatukan

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);
}
Cole Cameron
sumber
Tidak akan p=p/x*x+xbekerja
Neil
@Neil Ya, itu akan berhasil. Pasti terlalu memikirkan yang satu ini :)
Cole Cameron
2

PowerShell, 26 byte

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

Mengambil input sebagai array eksplisit, mis . > .\sort-by-multiplying.ps1 @(6,5,4,3,2,1)Via $args[0].

Kami kemudian untuk mengulanginya dengan |%{...}dan setiap iterasi melakukan sihir . Nah, hanya bercanda, kami menggunakan trik modulo yang sama dengan jawaban lain (props ke @aross karena saya melihatnya di sana dulu).

Parens enkapsulasi (...) memastikan bahwa hasil operasi matematika ditempatkan pada pipa, dan dengan demikian output. Jika kita membiarkannya, tidak ada yang akan dihasilkan karena $lvariabel dikumpulkan sampah setelah eksekusi selesai.

Contoh

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

Japt, 11 byte

Uå@Y*-~(X/Y

Uji secara online!

Bagaimana itu bekerja

          // Implicit: U = input array of integers
Uå@       // Cumulative reduce: map each previous value X and current value Y to:
-~(X/Y    //  floor(X/Y+1).
          // Implicit: output last expression
Produksi ETH
sumber
1

05AB1E , 11 byte

Kode:

R`[=sŽDŠ/ò*

Cobalah online!

Penjelasan:

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

Menggunakan pengodean CP-1252.

Adnan
sumber
1

Minkolang 0,15 , 17 byte

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

Coba di sini!

Penjelasan

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

Pada dasarnya, register menyimpan anggota terbaru dari daftar naik dan ini dibagi dengan input dan bertambah untuk mendapatkan pengali untuk anggota berikutnya. Fitur toroidal bidang kode Minkolang berarti bahwa loop secara horizontal tanpa perlu ()atau []loop.

El'endia Starman
sumber
1

Brachylog , 21 byte

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

Cobalah online!

Menggunakan jumlah nilai input sebagai batas atas untuk koefisien C. Cukup lambat, time out pada TIO untuk panjang daftar input melebihi 5 atau 6 (juga tergantung pada jumlah nilai). Tapi tidak selambat versi asli saya, yang membutuhkan daftar kecil hingga 3 elemen, dengan nilai kecil, untuk tidak kehabisan waktu:

21 byte

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

Cobalah online!

sundar - Pasang kembali Monica
sumber
1

Python 2 , 53 byte

lambda a:reduce(lambda b,v:b+[b[-1]/v*v+v],a,[0])[1:]

Cobalah online!

k*x>ymenyiratkan k>y/x; jadi yang terkecil kbisa adalah k=floor(y/x)+1. Karena dalam Python 2.7, pembagian integer sudah diambil seperti floor, kita inginkan k=y/x+1, dan k*x = (y/x+1)*x = y/x*x+x.

Chas Brown
sumber
0

Oracle SQL 11.2, 210 byte

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;

Tidak bermain golf

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;
Jeto
sumber
0

Chez Scheme (140 Bytes)

Versi Golf:

(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))

Versi Tidak Serigala:

(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)
)

Cobalah secara Online!

Zachary Cotton
sumber
* m(car l)bisa *(car l)m.
Jonathan Frech