Sắp xếp các số duy nhất trong bảng nhân


30

Thử thách khá đơn giản hôm nay:

Viết chương trình hoặc hàm nhận số nguyên dương N và in hoặc trả về danh sách đã sắp xếp của các số duy nhất xuất hiện trong bảng nhân có hàng và cột nhân cả hai phạm vi từ 1 đến N.

Danh sách có thể được sắp xếp theo thứ tự tăng dần (nhỏ nhất đến lớn nhất) hoặc thứ tự giảm dần (lớn nhất đến nhỏ nhất) và có thể được xuất ra ở bất kỳ định dạng hợp lý nào.

Mã ngắn nhất tính bằng byte thắng!

Thí dụ

Khi N = 4, bảng nhân giống như:

   1  2  3  4
  -----------
1| 1  2  3  4
 |
2| 2  4  6  8
 |
3| 3  6  9 12
 |
4| 4  8 12 16

Các số duy nhất trong bảng là 1, 2, 3, 4, 6, 8, 9, 12, 16. Chúng đã được sắp xếp, vì vậy

1, 2, 3, 4, 6, 8, 9, 12, 16

có thể là đầu ra chính xác của bạn cho N = 4. Nhưng vì việc sắp xếp có thể bị đảo ngược và có một số độ trễ trong định dạng, đây cũng sẽ là các đầu ra hợp lệ:

[16,12,9,8,6,4,3,2,1]
1
2
3
4
6
8
9
12
16
16 12 9 8 4 3 2 1

Các trường hợp thử nghiệm

N=1 -> [1]
N=2 -> [1, 2, 4]
N=3 -> [1, 2, 3, 4, 6, 9]
N=4 -> [1, 2, 3, 4, 6, 8, 9, 12, 16]
N=5 -> [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 20, 25]
N=6 -> [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 30, 36]
N=7 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 28, 30, 35, 36, 42, 49]
N=8 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 28, 30, 32, 35, 36, 40, 42, 48, 49, 56, 64]
N=9 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, 28, 30, 32, 35, 36, 40, 42, 45, 48, 49, 54, 56, 63, 64, 72, 81]
N=10 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, 28, 30, 32, 35, 36, 40, 42, 45, 48, 49, 50, 54, 56, 60, 63, 64, 70, 72, 80, 81, 90, 100]
N=11 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 27, 28, 30, 32, 33, 35, 36, 40, 42, 44, 45, 48, 49, 50, 54, 55, 56, 60, 63, 64, 66, 70, 72, 77, 80, 81, 88, 90, 99, 100, 110, 121]
N=12 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 27, 28, 30, 32, 33, 35, 36, 40, 42, 44, 45, 48, 49, 50, 54, 55, 56, 60, 63, 64, 66, 70, 72, 77, 80, 81, 84, 88, 90, 96, 99, 100, 108, 110, 120, 121, 132, 144]

Vì vậy, về cơ bản, mã trả về một danh sách các số trong bảng nhân được chỉ định bởi N, ngoại trừ bất kỳ số nào có thể được lặp lại?
TanMath

N có thể lớn đến mức nào?
xsot

1
@xsot Bạn có thể giả sử N * N sẽ nhỏ hơn giá trị int thông thường tối đa của ngôn ngữ của bạn (có thể là 2 ^ 31-1)
Sở thích của Calvin

Vì vậy, về cơ bản, đây là 1-n và các số nguyên tố không lên đến n ^ 2.
gregsdennis

1
@gregsdennis Không. Có rất nhiều vật liệu tổng hợp không có mặt. ví dụ: 91, 92, 93, 94, 95, 96 với N = 10.
Sở thích của Calvin

Câu trả lời:


12

Bình thường, 8 byte

S{*M^SQ2

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

Giải thích: SQlấy danh sách đầu vào được đánh giá ( Q) và tạo danh sách [1, 2, ..., Q]. ^SQ2tự lấy sản phẩm của Cartesian trong danh sách đó - tất cả các kết hợp sản phẩm có thể. *Mnhân tất cả các cặp này với nhau để tạo thành tất cả các kết quả có thể có trong bảng nhân và S{làm cho nó trở nên độc đáo và sắp xếp nó.


@FryAmTheEggman Đầu vào 5 đã cần sắp xếp, nếu không thì 10 và 9 trong đầu ra không đúng thứ tự.
Reto Koradi

darn tiếp tục quên về việc bắn tung tóe trên M. +1
Maltysen

13

Python 2, 61 51 byte

lambda n:sorted({~(i%n)*~(i/n)for i in range(n*n)})

Cảm ơn xnor đã rút ngắn một số cú pháp.


1
Chỉ set(...)có thể là một comp comp {...}. Ngoài ra, các chức năng được cho phép theo mặc định ở đây, vì vậy bạn chỉ có thể viết lambda n:....
xnor

Cảm ơn đã nhắc nhở tôi về sự hiểu biết thiết lập, tôi hoàn toàn quên nó tồn tại.
xsot

Tôi không thể thấy một cách tốt hơn để làm điều này, tốt nhất tôi thấy với đệ quy là 56 : f=lambda n:n*[0]and sorted(set(range(n,n*n+n,n)+f(n-1))).
xnor

11

APL, 18 16 byte

{y[⍋y←∪,∘.×⍨⍳⍵]}

Đây là một chức năng đơn âm không tên. Đầu ra theo thứ tự tăng dần.

Giải trình:

             ⍳⍵]}   ⍝ Get the integers from 1 to the input
         ∘.×⍨       ⍝ Compute the outer product of this with itself
        ,           ⍝ Flatten into an array
       ∪            ⍝ Select unique elements
     y←             ⍝ Assign to y
 {y[⍋               ⍝ Sort ascending

Đã khắc phục sự cố và lưu 2 byte nhờ Thomas Kwa!


7

CJam, 14 12 byte

Phiên bản mới nhất với những cải tiến được đề xuất bởi @aditsu:

{)2m*::*0^$}

Đây là một chức năng ẩn danh. Hãy thử trực tuyến , với mã đầu vào / đầu ra cần thiết để kiểm tra nó.

@Martin đề xuất một giải pháp rất thanh lịch ( {,:)_ff*:|$}) có cùng độ dài. Tôi đã sử dụng một cái bởi aditsu vì nó giống với giải pháp ban đầu của tôi hơn nhiều.

Sự khác biệt chính đối với giải pháp ban đầu của tôi là điều này giữ 0giá trị trong chuỗi ban đầu, giúp tiết kiệm 2 byte khi bắt đầu. Bạn sẽ nghĩ rằng điều này sẽ không giúp ích gì, vì bạn phải xóa 0giá trị khỏi kết quả. Nhưng cốt lõi của ý tưởng của @ aditsu là 0^ở phần cuối, đó là một sự khác biệt được thiết lập với 0. Điều này loại bỏ 0, đồng thời, vì đây là thao tác được thiết lập, loại bỏ các phần tử trùng lặp khỏi bộ giải pháp. Vì tôi đã cần 2 byte để loại bỏ các bản sao trước đó, nên 0về cơ bản là miễn phí.

Giải trình:

{     Start anonymous function.
  )     Increment to get N+1.
  2m*   Cartesian power, to get all pairs of numbers in range [0, N].
  ::*   Reduce all pairs with multiplication.
  0^    Remove 0, and remove duplicates at the same time since this is a set operation.
  $     Sort the list.
}     End anonymous function.

Đối với cùng độ dài, {2m*::)::*_&$},{)2m*::*_&$0-}
Peter Taylor

2
Làm thế nào về điều này cho hai byte ít hơn :){,:)_ff*:|$}
Martin Ender

1
Một cách khác:{)2m*::*0^$}
aditsu


4

Julia, 24 byte

n->sort(∪((x=1:n)*x'))

Đây là một hàm ẩn danh chấp nhận một số nguyên và trả về một mảng số nguyên.

Ung dung:

function f(n::Integer)
    # Construct a UnitRange from 1 to the input
    x = 1:n

    # Compute the outer product of x with itself
    o = x * transpose(x)

    # Get the unique elements, implicitly flattening
    # columnwise into an array
    u = unique(o)

    # Return the sorted output
    return sort(u)
end


4

zsh, 86 56 byte

cảm ơn @Dennis vì đã tiết kiệm 30 (!) byte

(for a in {1..$1};for b in {1..$1};echo $[a*b])|sort -nu

Giải thích / không có căn cứ:

(                      # begin subshell
  for a in {1..$1}     # loop through every pair of multiplicands
    for b in {1..$1}
      echo $[a*b]      # calculate a * b, output to stdout
) | sort -nu           # pipe output of subshell to `sort -nu', sorting
                       # numerically (-n) and removing duplicates (-u for uniq)

Điều này không hoạt động ở Bash vì Bash không mở rộng chương trình {1..$1}chỉ diễn giải theo nghĩa đen (vì vậy, a=5; echo {1..$a}đầu ra {1..5}thay vì 1 2 3 4 5).


Tôi đã chờ đợi một câu trả lời * sh. : D
Addison Crump

1
Mẹo bash có liên quan. Có vẻ để áp dụng cho vỏ Z là tốt.
Dennis


4

Ruby, 50 48 byte

->n{c=*r=1..n;r.map{|i|c|=r.map{|j|i*j}};c.sort}

Ung dung:

->n {
  c=*r=1..n
  r.map { |i| c|=r.map{|j|i*j} }
  c.sort
}

Sử dụng vòng lặp lồng nhau để nhân mỗi số với mỗi số khác tối đa n và sau đó sắp xếp mảng.

50 byte

->n{r=1..n;r.flat_map{|i|r.map{|j|i*j}}.uniq.sort}

Sử dụng:

->n{c=*r=1..n;r.map{|i|c|=r.map{|j|i*j}};c.sort}[4]
=> [1, 2, 3, 4, 6, 8, 9, 12, 16]

3

R, 39 byte

cat(unique(sort(outer(n<-1:scan(),n))))

Điều này đọc một số nguyên từ STDIN và ghi một danh sách giới hạn không gian vào STDOUT.

Chúng tôi tạo bảng nhân dưới dạng ma trận bằng cách sử dụng outer, hoàn toàn làm phẳng thành một vectơ và sắp xếp bằng cách sử dụng sort, chọn các phần tử duy nhất bằng cách sử dụng uniquevà in không gian được phân tách bằng cách sử dụng cat.




2

K, 17 byte

t@<t:?,/t*\:t:1+!

Không có nhiều để nói ở đây. Sắp xếp ( t@<t:) các mục duy nhất ( ?) của dẹt (,/ sản phẩm tự tạo cartesian được )t*\:t: ) trong tổng số 1 lên đến và bao gồm N ( 1+!).

Trong hành động:

  t@<t:?,/t*\:t:1+!5
1 2 3 4 5 6 8 9 10 12 15 16 20 25

2

Haskell, 55 54 byte

import Data.List
f n=sort$nub[x*y|x<-[1..n],y<-[1..x]]

Ví dụ sử dụng: f 4->[1,2,3,4,6,8,9,12,16] .

nub loại bỏ các yếu tố trùng lặp khỏi danh sách.

Chỉnh sửa: @Zgarb tìm thấy một thừa $.


2

J, 21 20 byte

Cảm ơn @Zgarb cho -1 byte!

/:~@~.@,@(1*/~@:+i.)

Câu trả lời J đầu tiên của tôi! Lời khuyên chơi golf được đánh giá cao, nếu có một cái gì đó để chơi golf.

Đây là một chức năng đơn trị; chúng ta lấy sản phẩm bên ngoài bởi nhân của danh sách 1..inputvới chính nó, làm phẳng, có các yếu tố độc đáo, và sắp xếp.


2

Kotlin, 70 byte

val a={i:Int->(1..i).flatMap{(1..i).map{j->it*j}}.distinct().sorted()}

Phiên bản bị đánh cắp:

val a: (Int) -> List<Int> = { 
    i -> (1..i).flatMap{ j -> (1..i).map{ k -> j * k } }.distinct().sorted()
}

Kiểm tra nó với:

fun main(args: Array<String>) {
    for(i in 1..12) {
        println(a(i))
    }
}

2

Shell + tiện ích chung, 41

seq -f"seq -f%g*%%g $1" $1|sh|bc|sort -nu

Hay cách khác:

Bash + coreutils, 48

eval printf '%s\\n' \$[{1..$1}*{1..$1}]|sort -nu

Xây dựng một mở rộng cú đúp trong một mở rộng số học:

\$[{1..n}*{1..n}]mở rộng đến các mở rộng số học $[1*1] $[1*2] ... $[1*n] ... $[n*n]được đánh giá và chuyển đến printf, in ra một dòng trên mỗi dòng, được dẫn đếnsort .

Sử dụng cẩn thận các trích dẫn, thoát và evalđảm bảo việc mở rộng xảy ra theo thứ tự yêu cầu.


Hay cách khác:

Bash thuần khiết, 60

eval a=($(eval echo [\$[{1..$1}*{1..$1}\]]=1))
echo ${!a[@]}


1

Chồn 0,14 , 25 22 18 byte

Tôi nhớ rằng tôi đã thực hiện rất thuận tiện các sản phẩm của Cartesian trước khi câu hỏi này được đăng !

1nLI20P[x*1R]sS$N.

Hãy thử nó ở đây. (Đầu ra theo thứ tự ngược lại.)

Giải trình

1                     Push a 1 onto the stack
 n                    Take number from input (n)
  L                   Pushes 1,2,...,n onto the stack
   I                  Pushes length of stack so 0P knows how many items to pop
    2                 Pushes 2 (the number of repeats)
     0P               Essentially does itertools.product(range(1,n+1), 2)
       [              Open for loop that repeats n^2 times (0P puts this on the stack)
        x             Dump (I know each product has exactly two numbers
         *            Multiply
          1R          Rotate 1 step to the right
            ]         Close for loop
             s        Sort
              S       Remove duplicates ("set")
               $N.    Output whole stack as numbers and stop.

1

JavaScript (ES6), 92 90 byte

n=>eval(`for(r=[],a=n;a;a--)for(b=n;b;)~r.indexOf(x=a*b--)||r.push(x);r.sort((a,b)=>a-b)`)

Giải trình

n=>eval(`                 // use eval to remove need for return keyword
  for(r=[],a=n;a;a--)     // iterate for each number a
    for(b=n;b;)           // iterate for each number b
      ~r.indexOf(x=a*b--) // check if it is already in the list, x = value
      ||r.push(x);        // add the result
  r.sort((a,b)=>a-b)      // sort the results by ascending value
                          // implicit: return r
`)

Kiểm tra

N = <input type="number" oninput="result.innerHTML=(

n=>eval(`for(r=[],a=n;a;a--)for(b=n;b;)~r.indexOf(x=a*b--)||r.push(x);r.sort((a,b)=>a-b)`)

)(+this.value)" /><pre id="result"></pre>


1

Perl 6 , 27 byte

{squish sort 1..$_ X*1..$_} # 27
{unique sort 1..$_ X*1..$_} # 27
{sort unique 1..$_ X*1..$_} # 27

Ví dụ sử dụng:

say {squish sort 1..$_ X*1..$_}(3); # (1 2 3 4 6 9)␤

my $code = {squish sort 1..$_ X*1..$_}

for 1..100 -> \N { say $code(N) }

my &code = $code;

say code 4; # (1 2 3 4 6 8 9 12 16)␤

1

Haskell, 51 byte

f n=[i|i<-[1..n*n],elem i[a*b|a<-[1..n],b<-[1..n]]]

Khá nhàm chán. Chỉ cần lọc danh sách [1..n*n]cho các thành phần của biểu mẫu a*babtrong [1..n]. Sử dụng filtercho cùng một chiều dài

f n=filter(`elem`[a*b|a<-[1..n],b<-[1..n]])[1..n*n]

Tôi đã cố gắng trong một thời gian để tạo ra danh sách các sản phẩm với một cái gì đó thông minh hơn như concatMaphay mapM, nhưng chỉ có kết quả lâu hơn. Một kiểm tra thành viên tinh vi hơn xuất hiện ở mức 52 byte, dài hơn 1 byte, nhưng có lẽ có thể rút ngắn.

f n=[k|k<-[1..n*n],any(\a->k`mod`a<1&&k<=n*a)[1..n]]

Bạn có thể lưu 3 byte bằng cách sử dụng (*)<$>..<*>..như này
ბიმო

1

JAVA - 86 byte

Set a(int a){Set s=new TreeSet();for(;a>0;a--)for(int b=a;b>0;)s.add(a*b--);return s;}

Ung dung

Set a(int a){
    Set s = new TreeSet();
    for (;a>0;a--){
        for(int b = a;b>0;){
            s.add(a*b--);
        }
    }
    return s;
}

1

Bình thường, 11 byte

S{sm*RdSdSQ

Điều này tương tự như câu trả lời của Julia. Cảm ơn @Maltysen


1

PHP, 74,73 70byte

while($i++<$j=$n)while($j)$a[]=$i*$j--;$a=array_unique($a);sort($a);

print_r($a); // Not counted, but to verify the result

Ung dung:

while($i++<$j=$n)
    while($j)
        $a[]=$i*$j--;

Trước:

while(($j=$i++)<$n)for(;$j++<$n;)$a[]=$i*$j;$a=array_unique($a);sort($a);

Không chắc chắn 100% phải làm gì với đầu ra, nhưng $achứa một mảng với các số tương ứng. $nlà số geven qua $_GET['n'], vớiregister_globals=1


1

TeaScript , 37 35 ký tự; 40 byte

Đã lưu 2 byte nhờ @Downgoat

TeaScript là JavaScript để chơi gôn.

(b+r(1,+x¬)ßam(z=>z*l±s`,`.u¡s»l-i)

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

Ung dung và giải thích

(b+r(1,+x+1)m(#am(z=>z*l)))s(',').u()s(#l-i)
              // Implicit: x = input number
r(1,+x+1)     // Generate a range of integers from 1 to x.
m(#           // Map each item "l" in this range "a" to:
 am(z=>       //  a, with each item "z" mapped to
  z*l))       //   z * l.
(b+      )    // Parse this as a string by adding it to an empty string.
s(',')        // Split the string at commas, flattening the list.
.u()          // Take only the unique items from the result.
s(#l-i)       // Sort by subtraction; the default sort sorts 10, 12, 100, etc. before 2.
              // Implicit: output last expression

Bạn chỉ có thể sử dụng rthay vì A.rđể tạo phạm vi
Downgoat

Chắc chắn đây là 35 byte ? Tôi nhận được 35 ký tự hoặc 40 byte.
manatwork

@manatwork Đây sẽ là 35 byte ở định dạng mã hóa ISO / IEC_8859-1 . Nhưng tôi không chắc chắn rằng TeaScript hỗ trợ mã hóa đó, vì vậy bây giờ tôi sẽ thay đổi nó thành 40 byte.
Sản xuất ETH

0

C, 96 byte

i,a[1<<16];main(n){for(scanf("%d",&n);i<n*n;a[~(i%n)*~(i++/n)]="%d ");while(i)printf(a[i--],i);}

Điều này in các số theo thứ tự giảm dần. Đề xuất được hoan nghênh vì điều này có vẻ xa tối ưu.


0

JavaScript (ES6), 86 byte

n=>{n++;a=[];for(j=1;j<n;j++)for(i=1;i<n;i++)if(a.indexOf(i*j)<0)a.push(i*j);return a}

Tìm cách rút ngắn nó (có thể sẽ thử các vòng lặp lồng nhau).


0

Perl 5, 91 byte

for my $y (1 .. $ARGV[0]){
    map {$s{$n}++ unless($s{$n=$y*$_}) } ($y .. $ARGV[0])
}
print join(" ", sort {$a<=>$b} keys %s) . "\n";

được chạy bằng cách chuyển đối số trên dòng lệnh. Đó là một vài tuyên bố ngắn khi chạy với sự nghiêm ngặt và cảnh báo.


0

Python, 124 102 byte

n=input()
l=[1]
for i in range(1,n+1):
 for j in range(1,n+1):l.append(i*j)
print sorted(list(set(l)))

Thêm kim tự tháp!


2
Đây thực sự là 123 byte, không phải 124. Nhưng bạn có thể lưu một vài byte bằng cách chỉ sử dụng một khoảng trống trên mỗi mức thụt đầu dòng chứ không phải 4.
Alex A.

1
Bạn cũng có thể đặt l.append(i*j)trên cùng một dòng như nếu có điều kiện. Tôi nghĩ rằng nó kết thúc là 102 byte hoàn toàn.
El'endia Starman

3
Và sử dụng +=thay vì append.
Kartik

@ El'endiaStarman chỉnh sửa, cảm ơn!
TanMath

1
Một vấn đề tương đối nhỏ: list(set(l))không được đảm bảo để được sắp xếp.
El'endia Starman

0

Perl 5, 67 byte

for$i(1..($n=pop)){$a{$_*$i}++for 1..$n}map say,sort{$a<=>$b}keys%a
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.