Classificar por Multiplicar


34

Você deve escrever um programa ou função que, dada uma lista de números inteiros positivos, multiplique cada elemento pelo menor número inteiro positivo possível, para criar uma lista estritamente crescente.

Por exemplo, se a entrada for

5 4 12 1 3

as multiplicações serão

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

e a saída será a lista crescente

5 8 12 13 15

Entrada

  • Uma lista de números inteiros positivos contendo pelo menos 1 elemento

Saída

  • Uma lista de números inteiros positivos

Exemplos

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

Este é um código de golfe, para que o programa ou função mais curto ganhe.

Curiosidade: o último elemento da saída para a entrada N, N-1, ... ,1parece ser o (N+1)thelemento da sequência A007952 . Se você encontrar uma prova, será bem-vindo incluí-la na sua resposta de golfe ou publicá-la como um comentário.


alguém já se baseou nessa prova?
Connor Clark

Respostas:


20

Gelatina , 6 5 bytes

:‘×µ\

A primeira resposta da Jelly antes de @Dennis acordar e me vencer. Experimente online!

Explicação

:          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

Obrigado a @Dennis por -1 byte.


4
:‘×µ\salva um byte.
Dennis

20
@ Dennis Oh merda ele acordou
Dennis van Gils

9

JavaScript (ES6), 28

Editar Conforme sugerido por @Patrick Roberts, ppode ser um parâmetro não inicializado. Contagem de mesmos bytes, mas evite usar uma variável global

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

TESTE

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>


Eu acho que você pode salvar alguns bytes usando o módulo, assim como eu fiz na minha resposta .
aross

Você não pode pular op = 0? Você precisa disso para executá-lo múltiplo em várias listas, mas a questão é apenas para uma única lista
Charlie Wynn

1
@CharlieWynn, se você não inicializar uma variável, obtém o erro de variável indefinida. Se, por acaso, a variável já existir (isso pode acontecer facilmente no ambiente de uma página da web), ela pode ter qualquer valor errado.
Edc65

@ edc65 com certeza, p já está definido nesta página!
Charlie Wynn

1
@PatrickRoberts pensando novamente, eu ainda podia evitar globals: f=a=>a.map(n=>a+=n-a%n,a=0). Mas não é o meu algoritmo (bobo mim) então eu vou manter o meu como é e upvote aross
edc65

6

Python 2, 67 64 bytes

Primeiro tente o código de golfe, para que as dicas sejam apreciadas.

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

Olá, acho que você está contando que a linha retorna como 2 bytes cada (usando o Windows?), Mas neste site você conta cada retorno de linha como um único byte. Portanto, sua pontuação é de 65 bytes. (Você pode copiar e colar seu código em mothereff.in/byte-counter, se não tiver certeza.) Além disso, você pode fazer isso em print lvez de return lsalvar outro byte. Bom trabalho!
mathmandan

Obrigado, eu não sabia sobre os retornos da linha. Isso explica por que sempre tenho contagens de bytes diferentes. E nem sequer considerei que a impressão é suficiente e não precisa retornar a lista.
Taronyu

Sem problemas! Aliás, como você mencionou que "as dicas são apreciadas", pode estar interessado em navegar em codegolf.stackexchange.com/questions/54/… . Apreciar!
mathmandan

5

PHP, 55 46 42 41 bytes

Usa codificação ISO 8859-1.

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

Execute assim ( -dadicionado apenas para estética):

php -d error_reporting=30709 -r 'for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;' 10 10 8
  • Guardou 1 byte thx em Ismael Miguel.
  • Economizou 8 bytes usando o módulo em vez do piso
  • Salva 4 bytes thx em Ismael Miguel (em vez de foreach)
  • Salva um byte usando para gerar um espaço.

Eu acho que você pode substituir $a+0por +$a. Além disso, você pode assumir que a entrada nunca terá um 0, portanto, você pode substituí-lo $a+0&&printpor simplesmente +$a&print. Na verdade, você pode até fazer $a&print, já que em PHP "0" == 0 == 0.0 == false. Mas pode não ser necessário se você apenas usar um echo, eu acho.
Ismael Miguel

O binário andnão funcionará (em oposição ao lógico), nem o eco funcionará dessa maneira. Desde que estou recebendo informações da CLI, o primeiro argumento é o -que eu quero pegar em vez de imprimir um zero. Tente php -r 'print_r($argv);' foo. No entanto, você salvou 1 byte com sua primeira sugestão, thx.
aross 09/02

1
Que tal for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,' ';? Tem 42 bytes e ignora o primeiro elemento.
Ismael Miguel

Bom dia, thx @IsmaelMiguel
aross

De nada. Se você quiser ser realmente excêntrico, poderá substituir o espaço por a^A, mas isso daria muitos avisos (os avisos são ignoráveis). Não mudará o número de bytes de forma alguma, mas certamente parece diferente.
Ismael Miguel

4

Haskell (30 28. 25 bytes)

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

Versão expandida

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)

Explicação

scanl1permite dobrar uma lista e acumular todos os valores intermediários em outra lista. É uma especialização de scanl, que tem o seguinte tipo:

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

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

Portanto, tudo o que precisamos é de uma função adequada que inclua dois o último elemento da nossa lista ( accna versão expandida) e o que desejamos processar ( nextna versão expandida) e retorne um número adequado.

Podemos derivar facilmente esse número dividindo o acumulador pelo próximo e exibindo o resultado. divcuida disso. Depois, basta adicionar 1para garantir que a lista esteja realmente aumentando (e que não terminemos 0).


Não é necessário dar um nome à sua função. Você também pode substituir ( ... )por $ ...e acho que contou uma nova linha final que pode ser omitida: scanl1$\x y->y*div x y+y24 bytes.
nimi

@nimi: Sério? Expressões contam? Dito isto, eu não salvo bytes com (...)vs $, pois ele $\ é analisado como operador e eu precisaria de um único espaço depois $.
Zeta

função sem nome são permitidas por padrão e scanl1(...)é uma função sem nome. Quanto a $vs ().: você está certo, meu erro.
nimi

4

C ++, 63. 60 57 bytes

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

Funciona no local dado um intervalo [first, last). Originalmente escrito como variante de modelo, mas era mais longo:

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

Versão extendida

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 bytes

q~{\_p1$/)*}*

Entrada como uma lista no estilo CJam. A saída é separada por avanço de linha.

Teste aqui.

Explicação

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

O valor final é deixado na pilha e impresso automaticamente no final.


3

Mathematica, 36. 32 bytes

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

Teste

#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 bytes

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

Requer -pe -lsinalizadores:

$ 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

Explicação:

# '-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 bytes

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

Teste

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

Solução anterior

algumas soluções recursivas, mas maiores

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

Também em vez de r+=[…], você pode usarr+=…,
Cyoce

@Cyoce i fazer mudanças, mas quando eu definido r=[0]no parâmetro padrão rtornar-se não-local
Erwan

você está certo, eu esqueci como o Python lidava com os parâmetros padrão. A outra dica deve funcionar embora
Cyoce 11/02/16

@Cyoce sim ele funciona graças a dicas
Erwan

3

Braquilog , 12 bytes

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

Por estranho que pareça, tentar multiplicar cada variável por um número começará tentando multiplicar por 2 e não por 0 ou 1. Isso parece funcionar e supera as outras implementações do Brachylog

Explicação

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

Experimente online!


2

Braquilog , 54 bytes

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

Explicação

:_{...}.                § 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

Suíte de teste

Reduz cumulativa, uma redução que retorna todos os valores intermediários, começando com 0. Como a entrada é garantida para conter apenas números inteiros positivos, isso é aceitável. Em cada etapa, pegamos o valor antigo, dividimos pelo novo valor e adicionamos 1, depois multiplicamos pelo novo valor.


2

C, 79 bytes

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

Não p=p/x*x+xfuncionaria?
911 Neil

@ Neil Sim, isso funcionaria. Definitivamente overthought este :)
Cole Cameron

2

PowerShell, 26 bytes

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

Recebe a entrada como uma matriz explícita, por exemplo, > .\sort-by-multiplying.ps1 @(6,5,4,3,2,1)via $args[0].

Em seguida, fazemos um loop forçado com isso |%{...}e cada iteração executa mágica . Brincadeira, usamos o mesmo truque de módulo que outras respostas (adereços para @aross porque eu o vi primeiro).

Os parênteses de encapsulamento (...)garantem que o resultado da operação matemática seja colocado no pipeline e, portanto, produzido. Se os deixássemos de fora, nada seria produzido, pois a $lvariável é coletada como lixo após a conclusão da execução.

Exemplo

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

1

Japonês, 11 bytes

Uå@Y*-~(X/Y

Teste online!

Como funciona

          // 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 bytes

Código:

R`[=sŽDŠ/ò*

Experimente online!

Explicação:

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

Usa a codificação CP-1252.


1

Referência 0.15 , 17 bytes

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

Experimente aqui!

Explicação

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

Essencialmente, o registro mantém o membro mais recente da lista ascendente e isso é dividido pela entrada e incrementado para obter o multiplicador para o próximo membro. O recurso toroidal do campo de código de Minkolang significa que ele faz um loop horizontalmente, sem a necessidade ()ou []loops.


1

Braquilog , 21 bytes

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

Experimente online!

Usa a soma dos valores de entrada como o limite superior para os coeficientes C. Muito lento, o tempo limite do TIO é excedido em comprimentos de lista de entrada além de 5 ou 6 (também dependendo da soma dos valores). Mas não tão lento quanto a minha versão original, que requer pequenas listas de até 3 elementos, com pequenos valores, para não atingir o tempo limite:

21 bytes

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

Experimente online!



1

Python 2 , 53 bytes

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

Experimente online!

k*x>yimplica k>y/x; então o menor kpode ser é k=floor(y/x)+1. Como no Python 2.7, a divisão inteira já é tomada como floor, queremos k=y/x+1e k*x = (y/x+1)*x = y/x*x+x.


0

Oracle SQL 11.2, 210 bytes

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;

Sem golfe

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

Esquema Chez (140 bytes)

Versão Golfed:

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

Versão Ungolfed:

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

Experimente Online!


* m(car l)pode ser *(car l)m.
Jonathan Frech

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.