Ordina i numeri univoci in una tabella di moltiplicazione


30

Una sfida abbastanza semplice oggi:

Scrivi un programma o una funzione che accetta un numero intero positivo N e stampa o restituisce un elenco ordinato dei numeri univoci che compaiono nella tabella di moltiplicazione i cui moltiplicatori di riga e colonna vanno entrambi da 1 a N compreso.

L'elenco può essere ordinato in ordine crescente (dal più piccolo al più grande) o in ordine decrescente (dal più grande al più piccolo) e può essere prodotto in qualsiasi formato ragionevole.

Vince il codice più breve in byte!

Esempio

Quando N = 4, la tabella di moltiplicazione appare come:

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

I numeri univoci nella tabella sono 1, 2, 3, 4, 6, 8, 9, 12, 16. Questi sono già ordinati, quindi

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

potrebbe essere l'output esatto per N = 4. Ma poiché l'ordinamento può essere invertito e c'è un margine di manovra nella formattazione, questi sarebbero anche output validi:

[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

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

Quindi, in sostanza, il codice restituisce un elenco di numeri nella tabella di moltiplicazione specificata da N, tranne per il fatto che qualsiasi numero non può essere ripetuto?
TanMath,

Quanto può essere grande N?
xsot,

1
@xsot Puoi dare per scontato che N * N sia inferiore al valore int abituale massimo della tua lingua (probabilmente 2 ^ 31-1)
Calvin's Hobbies

Quindi essenzialmente questo è 1-n e non primi fino a n ^ 2.
Gregregdennis,

1
@gregsdennis No. Ci sono molti compositi non presenti. ad es. 91, 92, 93, 94, 95, 96 per N = 10.
Calvin's Hobbies,

Risposte:


12

Pyth, 8 byte

S{*M^SQ2

Provalo online.

Spiegazione: SQaccetta l'input dell'elenco valutato ( Q) e crea un elenco [1, 2, ..., Q]. ^SQ2porta con sé il prodotto cartesiano di quell'elenco - tutte le possibili combinazioni di prodotti. *Mmoltiplica tutte queste coppie insieme per formare tutti i possibili risultati nella tabella di moltiplicazione e la S{rende unica e ordinata.


@FryAmTheEggman L'ingresso 5 richiede già l'ordinamento, altrimenti i 10 e 9 nell'output sono fuori servizio.
Reto Koradi,

dannatamente continua a dimenticarti di quello schifo M. +1
Maltysen,

13

Python 2, 61 51 byte

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

Grazie a xnor per abbreviare la sintassi.


1
La set(...)può essere solo un gruppo di concorrenti {...}. Inoltre, le funzioni sono consentite per impostazione predefinita qui, quindi puoi semplicemente scrivere lambda n:....
xnor

Grazie per avermi ricordato della comprensione impostata, ho completamente dimenticato che esistesse.
xsot,

Non riesco a vedere un modo migliore per fare questo, meglio vedo con la ricorsione è 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←∪,∘.×⍨⍳⍵]}

Questa è una funzione monadica senza nome. L'output è in ordine crescente.

Spiegazione:

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

Risolto un problema e salvato 2 byte grazie a Thomas Kwa!


7

CJam, 14 12 byte

Ultima versione con miglioramenti proposti da @aditsu:

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

Questa è una funzione anonima. Provalo online , con il codice di input / output necessario per testarlo.

@Martin ha proposto un'altra soluzione molto elegante ( {,:)_ff*:|$}) con la stessa lunghezza. Ho usato quello di aditsu perché era molto più simile alla mia soluzione originale.

La differenza principale rispetto alla mia soluzione originale è che questo mantiene il 0valore nella sequenza originale, che consente di risparmiare 2 byte all'inizio. Penseresti che questo non sarebbe d'aiuto, perché devi rimuovere il 0valore dal risultato. Ma il nucleo dell'idea di @aditsu è 0^alla fine, con una certa differenza 0. Questo rimuove il 0, e allo stesso tempo, dal momento che è un'operazione di set, elimina elementi duplicati dal set di soluzioni. Dato che avevo già bisogno di 2 byte per eliminare i duplicati prima, la rimozione di 0è quindi essenzialmente gratuita.

Spiegazione:

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

Per la stessa lunghezza, {2m*::)::*_&$},{)2m*::*_&$0-}
Peter Taylor

2
Che ne dici di questo per due byte in meno :){,:)_ff*:|$}
Martin Ender il

1
Un altro modo:{)2m*::*0^$}
aditsu,


4

Julia, 24 byte

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

Questa è una funzione anonima che accetta un numero intero e restituisce un array di numeri interi.

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

zsh, 86 56 byte

grazie a @Dennis per aver salvato 30 (!) byte

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

Spiegazione / non golfato:

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

Questo non funziona in Bash perché Bash non si espande {1..$1}, ma lo interpreta letteralmente (quindi, invece di a=5; echo {1..$a}output ).{1..5}1 2 3 4 5


Stavo aspettando una risposta * sh. : D
Addison Crump,

1
Punta bash pertinente. Sembra applicarsi anche alla shell Z.
Dennis,


4

Rubino, 50 48 byte

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

Utilizzo del loop nidificato per moltiplicare ciascun numero con tutti gli altri numeri fino a n e quindi ordinare l'array.

50 byte

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

3

R, 39 byte

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

Questo legge un numero intero da STDIN e scrive un elenco delimitato da spazi su STDOUT.

Creiamo la tabella di moltiplicazione come matrice usando outer, appiattiamo implicitamente un vettore e ordiniamo usando sort, selezioniamo elementi unici usando uniquee stampiamo lo spazio delimitato usando cat.




2

K, 17 byte

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

Non c'è molto da dire qui. Ordina ( t@<t:) gli articoli univoci ( ?) del ,/sottoprodotto cartesiano moltiplicato ( t*\:t:) ( ) di 1 fino a N ( 1+!) incluso .

In azione:

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

Esempio di utilizzo: f 4-> [1,2,3,4,6,8,9,12,16].

nub rimuove elementi duplicati da un elenco.

Modifica: @Zgarb ha trovato un superfluo $.


2

J, 21 20 byte

Grazie a @Zgarb per -1 byte!

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

La mia prima risposta J! I suggerimenti per il golf sono apprezzati, se c'è qualcosa da golf.

Questa è una funzione monadica; prendiamo il prodotto esterno moltiplicando l'elenco 1..inputcon se stesso, appiattiamo, prendiamo elementi unici e ordiniamo.


2

Kotlin, 70 byte

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

Versione non golfata:

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

Provalo con:

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

2

Shell + utilità comuni, 41

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

O in alternativa:

Bash + coreutils, 48

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

Costruisce un'espansione di parentesi graffe all'interno di un'espansione aritmetica:

\$[{1..n}*{1..n}]si espande alle espansioni aritmetiche $[1*1] $[1*2] ... $[1*n] ... $[n*n]che vengono valutate e passate a printf, che stampa uno per riga, a cui viene convogliato sort.

Uso attento di preventivi, fughe e evalassicurarsi che le espansioni avvengano nell'ordine richiesto.


O in alternativa:

Pure Bash, 60

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


1

Minkolang 0,14 , 25 22 18 byte

Mi sono ricordato che ho implementato molto comodamente i prodotti cartesiani prima che questa domanda fosse pubblicata !

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

Provalo qui. (Uscite in ordine inverso.)

Spiegazione

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

Spiegazione

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

Test

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

Esempio di utilizzo:

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

Piuttosto noioso. Filtra l'elenco [1..n*n]in base agli elementi del modulo a*bcon ae bin [1..n]. L'utilizzo filterdà la stessa lunghezza

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

Ho provato per un po 'a generare l'elenco dei prodotti con qualcosa di più intelligente concatMapo mapM, ma ho ottenuto solo risultati più lunghi. Un controllo più sofisticato dell'appartenenza è arrivato a 52 byte, 1 byte in più, ma forse può essere abbreviato.

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

È possibile salvare 3 byte utilizzando (*)<$>..<*>..come questo
ბიმო

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

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 byte

S{sm*RdSdSQ

Questo è simile alla risposta di Julia. Grazie a @Maltysen


1

PHP, 74,73 70 byte

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

Precedente:

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

Non sono sicuro al 100% di cosa fare con l'output, ma $acontiene un array con i numeri corrispondenti. $nè il numero via via $_GET['n'], conregister_globals=1


1

TeaScript , 37 35 caratteri; 40 byte

Salvato 2 byte grazie a @Downgoat

TeaScript è JavaScript per il golf.

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

Provalo online!

Ungolfed e spiegazione

(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

Puoi semplicemente utilizzare rinvece di A.rgenerare intervalli
Downgoat

Sicuro questo è 35 byte ? Ottengo 35 caratteri o 40 byte.
arte

@manatwork Questo sarebbe 35 byte nel formato di codifica ISO / IEC_8859-1 . Ma non sono sicuro che TeaScript supporti tale codifica, quindi per ora lo cambierò in 40 byte.
ETHproductions

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

Questo stampa i numeri in ordine decrescente. I suggerimenti sono benvenuti in quanto questo sembra tutt'altro che ottimale.


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}

Cercando di accorciarlo (forse proverò ad annidare i loop).


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

da eseguire passando l'argomento sulla riga di comando. Sono poche le dichiarazioni a corto di rigature e avvertimenti.


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

Più pitonico!


2
Si tratta in realtà di 123 byte, non di 124. Ma è possibile salvare alcuni byte utilizzando solo un singolo spazio per livello di rientro anziché 4.
Alex A.

1
Puoi anche mettere l.append(i*j)sulla stessa riga del condizionale if. Penso che finisca per essere 102 byte complessivamente.
El'endia Starman,

3
E usa +=invece di append.
Kartik,

@ El'endiaStarman modificato, grazie!
TanMath,

1
Un problema relativamente minore: list(set(l))non è garantito che sia ordinato.
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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.