Classificar os números exclusivos em uma tabela de multiplicação

30

Desafio bastante simples hoje:

Escreva um programa ou função que receba um número inteiro positivo N e imprima ou retorne uma lista classificada dos números exclusivos que aparecem na tabela de multiplicação cujos multiplicandos de linha e coluna variam de 1 a N, inclusive.

A lista pode ser classificada em ordem crescente (do menor para o maior) ou em ordem decrescente (do maior para o menor) e pode ser impressa em qualquer formato razoável.

O código mais curto em bytes vence!

Exemplo

Quando N = 4, a tabela de multiplicação se parece com:

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

Os números únicos na tabela são 1, 2, 3, 4, 6, 8, 9, 12, 16. Eles já estão classificados, então

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

pode ser sua saída exata para N = 4. Mas, como a classificação pode ser revertida e há alguma margem de manobra na formatação, essas também seriam saídas válidas:

[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

Casos de teste

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]
Passatempos de Calvin
fonte
Então, basicamente, o código retorna uma lista de números na tabela de multiplicação especificada por N, exceto que qualquer número não pode ser repetido?
TanMath
Quão grande N pode ser?
Xsot # 28/15
1
@xsot Você pode assumir N * N será menor do que o valor int costume máximo do seu idioma (provavelmente 2 ^ 31-1)
Calvin Hobbies
Então, essencialmente, isso é 1-n e não-primos até n ^ 2.
gregsdennis
1
@gregsdennis Não. Não há muitos compósitos presentes. por exemplo, 91, 92, 93, 94, 95, 96 para N = 10.
Calvin's Hobbies

Respostas:

12

Pitão, 8 bytes

S{*M^SQ2

Experimente online.

Explicação: SQpega a entrada da lista avaliada ( Q) e faz uma lista [1, 2, ..., Q]. ^SQ2leva consigo o produto cartesiano dessa lista - todas as combinações possíveis de produtos. *Mmultiplica todos esses pares para formar todos os resultados possíveis na tabela de multiplicação e o S{torna único e o classifica.

orlp
fonte
@FryAmTheEggman A entrada 5 já precisa de classificação, caso contrário, os 10 e 9 na saída estão fora de ordem.
Reto Koradi
maldito, continuo esquecendo disso M. +1
Maltysen
13

Python 2, 61 51 bytes

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

Agradecemos ao xnor por reduzir algumas sintaxes.

xsot
fonte
1
O set(...)pode ser apenas um conjunto de comp {...}. Além disso, as funções são permitidas por padrão aqui, para que você possa escrever lambda n:....
Xnor
Obrigado por me lembrar sobre a compreensão do conjunto, esqueci completamente que ela existia.
Xsot # 28/15
Eu não posso ver uma maneira melhor de fazer isso, o melhor que eu vejo com recursividade é 56: f=lambda n:n*[0]and sorted(set(range(n,n*n+n,n)+f(n-1))).
Xnor
11

APL, 18 16 bytes

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

Esta é uma função monádica sem nome. A saída está em ordem crescente.

Explicação:

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

Corrigido um problema e economizado 2 bytes graças a Thomas Kwa!

Alex A.
fonte
7

CJam, 14 12 bytes

Versão mais recente com melhorias propostas pelo @aditsu:

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

Esta é uma função anônima. Experimente online , com o código de entrada / saída necessário para testá-lo.

A @Martin propôs outra solução muito elegante ( {,:)_ff*:|$}) com o mesmo comprimento. Eu usei o do aditsu porque era muito mais parecido com a minha solução original.

A principal diferença para minha solução original é que isso mantém o 0valor na sequência original, que economiza 2 bytes no início. Você pensaria que isso não ajudaria, porque você precisa remover o 0valor do resultado. Mas o núcleo da ideia do @ aditsu é 0^o final, que é uma diferença definida 0. Isso remove 0e, ao mesmo tempo, como é uma operação de conjunto, elimina elementos duplicados do conjunto de soluções. Como eu já precisava de 2 bytes para eliminar as duplicatas antes, a remoção 0é essencialmente gratuita.

Explicação:

{     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.
Reto Koradi
fonte
Para o mesmo comprimento, {2m*::)::*_&$},{)2m*::*_&$0-}
Peter Taylor
2
Como sobre isso por dois bytes menos :){,:)_ff*:|$}
Martin Ender
1
Outra maneira:{)2m*::*0^$}
aditsu 28/11/2015
5

Oitava, 22 bytes

@(n)unique((a=1:n)'*a)
alefalpha
fonte
4

Julia, 24 bytes

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

Esta é uma função anônima que aceita um número inteiro e retorna uma matriz inteira.

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
Alex A.
fonte
4

MATLAB, 24 bytes

@(n)unique((1:n)'*(1:n))
Stewie Griffin
fonte
Um bom! Em breve será possível fazê-lo em 7 ou 8 bytes ... :-)
Luis Mendo
Oooh, legal! :-)
Stewie Griffin
@Luis você já tentou este em MATL?
Stewie Griffin
Eu não tenho muito tempo agora para ler todo o desafio, mas vendo o seu código Matlab parece que ele poderia ser feito com MATL
Luis Mendo
4

zsh, 86 56 bytes

graças a @Dennis por salvar 30 (!) bytes

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

Explicação / não destruído:

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

Isso não funciona no Bash porque o Bash não se expande {1..$1}- apenas o interpreta literalmente (portanto, a=5; echo {1..$a}gera em {1..5}vez de 1 2 3 4 5).

Maçaneta da porta
fonte
Eu estava esperando por uma resposta * sh. : D
Addison Crump
1
Dica relevante para o bash. Parece aplicar-se ao shell Z também.
Dennis
4

Ruby, 50 48 bytes

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

Usando loop aninhado para multiplicar cada número com qualquer outro número até n e, em seguida, classificando a matriz.

50 bytes

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

Uso:

->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]
Vasu Adari
fonte
3

R, 39 bytes

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

Isso lê um número inteiro de STDIN e grava uma lista delimitada por espaço em STDOUT.

Criamos a tabela de multiplicação como uma matriz usando outer, achatamos implicitamente em um vetor e classificamos usando sort, selecionamos elementos exclusivos usando uniquee imprimimos o espaço delimitado usando cat.

Alex A.
fonte
35 bytes
Giuseppe
2

Mathematica, 25 bytes

Union@@Array[1##&,{#,#}]&
alefalpha
fonte
2

K, 17 bytes

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

Não há muito a dizer aqui. Classifique ( t@<t:) os itens exclusivos ( ?) do ,/autoproduto cartesiano multiplicado ( ) achatado ( ) ( t*\:t:1) de 1 até N ( 1+!), inclusive .

Em ação:

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

Haskell, 55 54 bytes

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

Exemplo de uso: f 4-> [1,2,3,4,6,8,9,12,16].

nub remove elementos duplicados de uma lista.

Edit: @Zgarb encontrou um supérfluo $.

nimi
fonte
2

J, 21 20 bytes

Obrigado a @Zgarb por -1 byte!

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

Minha primeira resposta J! Dicas de golfe são apreciadas, se houver algo para jogar golfe.

Esta é uma função monádica; pegamos o produto externo pela multiplicação da lista 1..input, achatamos, pegamos elementos exclusivos e classificamos.

lirtosiast
fonte
2

Kotlin, 70 bytes

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

Versão não destruída:

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

Teste com:

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

Shell + utilitários comuns, 41

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

Ou alternativamente:

Bash + coreutils, 48

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

Constrói uma expansão de braquete dentro de uma expansão aritmética:

\$[{1..n}*{1..n}]expande para as expansões aritméticas $[1*1] $[1*2] ... $[1*n] ... $[n*n]que são avaliadas e passadas para printf, que imprimem uma por linha, às quais são canalizadas sort.

O uso cuidadoso de cotações, escapa e evalgarante que as expansões ocorram na ordem necessária.


Ou alternativamente:

Pure Bash, 60

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

Minkolang 0.14 , 25 22 18 bytes

Lembrei-me de que implementei de maneira muito conveniente produtos cartesianos antes que essa pergunta fosse publicada !

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

Experimente aqui. (Saídas na ordem inversa.)

Explicação

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.
El'endia Starman
fonte
1

JavaScript (ES6), 92 90 bytes

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

Explicação

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

Teste

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>

user81655
fonte
1

Perl 6 , 27 bytes

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

Exemplo de uso:

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)␤
Brad Gilbert b2gills
fonte
1

Haskell, 51 bytes

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

Muito chato. Apenas filtra a lista [1..n*n]para os elementos do formulário a*bcom ae bdentro [1..n]. Usar filterfornece o mesmo comprimento

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

Tentei por um tempo gerar a lista de produtos com algo mais inteligente concatMapou mapM, mas só obtive resultados mais longos. Uma verificação mais sofisticada da associação chegou a 52 bytes, 1 byte mais, mas talvez possa ser reduzida.

f n=[k|k<-[1..n*n],any(\a->k`mod`a<1&&k<=n*a)[1..n]]
xnor
fonte
Você pode salvar 3 bytes usando (*)<$>..<*>..como este
ბიმო
1

JAVA - 86 bytes

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;
}
Yassin Hajaj
fonte
1

Pitão, 11 bytes

S{sm*RdSdSQ

Isso é semelhante à resposta de Julia. Obrigado a @Maltysen

TanMath
fonte
1

PHP, 74,73 70bytes

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

Anterior:

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

Não tem 100% de certeza do que fazer com a saída, mas $acontém uma matriz com os números correspondentes. $né o número geven via $_GET['n'], comregister_globals=1

Martijn
fonte
1

TeaScript , 37 35 caracteres; 40 bytes

Guardado 2 bytes graças a @Downgoat

TeaScript é JavaScript para jogar golfe.

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

Experimente online!

Ungolfed e explicação

(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
ETHproductions
fonte
Você pode apenas usar rem vez de A.rpara as faixas de geração
Downgoat
Claro que isso é 35 bytes ? Eu recebo 35 caracteres ou 40 bytes.
Manatwork
@manatwork Seriam 35 bytes no formato de codificação ISO / IEC_8859-1 . Mas não tenho certeza de que o TeaScript suporta essa codificação, então alterarei para 40 bytes por enquanto.
ETHproductions
0

C, 96 bytes

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

Isso imprime os números em ordem decrescente. As sugestões são bem-vindas, pois isso parece longe de ser o ideal.

xsot
fonte
0

JavaScript (ES6), 86 bytes

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}

Procurando encurtá-lo (talvez tente aninhar loops).

nicael
fonte
0

Perl 5, 91 bytes

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

para ser executado passando o argumento na linha de comando. Faltam poucas declarações para executar com restrições e avisos.

Walter A. Aprile
fonte
0

Python, 124 102 bytes

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

Mais pitônico!

TanMath
fonte
2
Na verdade, são 123 bytes, e não 124. Mas você pode salvar alguns bytes usando apenas um único espaço por nível de indentação, em vez de 4. #
Alex A.
1
Você também pode colocar l.append(i*j)na mesma linha que o if condicional. Eu acho que acaba tendo 102 bytes no total.
El'endia Starman 28/11/2015
3
E use em +=vez de append.
Kartik
@ El'endiaStarman editado, obrigado!
TanMath
1
Uma questão relativamente pequena: list(set(l))não é garantido que seja resolvido.
El'endia Starman 28/11/2015
0

Perl 5, 67 bytes

for$i(1..($n=pop)){$a{$_*$i}++for 1..$n}map say,sort{$a<=>$b}keys%a
msh210
fonte