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]

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.


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


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!


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.

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


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


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


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]

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.




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

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


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.


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

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[@]}


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.

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>


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

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

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

1

Pyth, 11 octets

S{sm*RdSdSQ

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


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


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

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.


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


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.


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!


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.