Trier les nombres uniques dans une table de multiplication

30

Un défi assez simple aujourd'hui:

Écrivez un programme ou une fonction qui accepte un entier positif N et imprime ou retourne une liste triée des nombres uniques qui apparaissent dans la table de multiplication dont les multiplicands de ligne et de colonne vont tous deux de 1 à N inclus.

La liste peut être triée par ordre croissant (du plus petit au plus grand) ou par ordre décroissant (du plus grand au plus petit), et peut être sortie dans n'importe quel format raisonnable.

Le code le plus court en octets gagne!

Exemple

Lorsque N = 4, la table de multiplication ressemble à:

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

Les numéros uniques dans le tableau sont 1, 2, 3, 4, 6, 8, 9, 12, 16. Ceux-ci sont déjà triés, donc

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

pourrait être votre sortie exacte pour N = 4. Mais puisque le tri peut être inversé et qu'il y a une certaine marge de manœuvre dans le formatage, ces sorties seraient également valides:

[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

Cas de test

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]
Loisirs de Calvin
la source
Donc, fondamentalement, le code renvoie une liste de nombres dans la table de multiplication spécifiée par N, sauf qu'aucun nombre ne peut être répété?
TanMath
Quelle taille peut être N?
2015
1
@xsot Vous pouvez supposer que N * N sera inférieur à la valeur int habituelle maximale de votre langue (probablement 2 ^ 31-1)
Calvin's Hobbies
Donc, c'est essentiellement 1-n et non premiers jusqu'à n ^ 2.
gregsdennis
1
@gregsdennis Non. De nombreux composites sont absents. par exemple 91, 92, 93, 94, 95, 96 pour N = 10.
Calvin's Hobbies

Réponses:

12

Pyth, 8 octets

S{*M^SQ2

Essayez-le en ligne.

Explication: SQprend l'entrée de liste évaluée ( Q) et crée une liste [1, 2, ..., Q]. ^SQ2prend le produit cartésien de cette liste avec lui-même - toutes les combinaisons de produits possibles. *Mmultiplie toutes ces paires pour former tous les résultats possibles dans la table de multiplication, la S{rend unique et la trie.

orlp
la source
@FryAmTheEggman L'entrée 5 a déjà besoin d'être triée, sinon les 10 et 9 de la sortie sont en panne.
Reto Koradi
sacrément continuer à oublier cette éclaboussure M. +1
Maltysen
13

Python 2, 61 51 octets

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

Merci à xnor d'avoir raccourci une syntaxe.

xsot
la source
1
Le set(...)peut simplement être un ensemble comp {...}. De plus, les fonctions sont autorisées par défaut ici, vous pouvez donc simplement écrire lambda n:....
2015 à 7h03
Merci de m'avoir rappelé la compréhension des ensembles, j'ai complètement oublié qu'elle existait.
2015
Je ne vois pas une meilleure façon de le faire, mieux que je vois avec récursion est 56: f=lambda n:n*[0]and sorted(set(range(n,n*n+n,n)+f(n-1))).
2015 à 7h22
11

APL, 18 16 octets

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

Il s'agit d'une fonction monadique sans nom. La sortie est en ordre croissant.

Explication:

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

Correction d'un problème et sauvegarde de 2 octets grâce à Thomas Kwa!

Alex A.
la source
7

CJam, 14 12 octets

Dernière version avec améliorations proposées par @aditsu:

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

Il s'agit d'une fonction anonyme. Essayez-le en ligne , avec le code d'entrée / sortie nécessaire pour le tester.

@Martin a proposé une autre solution très élégante ( {,:)_ff*:|$}) de même longueur. J'ai utilisé celui d'Aditsu parce qu'il était beaucoup plus similaire à ma solution d'origine.

La principale différence avec ma solution d'origine est qu'elle conserve la 0valeur dans la séquence d'origine, ce qui économise 2 octets au début. Vous penseriez que cela n'aiderait pas, car vous devez supprimer la 0valeur du résultat. Mais le cœur de l'idée de @ aditsu est 0^la fin, ce qui est une différence fixe avec 0. Cela supprime le 0, et en même temps, puisqu'il s'agit d'une opération d'ensemble, élimine les éléments en double de l'ensemble de solutions. Étant donné que j'avais déjà besoin de 2 octets pour éliminer les doublons auparavant, la suppression du 0est alors essentiellement gratuite.

Explication:

{     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
la source
Pour la même longueur, {2m*::)::*_&$},{)2m*::*_&$0-}
Peter Taylor
2
Que diriez-vous de cela pour deux octets de moins :){,:)_ff*:|$}
Martin Ender
1
Une autre façon:{)2m*::*0^$}
aditsu
5

Octave, 22 octets

@(n)unique((a=1:n)'*a)
alephalpha
la source
4

Julia, 24 octets

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

Il s'agit d'une fonction anonyme qui accepte un entier et renvoie un tableau d'entiers.

Non golfé:

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.
la source
4

MATLAB, 24 octets

@(n)unique((1:n)'*(1:n))
Stewie Griffin
la source
Bon! Bientôt il sera possible de le faire en 7 ou 8 octets ... :-)
Luis Mendo
Oooh, sympa! :-)
Stewie Griffin
@Luis avez-vous essayé celui-ci en MATL?
Stewie Griffin
Je n'ai pas beaucoup de temps maintenant pour lire tout le défi, mais en voyant votre code Matlab, il semble que cela pourrait être fait avec MATL
Luis Mendo
4

zsh, 86 56 octets

merci à @Dennis pour avoir économisé 30 (!) octets

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

Explication / non golfé:

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

Cela ne fonctionne pas dans Bash parce que Bash ne se développe pas {1..$1}- il l'interprète juste littéralement (donc, a=5; echo {1..$a}sort {1..5}au lieu de 1 2 3 4 5).

Poignée de porte
la source
J'attendais une réponse * sh. : D
Addison Crump
1
Astuce bash pertinente. Semble également s'appliquer à la coque Z.
Dennis
4

Rubis, 50 48 octets

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

Non golfé:

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

Utilisation de la boucle imbriquée pour multiplier chaque nombre par un autre nombre jusqu'à n, puis tri du tableau.

50 octets

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

Usage:

->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
la source
3

R, 39 octets

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

Cela lit un entier depuis STDIN et écrit une liste délimitée par des espaces dans STDOUT.

Nous créons la table de multiplication sous forme de matrice à l'aide outer, aplatissons implicitement dans un vecteur et trions à l'aide sort, sélectionnons des éléments uniques à l'aide uniqueet imprimons l'espace délimité à l'aide cat.

Alex A.
la source
35 octets
Giuseppe
2

Mathematica, 25 octets

Union@@Array[1##&,{#,#}]&
alephalpha
la source
2

K, 17 octets

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

Pas grand chose à dire ici. Trier ( t@<t:) les éléments uniques ( ?) de l' ,/autoproduit cartésien multiplié aplati ( t*\:t:) de 1 à N ( 1+!) inclus .

En action:

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

Haskell, 55 54 octets

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

Exemple d'utilisation: f 4->[1,2,3,4,6,8,9,12,16] .

nub supprime les éléments en double d'une liste.

Edit: @Zgarb a trouvé un superflu $.

nimi
la source
2

J, 21 20 octets

Merci à @Zgarb pour -1 octet!

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

Ma première réponse J! Les conseils de golf sont appréciés s'il y a quelque chose à jouer au golf.

Il s'agit d'une fonction monadique; nous prenons le produit extérieur par multiplication de la liste 1..inputavec lui-même, aplatissons, prenons des éléments uniques et trions.

lirtosiast
la source
2

Kotlin, 70 octets

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

Version non golfée:

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

Testez-le avec:

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

Shell + utilitaires communs, 41

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

Ou bien:

Bash + coreutils, 48

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

Construit une expansion d'accolade à l'intérieur d'une expansion arithmétique:

\$[{1..n}*{1..n}]se développe aux extensions arithmétiques $[1*1] $[1*2] ... $[1*n] ... $[n*n]qui sont évaluées et transmises à printf, qui en imprime une par ligne, qui est dirigée vers sort.

Utilisez soigneusement les devis, les évasions et evalassurez-vous que les extensions se produisent dans l'ordre requis.


Ou bien:

Pure Bash, 60

eval a=($(eval echo [\$[{1..$1}*{1..$1}\]]=1))
echo ${!a[@]}
Traumatisme numérique
la source
1

Minkolang 0,14 , 25 22 18 octets

Je me suis souvenu que j'avais implémenté très commodément des produits cartésiens avant que cette question ne soit publiée !

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

Essayez-le ici.(Sorties dans l'ordre inverse.)

Explication

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
la source
1

JavaScript (ES6), 92 90 octets

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

Explication

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

Tester

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
la source
1

Perl 6 , 27 octets

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

Exemple d'utilisation:

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
la source
1

Haskell, 51 octets

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

Plutôt ennuyeux. Filtre simplement la liste [1..n*n]des éléments du formulaire a*bavec aet bdans [1..n]. L'utilisation filterdonne la même longueur

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

J'ai essayé pendant un certain temps de générer la liste des produits avec quelque chose de plus intelligent comme concatMapou mapM, mais je n'ai obtenu que des résultats plus longs. Une vérification plus sophistiquée de l'adhésion est arrivée à 52 octets, 1 octet de plus, mais peut peut-être être raccourcie.

f n=[k|k<-[1..n*n],any(\a->k`mod`a<1&&k<=n*a)[1..n]]
xnor
la source
Vous pouvez économiser 3 octets en utilisant (*)<$>..<*>..comme ceci
ბიმო
1

JAVA - 86 octets

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

Non golfé

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
la source
1

Pyth, 11 octets

S{sm*RdSdSQ

Ceci est similaire à la réponse de Julia. Merci à @Maltysen

TanMath
la source
1

PHP, 74,73 70 octets

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

Non golfé:

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

Précédent:

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

Pas sûr à 100% de ce qu'il faut faire avec la sortie, mais $acontient un tableau avec les numéros correspondants. $nest le nombre via $_GET['n'], avecregister_globals=1

Martijn
la source
1

TeaScript , 37 35 caractères; 40 octets

Sauvegardé 2 octets grâce à @Downgoat

TeaScript est JavaScript pour le golf.

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

Essayez-le en ligne!

Non golfé et explication

(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
la source
Vous pouvez simplement utiliser rau lieu de A.rpour générer des plages
Downgoat
Bien sûr, cela fait 35 octets ? J'obtiens 35 caractères ou 40 octets.
manatwork
@manatwork Ce serait 35 octets au format de codage ISO / IEC_8859-1 . Mais je ne suis pas sûr que TeaScript supporte cet encodage, donc je vais le changer à 40 octets pour l'instant.
ETHproductions
0

C, 96 octets

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

Ceci imprime les nombres dans l'ordre décroissant. Les suggestions sont les bienvenues car cela semble loin d'être optimal.

xsot
la source
0

JavaScript (ES6), 86 octets

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}

Vous cherchez à le raccourcir (essayez peut-être d'essayer des boucles d'imbrication).

nicael
la source
0

Perl 5, 91 octets

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

à exécuter en passant l'argument sur la ligne de commande. Il y a quelques déclarations à court d'exécution avec des restrictions et des avertissements.

Walter A. Aprile
la source
0

Python, 124 102 octets

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

Plus pythonique!

TanMath
la source
2
Il s'agit en fait de 123 octets, pas de 124. Mais vous pouvez économiser quelques octets en n'utilisant qu'un seul espace par niveau d'indentation plutôt que 4.
Alex A.
1
Vous pouvez également mettre l.append(i*j)sur la même ligne que si conditionnel. Je pense que cela finit par être de 102 octets au total.
El'endia Starman
3
Et utilisez +=plutôt append.
Kartik
@ El'endiaStarman édité, merci!
TanMath
1
Un problème relativement mineur: list(set(l))le tri n'est pas garanti.
El'endia Starman
0

Perl 5, 67 octets

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