Сортировать уникальные числа в таблице умножения


30

Довольно простая задача сегодня:

Напишите программу или функцию, которая принимает положительное целое число N и печатает или возвращает отсортированный список уникальных чисел, которые появляются в таблице умножения, чьи мультипликаторы строк и столбцов находятся в диапазоне от 1 до N включительно.

Список может быть отсортирован в порядке возрастания (от меньшего к большему) или в порядке убывания (от наибольшего к наименьшему) и может быть выведен в любом приемлемом формате.

Самый короткий код в байтах побеждает!

пример

Когда N = 4, таблица умножения выглядит следующим образом:

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

Уникальные числа в таблице 1, 2, 3, 4, 6, 8, 9, 12, 16. Они уже отсортированы, так что

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

может быть вашим точным выводом для N = 4. Но так как сортировка может быть обратной, и есть некоторая свобода в форматировании, это также будет допустимым выводом:

[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

Тестовые случаи

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]

Таким образом, в основном, код возвращает список чисел в таблице умножения, указанных N, кроме того, что любое число не может повторяться?
TanMath

Насколько большой N может быть?
xsot

1
@xsot Вы можете предположить, что N * N будет меньше, чем максимальное обычное значение вашего языка int (вероятно, 2 ^ 31-1)
Увлечения Кэлвина

Таким образом, по существу это 1-n и не простые числа до n ^ 2.
gregsdennis

1
@gregsdennis Нет. Есть много композитов, которых нет. например, 91, 92, 93, 94, 95, 96 для N = 10.
Увлечения Кэлвина

Ответы:


12

Pyth, 8 байт

S{*M^SQ2

Попробуйте онлайн.

Объяснение: SQберет оцененный ввод input ( Q) и составляет список [1, 2, ..., Q]. ^SQ2берет декартово произведение из этого списка с собой - все возможные комбинации продуктов. *Mумножает все эти пары вместе, чтобы сформировать все возможные результаты в таблице умножения, S{делает ее уникальной и сортирует ее.


@FryAmTheEggman Вход 5 уже нуждается в сортировке, иначе 10 и 9 в выходных данных будут не в порядке.
Рето Коради

черт, продолжай забывать об этом плескаться на M. +1
Maltysen

13

Python 2, 61 51 байт

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

Спасибо xnor за сокращение некоторого синтаксиса.


1
set(...)Может быть просто набор компом {...}. Также здесь разрешены функции по умолчанию, так что вы можете просто написать lambda n:....
xnor

Спасибо, что напомнили мне о заданном понимании, я полностью забыл, что он существует.
xsot

Я не вижу лучшего способа сделать это, лучше всего я вижу с рекурсией 56 f=lambda n:n*[0]and sorted(set(range(n,n*n+n,n)+f(n-1))).
xnor

11

APL, 18 16 байтов

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

Это безымянная монадическая функция. Вывод в порядке возрастания.

Объяснение:

             ⍳⍵]}   ⍝ 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

Исправлена ​​проблема и сохранены 2 байта благодаря Thomas Kwa!


7

CJam, 14 12 байтов

Последняя версия с улучшениями, предложенными @aditsu:

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

Это анонимная функция. Попробуйте онлайн , с кодом ввода / вывода, необходимым для тестирования.

@Martin предложил другое очень элегантное решение ( {,:)_ff*:|$}) с такой же длиной. Я использовал один от aditsu, потому что он был намного больше похож на мое оригинальное решение.

Основное отличие от моего первоначального решения состоит в том, что он сохраняет 0значение в исходной последовательности, что экономит 2 байта в начале. Вы можете подумать, что это не поможет, потому что вы должны удалить 0значение из результата. Но суть идеи @ aditsu - 0^это конец, с которым есть определенная разница 0. Это удаляет 0, и в то же время, поскольку это операция набора, удаляет дубликаты элементов из набора решений. Так как для устранения дубликатов мне уже потребовалось 2 байта, удаление 0будет, по существу, бесплатным.

Объяснение:

{     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.

По той же длины, {2m*::)::*_&$},{)2m*::*_&$0-}
Питер Тейлор

2
Как насчет этого на два байта меньше :){,:)_ff*:|$}
Мартин Эндер

1
Другой способ:{)2m*::*0^$}
aditsu


4

Юлия, 24 байта

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

Это анонимная функция, которая принимает целое число и возвращает массив целых чисел.

Ungolfed:

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

MATLAB, 24 байта

@(n)unique((1:n)'*(1:n))

Хороший! Скоро можно будет сделать это за 7 или 8 байт ... :-)
Луис Мендо

Ооо, здорово! :-)
Стьюи Гриффин

@ Луис, ты пробовал это в MATL?
Стьюи Гриффин

У меня не так много времени, чтобы прочитать весь тест, но, глядя на ваш код Matlab, похоже, что это можно сделать с помощью MATL
Луис Мендо

4

zsh, 86 56 байт

спасибо @Dennis за сохранение 30 (!) байтов

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

Объяснение / ungolfed:

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

Это не работает в Bash, потому что Bash не расширяется {1..$1}- он просто интерпретирует его буквально (поэтому a=5; echo {1..$a}выводит {1..5}вместо 1 2 3 4 5).


Я ждал * sh ответа. : D
Эддисон Крамп

1
Соответствующий совет Bash. Кажется, применимо и к Z-оболочке.
Денис


4

Рубин, 50 48 байтов

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

Ungolfed:

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

Использование вложенного цикла для умножения каждого числа на любое другое число до n и последующей сортировки массива.

50 байтов

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

Использование:

->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 байт

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

Это читает целое число из STDIN и записывает список с разделителями пробелами в STDOUT.

Мы создаем таблицу умножения как матрицу, используя outer, неявно сглаживая в векторе и сортируя используя sort, выбирая уникальные элементы используя unique, и печатая пространство, разделенное использованием cat.




2

К, 17 байт

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

Не так много, чтобы сказать здесь. Сортировать ( t@<t:) уникальные предметы (? ) ,/умноженного ( ) умноженного декартова собственного произведения ( t*\:t:) от 1 до N включительно ( 1+!).

В бою:

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

2

Haskell, 55 54 байта

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

Пример использования: f 4->[1,2,3,4,6,8,9,12,16] .

nub удаляет дубликаты элементов из списка.

Редактировать: @Zgarb нашел лишнее $.


2

J, 21 20 байт

Спасибо @Zgarb за -1 байт!

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

Мой первый ответ J! Гольф советы приветствуются, если есть что-то для гольфа.

Это монадическая функция; мы берем внешний продукт умножением списка 1..inputна себя, выравниваем, берем уникальные элементы и сортируем.


2

Котлин, 70 байт

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

Безголовая версия:

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

Проверьте это с:

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

2

Shell + коммунальные услуги, 41

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

Или в качестве альтернативы:

Bash + coreutils, 48

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

Создает расширение в фигурном расширении:

\$[{1..n}*{1..n}]расширяется до арифметических расширений, $[1*1] $[1*2] ... $[1*n] ... $[n*n]которые оцениваются и передаются printf, что печатает по одному на строку, по которой передается sort.

Тщательное использование кавычек, экранирование и evalобеспечение расширения происходит в необходимом порядке.


Или в качестве альтернативы:

Чистый Баш, 60

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


1

Минколанг 0,14 , 25 22 18 байт

Я вспомнил, что я очень удобно реализовывал декартовы продукты, прежде чем этот вопрос был опубликован !

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

Попробуй это здесь.(Выходы в обратном порядке.)

объяснение

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 байт

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

объяснение

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

Тест

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 байт

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

Пример использования:

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 байт

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

Довольно скучный. Просто фильтрует список [1..n*n]по элементам формы a*bс aи bв [1..n]. Использование filterдает одинаковую длину

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

Некоторое время я пытался составить список продуктов с чем-то более умным, как concatMapили mapM, но получил только более длинные результаты. Более сложная проверка членства выполняется на 52 байта, на 1 байт длиннее, но, возможно, может быть сокращена.

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

Вы можете сохранить 3 байта, используя (*)<$>..<*>..как это
ბიმო

1

JAVA - 86 байт

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

Ungolfed

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

Pyth, 11 байт

S{sm*RdSdSQ

Это похоже на ответ Юлии. Благодаря @Maltysen


1

PHP, 74,73 70 байтов

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

Ungolfed:

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

Предыдущая:

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

Не уверен на 100%, что делать с выводом, но $aсодержит массив с соответствующими числами. $nэто число, полученное через $_GET['n'], сregister_globals=1


1

TeaScript , 37 35 символов; 40 байт

Сохранено 2 байта благодаря @Downgoat

TeaScript - это JavaScript для игры в гольф.

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

Попробуйте онлайн!

Неуправляемый и объяснение

(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

Вы можете просто использовать rвместо A.rгенерации диапазонов
Downgoat

Уверен, что это 35 байтов ? Я получаю 35 символов или 40 байтов.
manatwork

@manatwork Это будет 35 байтов в формате кодирования ISO / IEC_8859-1 . Но я не уверен, что TeaScript поддерживает эту кодировку, поэтому я пока поменяю ее на 40 байт.
ETHproductions

0

C 96 байтов

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

Это печатает числа в порядке убывания. Предложения приветствуются, так как это выглядит далеко не оптимально.


0

JavaScript (ES6), 86 байт

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}

Глядя, чтобы сократить его (может быть, попробует вложенные циклы).


0

Perl 5, 91 байт

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

запускаться путем передачи аргумента в командной строке. Это довольно много заявлений, за исключением того, чтобы работать с ограничениями и предупреждениями.


0

Python, 124 102 байта

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

Больше питона!


2
На самом деле это 123 байта, а не 124. Но вы можете сэкономить несколько байтов, используя только один пробел на уровень отступа, а не 4.
Алекс А.

1
Вы также можете поставить l.append(i*j)на одну строку с условным условием if. Я думаю, что в итоге получается 102 байта.
El'endia Starman

3
И использовать +=вместо append.
Картик

@ El'endiaStarman отредактировал, спасибо!
TanMath

1
Одна относительно небольшая проблема: list(set(l))сортировка не гарантируется.
El'endia Starman

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.