Trier par multiplier


34

Vous devriez écrire un programme ou une fonction qui donne une liste d’entiers positifs multipliant chaque élément avec le plus petit entier positif possible pour créer une liste strictement croissante.

Par exemple, si l'entrée est

5 4 12 1 3

les multiplications seront

5*1=5 4*2=8 12*1=12 1*13=13 3*5=15

et la sortie sera la liste croissante

5 8 12 13 15

Contribution

  • Une liste d'entiers positifs contenant au moins 1 élément

Sortie

  • Une liste d'entiers positifs

Exemples

9 => 9
1 2 => 1 2
2 1 => 2 3
7 3 => 7 9
1 1 1 1 => 1 2 3 4
5 4 12 1 3 => 5 8 12 13 15
3 3 3 8 16 => 3 6 9 16 32
6 5 4 3 2 1 => 6 10 12 15 16 17
9 4 6 6 5 78 12 88 => 9 12 18 24 25 78 84 88
8 9 41 5 12 3 5 6 => 8 9 41 45 48 51 55 60
15 8 12 47 22 15 4 66 72 15 3 4 => 15 16 24 47 66 75 76 132 144 150 153 156

Il s’agit d’un code de golf, de sorte que le programme ou la fonction le plus court gagne.

Fait amusant: le dernier élément de la sortie pour l'entrée N, N-1, ... ,1semble être l' (N+1)thélément de la séquence A007952 . Si vous trouvez une preuve, vous êtes invité à l'inclure dans votre réponse au golf ou à la poster en tant que commentaire.


Quelqu'un a-t-il déjà trouvé une solution à cette preuve?
Connor Clark

Réponses:


20

Gelée , 6 à 5 octets

:‘×µ\

Première réponse Jelly avant que @Dennis se réveille et me batte. Essayez-le en ligne!

Explication

:          Integer division, m//n
 ‘         Increment, (m//n+1)
  ×        Multiply, (m//n+1)*n
   µ       Turn the previous links into a new monadic chain
    \      Accumulate on the array

Merci à @Dennis pour -1 octet.


4
:‘×µ\enregistre un octet.
Dennis

20
@ Dennis Oh merde, il s'est réveillé
Dennis van Gils

9

JavaScript (ES6), 28

modifier Comme suggéré par @Patrick Roberts, ppeut être un paramètre non initialisé. Même nombre d'octets mais éviter d'utiliser une variable globale

(a,p)=>a.map(n=>p=n*-~(p/n))

TESTER

f=(a,p)=>a.map(n=>p=n*-~(p/n))

console.log=x=>O.textContent+=x+'\n'

;[
[[9], [ 9]],
[[1, 2], [ 1, 2]],
[[2, 1], [ 2, 3]],
[[7, 3], [ 7, 9]],
[[1, 1, 1, 1], [ 1, 2, 3, 4]],
[[5, 4, 12, 1, 3], [ 5, 8, 12, 13, 15]],
[[3, 3, 3, 8, 16], [ 3, 6, 9, 16, 32]],
[[6, 5, 4, 3, 2, 1], [ 6, 10, 12, 15, 16, 17]],
[[9, 4, 6, 6, 5, 78, 12, 88], [ 9, 12, 18, 24, 25, 78, 84, 88]],
[[8, 9, 41, 5, 12, 3, 5, 6], [ 8, 9, 41, 45, 48, 51, 55, 60]],
[[15, 8, 12, 47, 22, 15, 4, 66, 72, 15, 3, 4], [ 15, 16, 24, 47, 66, 75, 76, 132, 144, 150, 153, 156]]
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i),ok=(k+'')==(r+'')
  console.log(i + ' => ' + r + (ok?' OK':'FAIL expecting '+x))
})
<pre id=O></pre>


Je pense que vous pouvez économiser quelques octets en utilisant modulo, tout comme je l’ai fait dans ma réponse .
aross

Ne pouvez-vous pas sauter le p = 0? Vous en avez besoin pour exécuter plusieurs listes, mais la question ne concerne qu'une liste
Charlie Wynn

1
@CharlieWynn si vous n'initialisez pas une variable, vous obtenez l'erreur pour la variable non définie. Si par hasard la variable existe déjà (ce qui pourrait facilement arriver dans l'environnement d'une page Web), elle pourrait avoir une valeur erronée.
Edc65

@ edc65 bien sûr, p est déjà défini sur cette page!
Charlie Wynn

1
@PatrickRoberts penser à nouveau, je pourrais encore éviter GLOBALS: f=a=>a.map(n=>a+=n-a%n,a=0). Mais ce n'est pas mon algorithme (idiot moi) donc je vais garder le mien tel quel et le vote vers le haut
edc65

6

Python 2, 67 64 octets

Commencez par essayer le code-golf, les conseils sont donc appréciés.

def m(l):
 for x in range(1,len(l)):l[x]*=l[x-1]/l[x]+1
 print l

Bonjour, je pense que vous comptez les retours à la ligne comme 2 octets chacun (avec Windows?), Mais sur ce site, vous comptez chaque retour à la ligne comme un seul octet. Donc, votre score est en réalité de 65 octets. (Vous pouvez copier et coller votre code dans mothereff.in/byte-counter si vous n’êtes pas sûr.) Vous pouvez également le faire print lau lieu de return lsauvegarder un autre octet. Bon travail!
mathmandan

Merci, je n'étais pas au courant des retours en ligne. Cela explique pourquoi j’ai toujours eu différents nombres d’octets. Et je n'ai même pas considéré que l'impression était suffisante et qu'il n'était pas nécessaire de renvoyer la liste.
Taronyu

Aucun problème! BTW, puisque vous avez mentionné que "les conseils sont appréciés", vous pourriez être intéressé par la navigation sur codegolf.stackexchange.com/questions/54/… . Prendre plaisir!
mathmandan

5

PHP, 55 46 42 41 octets

Utilise le codage ISO 8859-1.

for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;

Courez comme ceci ( -dajouté pour l'esthétique seulement):

php -d error_reporting=30709 -r 'for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;' 10 10 8
  • Enregistré 1 octet à Ismael Miguel.
  • Sauvegardé 8 octets en utilisant modulo au lieu de floor
  • Enregistré 4 octets thx à Ismael Miguel (pour au lieu de pour chaque)
  • Enregistré un octet en utilisant pour donner un espace.

Je pense que vous pouvez remplacer $a+0par +$a. En outre, vous pouvez supposer que l’entrée n’aura jamais de valeur 0, vous pouvez donc $a+0&&printsimplement remplacer votre par +$a&print. En fait, vous pourriez même le faire $a&print, car en PHP "0" == 0 == 0.0 == false. Mais cela ne sera peut-être pas nécessaire si vous utilisez simplement un echo, je pense.
Ismael Miguel

Le binaire andne fonctionnera pas (contrairement à la logique), et écho ne fonctionnera pas de cette façon. Étant donné que je prends des informations de la CLI, le premier argument est celui -que je veux comprendre au lieu d’imprimer un zéro. Essayez php -r 'print_r($argv);' foo. Enregistré 1 octet avec votre première suggestion cependant, thx.
aross

1
Que diriez- for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,' ';vous Il a une longueur de 42 octets et ignore le premier élément.
Ismael Miguel

Nice one, merci @IsmaelMiguel
aross

De rien. Si vous voulez être vraiment pervers, vous pouvez remplacer l'espace par a^A, mais cela produirait trop d'avertissements (les avertissements sont ignorables). Cela ne changera en rien le nombre de tiers, mais il semblera que ce sera différent.
Ismael Miguel

4

Haskell (30 28 25 octets)

scanl1(\x y->y*div x y+y)

Version élargie

f :: Integral n => [n] -> [n]
f xs = scanl1 increaseOnDemand xs
 where
   increaseOnDemand :: Integral n => n -> n -> n
   increaseOnDemand acc next = next * (1 + acc `div` next)

Explication

scanl1vous permet de plier une liste et d’accumuler toutes les valeurs intermédiaires dans une autre liste. C'est une spécialisation de scanl, qui a le type suivant:

scanl  :: (acc  -> elem -> acc)  -> acc -> [elem] -> [acc]
scanl1 :: (elem -> elem -> elem) ->        [elem] -> [elem]

scanl1 f (x:xs) = scanl f x xs

Par conséquent, tout ce dont nous avons besoin est une fonction appropriée prenant à la fois le dernier élément de notre liste ( accdans la version étendue) et celui que nous souhaitons traiter ( nextdans la version étendue) et renvoyer un nombre approprié.

Nous pouvons facilement déduire ce nombre en divisant l'accumulateur par le suivant et en recouvrant le résultat. divprend soin de cela. Ensuite, nous devons simplement ajouter 1pour nous assurer que la liste augmente réellement (et que nous ne finissons pas avec 0).


Pas besoin de donner un nom à votre fonction. Vous pouvez également remplacer le ( ... )avec par $ ...et je pense que vous avez compté une nouvelle ligne qui peut être omise:, scanl1$\x y->y*div x y+y24 octets.
nimi

@nimi: vraiment? Les expressions comptent? Cela étant dit, je ne sauve pas d'octets avec (...)vs $, car $\ est analysé en tant qu'opérateur et j'aurais besoin d'un espace après $.
Zeta

Les fonctions non nommées sont autorisées par défaut et scanl1(...)est une fonction non nommée. En ce qui concerne $vs (): vous avez raison, mon erreur.
nimi

4

C ++, 63 60 57 octets

void s(int*f,int*e){for(int c=*f;++f!=e;c=*f+=c/ *f**f);}

Fonctionne sur place étant donné une plage [first, last). Initialement écrit en tant que variante de modèle, mais c'était plus long:

template<class T>void s(T f,T e){for(auto c=*f;++f!=e;c=*f+=c/ *f**f);}

Version étendue

template <class ForwardIterator>
void sort(ForwardIterator first, ForwardIterator last){
    auto previous = *first;

    for(++first; first != last; ++first){
        auto & current = *first;
        current += current * (current / previous);
        previous = current;
    }
}

3

CJam, 13 octets

q~{\_p1$/)*}*

Entrée sous forme de liste de style CJam. La sortie est séparée par un saut de ligne.

Testez-le ici.

Explication

q~    e# Read and evaluate input.
{     e# Fold this block over the list (i.e. "foreach except first")...
  \   e#   Swap with previous value.
  _p  e#   Duplicate and print previous value.
  1$  e#   Copy current value.
  /   e#   Integer division.
  )*  e#   Increment and multiply current value by the result.
}*

La valeur finale est laissée sur la pile et imprimée automatiquement à la fin.


3

Mathematica, 36 32 octets

 #2(Floor[#1/#2]+1)&~FoldList~#&

Tester

#2(Floor[#1/#2]+1)&~FoldList~#& /@ {{5, 4, 12, 1, 3}, 
   {15, 8, 12, 47, 22, 15, 4, 66, 72, 15, 3, 4}}
(* {{5, 8, 12, 13, 15}, {15, 16, 24, 47, 66, 75, 76, 132, 144, 
  150, 153, 156}} *)

3

Perl, 17 + 3 = 20 octets

$p=$_*=$==1+$p/$_

Requiert -pet -ldrapeaux:

$ perl -ple'$p=$_*=$==1+$p/$_' <<< $'15\n8\n12\n47\n22\n15\n4\n66\n72\n15\n3\n4'
15
16
24
47
66
75
76
132
144
150
153
156

Explication:

# '-p' reads each line into $_ and auto print
# '-l' chomp off newline on input and also inserts a new line when printing
# When assigning a number to `$=` it will automatic be truncated to an integer
# * Added newlines for each assignment 
$p=
  $_*=
    $==
      1+$p/$_

3

Python (3.5), 63 62 octets

def f(a):
 r=[0]
 for i in a:r+=i*(r[-1]//i+1),
 return r[1:]

Tester

>>> print('\n'.join([str(i)+' => '+str(f(i)) for i in [[9],[1,2],[2,1],[7,3],[1,1,1,1],[5,4,12,1,3],[3,3,3,8,16],[6,5,4,3,2,1],[9,4,6,6,5,78,12,88],[8,9,41,5,12,3,5,6],[15,8,12,47,22,15,4,66,72,15,3,4]]]))
[9] => [9]
[1, 2] => [1, 2]
[2, 1] => [2, 3]
[7, 3] => [7, 9]
[1, 1, 1, 1] => [1, 2, 3, 4]
[5, 4, 12, 1, 3] => [5, 8, 12, 13, 15]
[3, 3, 3, 8, 16] => [3, 6, 9, 16, 32]
[6, 5, 4, 3, 2, 1] => [6, 10, 12, 15, 16, 17]
[9, 4, 6, 6, 5, 78, 12, 88] => [9, 12, 18, 24, 25, 78, 84, 88]
[8, 9, 41, 5, 12, 3, 5, 6] => [8, 9, 41, 45, 48, 51, 55, 60]
[15, 8, 12, 47, 22, 15, 4, 66, 72, 15, 3, 4] => [15, 16, 24, 47, 66, 75, 76, 132, 144, 150, 153, 156]

Solution précédente

des solutions récursives mais plus grandes

(68 bytes) f=lambda a,i=0:[i,*f(a[1:],a[0]*(i//a[0]+1))][i==0:]if a!=[]else[i]
(64 bytes) f=lambda a,i=0:a>[]and[i,*f(a[1:],a[0]*(i//a[0]+1))][i<1:]or[i]

Aussi, au lieu de r+=[…], vous pouvez utiliserr+=…,
Cyoce 10/02/2016

@Cyoce je fais des changements mais quand je définis r=[0]dans le paramètre par défaut rdeviennent non locaux
Erwan

vous avez raison, j'ai oublié comment Python gérait les paramètres par défaut. L'autre astuce devrait marcher
Cyoce

@Cyoce oui ça marche merci pour les conseils
Erwan

3

Brachylog , 12 octets

{≤.;?%0∧}ᵐ<₁

Assez bizarre pour essayer de multiplier chaque variable par un nombre commencera par essayer de multiplier par 2 et non par 0 ou 1. Cela semble fonctionner bien et bat les deux autres implémentations de Brachylog

Explication

{       }ᵐ          --  Map each number
 ≤.                 --      to a number greater or equal to the original
  .;?%0             --      and a multiple of the original
       ∧            --      no more constraints
          <₁        --  so that the list is strictly increasing

Essayez-le en ligne!


2

Brachylog , 54 octets

:_{h_.|[L:T],LhH,(T_,IH;0:$Ie*H=:T>I),Lb:I:1&:[I]rc.}.

Explication

:_{...}.                § Call sub-predicate 1 with [Input, []] as input. Unify its output
                        § with the output of the main predicate


§ Sub-predicate 1

h_.                     § If the first element of the input is an empty list, unify the
                        § output with the empty list
|                       § Else
[L:T],LhH,              § Input = [L,T], first element of L is H
    (T_,IH              §     If T is the empty list, I = H
    ;                   §     Else
    0:$Ie*H=:T>I),      §     Enumerate integers between 0 and +inf, stop and unify the
                        §     enumerated integer with I only if I*H > T
Lb:I:1&                 § Call sub-predicate 1 with input [L minus its first element, I]
:[I]rc.                 § Unify the output of the sub-predicate with
                        § [I|Output of the recursive call]

2

Pyth, 11

t.u*Yh/NYQ0

Suite de tests

Est-ce qu'une réduction cumulative, une réduction qui renvoie toutes les valeurs intermédiaires, en commençant par 0. Comme il est garanti que l'entrée ne contient que des entiers positifs, c'est bon. À chaque étape, nous prenons l'ancienne valeur, nous la divisons par la nouvelle valeur et ajoutons 1, puis nous multiplions par la nouvelle valeur.


2

C, 79 octets

p;main(x,v)char**v;{for(;*++v;printf("%d ",p=((x+p-1)/x+!(p%x))*x))x=atoi(*v);}

Ungolfed

p; /* previous value */

main(x,v) char**v;
{
    /* While arguments, print out x such that x[i] > x[i-1] */
    for(;*++v; printf("%d ", p = ((x+p-1)/x + !(p%x)) * x))
        x = atoi(*v);
}

Ça ne p=p/x*x+xmarcherait pas ?
Neil

@ Neil Oui, ça marcherait. Certainement surpassé celui-ci :)
Cole Cameron

2

PowerShell, 26 octets

$args[0]|%{($l+=$_-$l%$_)}

Prend les entrées sous forme de tableau explicite, par exemple > .\sort-by-multiplying.ps1 @(6,5,4,3,2,1)via $args[0].

Ensuite, nous bouclons dessus avec |%{...}et chaque itération effectue de la magie . Nah, je plaisante, nous utilisons le même truc modulo que d'autres réponses (accessoires à @aross parce que je l'ai repéré ici en premier).

Les parenthèses encapsulantes (...)garantissent que le résultat de l'opération mathématique est placé sur le pipeline, et ainsi généré. Si nous les laissions désactivés, rien ne serait sorti puisque la $lvariable est nettoyée une fois l'exécution terminée.

Exemple

PS C:\Tools\Scripts\golfing> .\sort-by-multiplying.ps1 @(8,9,1,5,4)
8
9
10
15
16

1

Japt, 11 octets

Uå@Y*-~(X/Y

Testez-le en ligne!

Comment ça marche

          // Implicit: U = input array of integers
Uå@       // Cumulative reduce: map each previous value X and current value Y to:
-~(X/Y    //  floor(X/Y+1).
          // Implicit: output last expression

1

05AB1E , 11 octets

Code:

R`[=sŽDŠ/ò*

Essayez-le en ligne!

Explication:

R            # Reverse input
 `           # Flatten the list
  [          # While loop
   =         # Print the last item
    s        # Swap the last two items
     Ž       # If the stack is empty, break
      D      # Duplicate top of the stack
       Š     # Pop a,b,c and push c,a,b
        /    # Divide a / b
         ò   # Inclusive round up
          *  # Multiply the last two items

Utilise le codage CP-1252.


1

Minkolang 0,15 , 17 octets

nd1+?.z0c:1+*d$zN

Essayez-le ici!

Explication

nd                   Take number from input and duplicate it
  1+                 Add 1
    ?.               Stop if top of stack is 0 (i.e., when n => -1 because input is empty).
      z              Push value from register
       0c            Copy first item on stack
         :           Pop b,a and push a//b
          1+         Add 1
            *        Multiply
             d$z     Duplicate and store in register
                N    Output as number

Essentiellement, le registre conserve le dernier membre de la liste ascendante. Cette dernière est divisée par l'entrée et incrémentée pour obtenir le multiplicateur du prochain membre. La fonction toroïdal des moyens de champ de code de Minkolang que les boucles horizontalement sans avoir besoin de ()ou des []boucles.


1

Brachylog , 21 octets

l~lCℕ₁ᵐ≤ᵛ~+?&;Cz≜×ᵐ<₁

Essayez-le en ligne!

Utilise la somme des valeurs d'entrée comme limite supérieure pour les coefficients C. Assez lentement, la temporisation sur TIO pour les longueurs de liste en entrée supérieures à 5 ou 6 (également en fonction de la somme des valeurs). Mais pas aussi lentement que ma version d'origine, qui nécessite de minuscules listes de 3 éléments maximum, avec des valeurs infimes, pour ne pas expirer:

21 octets

l~l.&+^₂⟦₁⊇.;?z/ᵐℕ₁ᵐ∧

Essayez-le en ligne!



1

Python 2 , 53 octets

lambda a:reduce(lambda b,v:b+[b[-1]/v*v+v],a,[0])[1:]

Essayez-le en ligne!

k*x>yimplique k>y/x; donc le plus petit kpeut être est k=floor(y/x)+1. Depuis Python 2.7, la division entière est déjà prise comme floor, nous voulons k=y/x+1, et k*x = (y/x+1)*x = y/x*x+x.


0

Oracle SQL 11.2, 210 octets

WITH v AS(SELECT TO_NUMBER(COLUMN_VALUE)a,rownum i FROM XMLTABLE(('"'||REPLACE(:1,' ','","')||'"'))),c(p,n)AS(SELECT a,2 FROM v WHERE i=1UNION ALL SELECT a*CEIL((p+.1)/a),n+1 FROM c,v WHERE i=n)SELECT p FROM c;

Non-golfé

WITH v AS                                           
(
  SELECT TO_NUMBER(COLUMN_VALUE)a, rownum i            -- Convert the input string into rows 
  FROM   XMLTABLE(('"'||REPLACE(:1,' ','","')||'"'))   -- using space as the separator between elements
)
, c(p,n) AS                        
(
  SELECT a, 2 FROM v WHERE i=1                         -- Initialize the recursive view
  UNION ALL 
  SELECT a*CEIL((p+.1)/a),n+1 FROM c,v WHERE i=n       -- Compute the value for the nth element
)
SELECT p FROM c;

0

Chez Scheme (140 Bytes)

Version Golfée:

(define(f l)(define(g l p m)(cond((null? l)l)((<(*(car l)m)(+ p 1))(g l p(+ m 1)))(else(cons(*(car l)m)(g(cdr l)(* m(car l))1)))))(g l 0 1))

Version non-golfée:

(define(f l)
  (define(g l p m)
    (cond
      ((null? l) l)
      ((< (* (car l) m) (+ p 1)) (g l p (+ m 1)))
      (else (cons (* (car l) m) (g (cdr l) (* m (car l)) 1)))
    )
  )
  (g l 0 1)
)

Essayez-le en ligne!


* m(car l)peut être *(car l)m.
Jonathan Frech

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.