Sắp xếp theo bội số


34

Bạn nên viết một chương trình hoặc hàm đưa ra danh sách các số nguyên dương nhân với mỗi phần tử với số nguyên dương nhỏ nhất có thể để tạo danh sách tăng nghiêm ngặt.

Ví dụ: nếu đầu vào là

5 4 12 1 3

các phép nhân sẽ là

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

và đầu ra sẽ là danh sách ngày càng tăng

5 8 12 13 15

Đầu vào

  • Danh sách các số nguyên dương chứa ít nhất 1 phần tử

Đầu ra

  • Danh sách các số nguyên dương

Ví dụ

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

Đây là mã golf nên chương trình hoặc chức năng ngắn nhất sẽ thắng.

Sự thật thú vị: phần tử cuối cùng của đầu ra cho đầu vào N, N-1, ... ,1dường như là (N+1)thphần tử của chuỗi A007952 . Nếu bạn tìm thấy một bằng chứng, bạn được hoan nghênh đưa nó vào câu trả lời golf của bạn hoặc đăng nó dưới dạng một nhận xét.


có ai đã làm căn cứ trên bằng chứng đó chưa?
Connor Clark

Câu trả lời:


20

Thạch , 6 5 byte

:‘×µ\

Câu trả lời đầu tiên của Jelly trước khi @Dennis thức dậy và đánh bại tôi. Hãy thử trực tuyến!

Giải trình

:          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

Cảm ơn @Dennis cho -1 byte.


4
:‘×µ\tiết kiệm một byte.
Dennis

20
@Dennis Oh shit anh thức dậy
Dennis van Gils

9

JavaScript (ES6), 28

Chỉnh sửa Theo đề xuất của @Patrick Roberts, pcó thể là một tham số chưa được khởi tạo. Cùng một số byte nhưng tránh sử dụng biến toàn cục

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

KIỂM TRA

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>


Tôi nghĩ bạn có thể tiết kiệm một vài byte bằng cách sử dụng modulo, giống như tôi đã làm trong câu trả lời của mình .
vào

Bạn không thể bỏ qua p = 0? Bạn cần nó để chạy nó trên nhiều danh sách nhưng câu hỏi chỉ dành cho một danh sách duy nhất
Charlie Wynn

1
@CharlieWynn nếu bạn không khởi tạo một biến, bạn sẽ gặp lỗi cho biến không xác định. Nếu tình cờ biến đã tồn tại (điều đó có thể dễ dàng xảy ra trong môi trường của một trang web), thì nó có thể có bất kỳ giá trị sai nào.
edc65

@ edc65 chắc chắn rồi, p đã được xác định trên trang này!
Charlie Wynn

1
@PatrickRoberts suy nghĩ lại, tôi vẫn có thể tránh được toàn cầu : f=a=>a.map(n=>a+=n-a%n,a=0). Nhưng đó không phải là thuật toán của tôi (ngớ ngẩn với tôi) vì vậy tôi sẽ giữ nguyên như tôi và nâng cấp trên khắp
edc65

6

Python 2, 67 64 byte

Đầu tiên hãy thử chơi golf, vì vậy các mẹo được đánh giá cao.

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

Xin chào, tôi nghĩ rằng bạn đang đếm dòng trả về là 2 byte mỗi dòng (sử dụng Windows?), Nhưng trên trang web này, bạn đếm mỗi dòng trả về là một byte đơn. Vì vậy, điểm của bạn thực sự là 65 byte. (Bạn có thể sao chép và dán mã của mình vào Mothereff.in/byte-count nếu bạn không chắc chắn.) Ngoài ra, bạn có thể làm print lthay vì return llưu một byte khác. Công việc tốt!
mathmandan

Cảm ơn, tôi đã không biết về lợi nhuận của dòng. Điều đó giải thích tại sao tôi luôn có số byte khác nhau. Và tôi thậm chí đã không cân nhắc, việc in ấn là đủ và nó không phải trả về danh sách.
Taronyu

Không vấn đề gì! BTW, vì bạn đã đề cập rằng "các mẹo được đánh giá cao", bạn có thể quan tâm đến việc duyệt qua codegolf.stackexchange.com/questions/54/ . Thưởng thức!
mathmandan

5

PHP, 55 46 42 41 byte

Sử dụng mã hóa ISO 8859-1.

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

Chạy như thế này (chỉ -dthêm tính thẩm mỹ):

php -d error_reporting=30709 -r 'for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;' 10 10 8
  • Đã lưu 1 byte thx cho Ismael Miguel.
  • Đã lưu 8 byte bằng cách sử dụng modulo thay vì sàn
  • Đã lưu 4 byte thx cho Ismael Miguel (thay vì foreach)
  • Đã lưu một byte bằng cách sử dụng để mang lại một khoảng trắng.

Tôi nghĩ rằng bạn có thể thay thế $a+0bằng +$a. Ngoài ra, bạn có thể giả định rằng đầu vào sẽ không bao giờ có a 0, vì vậy, bạn có thể thay thế $a+0&&printbằng cách đơn giản +$a&print. Trong thực tế, bạn thậm chí có thể làm $a&print, vì trong PHP "0" == 0 == 0.0 == false. Nhưng nó có thể không cần thiết nếu bạn chỉ sử dụng một echo, tôi nghĩ.
Ismael Miguel

Nhị phân andsẽ không hoạt động (trái ngược với logic), cũng sẽ không lặp lại hoạt động theo cách này. Vì tôi đang lấy đầu vào từ CLI, nên đối số đầu tiên là -, tôi muốn nắm bắt thay vì in số không. Hãy thử php -r 'print_r($argv);' foo. Đã lưu 1 byte với đề xuất đầu tiên của bạn, thx.
vào

1
Thế còn for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,' ';? Nó dài 42 byte và bỏ qua phần tử đầu tiên.
Ismael Miguel

Một người đẹp, thx @IsmaelMiguel
vào

Không có gì. Nếu bạn muốn thực sự khó chịu, bạn có thể thay thế không gian bằng a^A, nhưng điều đó sẽ tràn ra quá nhiều cảnh báo (cảnh báo là không thể biết được). Nó sẽ không thay đổi bytecount theo bất kỳ cách nào, nhưng surelly trông khác.
Ismael Miguel

4

Haskell (30 28 25 byte)

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

Phiên bản mở rộng

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)

Giải trình

scanl1cho phép bạn gấp một danh sách và tích lũy tất cả các giá trị trung gian vào một danh sách khác. Đây là một chuyên ngành scanl, có loại sau:

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

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

Do đó, tất cả những gì chúng ta cần là một hàm phù hợp lấy hai phần tử cuối cùng trong danh sách của chúng ta ( acctrong phiên bản mở rộng) và hàm chúng ta muốn xử lý ( nexttrong phiên bản mở rộng) và trả về một số phù hợp.

Chúng ta có thể dễ dàng lấy được con số này bằng cách chia bộ tích lũy qua số tiếp theo và kết quả. divchăm sóc điều đó Sau đó, chúng tôi chỉ cần thêm 1để đảm bảo rằng danh sách thực sự đang tăng (và chúng tôi không kết thúc 0).


Không cần phải cung cấp cho chức năng của bạn một tên. Bạn cũng có thể thay thế ( ... )bằng $ ...và tôi nghĩ bạn đã đếm một dòng mới cuối cùng có thể được bỏ qua : scanl1$\x y->y*div x y+y, 24 byte.
nimi

@nimi: Thật sao? Biểu thức tính? Điều đó đang được nói, tôi không lưu bất kỳ byte nào với (...)vs $, vì $\ được phân tích cú pháp như toán tử và tôi sẽ cần một khoảng trống sau đó $.
Zeta

chức năng không tên được cho phép theo mặc định an scanl1(...)là một chức năng chưa được đặt tên. Về $so với (): bạn nói đúng, lỗi của tôi.
nimi

4

C ++ 63 60 57 byte

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

Làm việc tại chỗ đưa ra một phạm vi [first, last). Ban đầu được viết dưới dạng biến thể mẫu, nhưng nó dài hơn:

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

Phiên bản mở rộng

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 byte

q~{\_p1$/)*}*

Nhập dưới dạng danh sách kiểu CJam. Đầu ra được phân tách dòng.

Kiểm tra nó ở đây.

Giải trình

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

Giá trị cuối cùng được để lại trên ngăn xếp và được in tự động ở cuối.


3

Toán học, 36 32 byte

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

Kiểm tra

#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 byte

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

Yêu cầu -p-lcờ:

$ 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

Giải trình:

# '-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 byte

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

Kiểm tra

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

Giải pháp trước

một số giải pháp đệ quy nhưng lớn hơn

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

Ngoài ra, thay vì r+=[…], bạn có thể sử dụngr+=…,
Cyoce

@Cyoce tôi thực hiện thay đổi nhưng khi tôi xác r=[0]định tham số mặc định rtrở thành không cục bộ
Erwan

bạn nói đúng, tôi quên cách Python xử lý các thông số mặc định. Mẹo khác nên hoạt động mặc dù
Cyoce

@Cyoce có nó hoạt động nhờ lời khuyên
Erwan

3

Brachylog , 12 byte

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

Thật kỳ lạ khi cố gắng nhân mỗi biến với một số sẽ bắt đầu bằng cách nhân 2 và không 0 hoặc 1. Điều này dường như hoạt động mặc dù và đánh bại cả hai triển khai Brachylog khác

Giải trình

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

Hãy thử trực tuyến!


2

Brachylog , 54 byte

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

Giải trình

:_{...}.                § 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

Bình thường, 11

t.u*Yh/NYQ0

Phòng thử nghiệm

Có giảm tích lũy, giảm mà trả về tất cả các giá trị trung gian, bắt đầu bằng 0. Vì đầu vào được đảm bảo chỉ chứa các số nguyên dương, nên điều này là ổn. Trong mỗi bước, chúng tôi lấy giá trị cũ, chia nó cho giá trị mới và thêm 1, sau đó chúng tôi nhân với giá trị mới.


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);}

Bị đánh cắp

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);
}

Sẽ không p=p/x*x+xlàm việc?
Neil

@Neil Vâng, điều đó sẽ làm việc. Chắc chắn đã vượt qua điều này :)
Cole Cameron

2

PowerShell, 26 byte

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

Đưa đầu vào như một mảng rõ ràng, ví dụ, > .\sort-by-multiplying.ps1 @(6,5,4,3,2,1)thông qua $args[0].

Sau đó, chúng tôi lặp lại điều đó với |%{...}và mỗi lần lặp lại thực hiện phép thuật . Không, đùa thôi, chúng tôi sử dụng thủ thuật modulo giống như các câu trả lời khác (đạo cụ cho @aross vì tôi phát hiện ra nó ở đó trước).

Các parens đóng gói (...)đảm bảo rằng kết quả của phép toán được đặt trên đường ống và do đó xuất ra. Nếu chúng ta bỏ đi những thứ đó, sẽ không có gì là đầu ra vì $lbiến được thu gom rác sau khi kết thúc thực hiện.

Thí dụ

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

1

Japt, 11 byte

Uå@Y*-~(X/Y

Kiểm tra nó trực tuyến!

Làm thế nào nó hoạt động

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

1

05AB1E , 11 byte

Mã số:

R`[=sŽDŠ/ò*

Hãy thử trực tuyến!

Giải trình:

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

Sử dụng mã hóa CP-1252.


1

Chồn 0,15 , 17 byte

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

Hãy thử nó ở đây!

Giải trình

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

Về cơ bản, thanh ghi giữ thành viên mới nhất của danh sách tăng dần và điều này được chia cho đầu vào và tăng lên để có được hệ số nhân cho thành viên tiếp theo. Tính năng hình xuyến của trường mã của Minkolang có nghĩa là nó lặp theo chiều ngang mà không cần ()hoặc []vòng lặp.


1

Brachylog , 21 byte

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

Hãy thử trực tuyến!

Sử dụng tổng các giá trị đầu vào làm giới hạn trên cho các hệ số C. Khá chậm, hết thời gian trên TIO cho độ dài danh sách đầu vào vượt quá 5 hoặc 6 (cũng tùy thuộc vào tổng của các giá trị). Nhưng không chậm như phiên bản gốc của tôi, yêu cầu danh sách nhỏ gồm tối đa 3 yếu tố, với các giá trị nhỏ, không hết thời gian:

21 byte

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

Hãy thử trực tuyến!



1

Python 2 , 53 byte

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

Hãy thử trực tuyến!

k*x>yngụ ý k>y/x; vì vậy nhỏ nhất kcó thể là k=floor(y/x)+1. Vì trong Python 2.7, phép chia số nguyên đã được thực hiện như floor, chúng tôi muốn k=y/x+1k*x = (y/x+1)*x = y/x*x+x.


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;

Không chơi gôn

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

Lược đồ Chez (140 byte)

Phiên bản chơi gôn:

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

Phiên bản Ungolfed:

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

Hãy thử trực tuyến!


* m(car l)có thể *(car l)m.
Jonathan Frech

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.