Çarpmaya Göre Sırala


34

Olumlu bir tamsayı listesi verilen bir program ya da işlev yazmalısınız, her elemanı katı bir şekilde artan bir liste oluşturmak için mümkün olan en küçük pozitif tamsayı ile çarpın.

Örneğin, giriş ise

5 4 12 1 3

çarpımlar olacak

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

ve çıktı artan liste olacak

5 8 12 13 15

Giriş

  • En az 1 eleman içeren pozitif tamsayıların listesi

Çıktı

  • Olumlu tamsayıların bir listesi

Örnekler

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

Bu kod golf yani en kısa program veya işlev kazanır.

Eğlenceli gerçek: Girdi için çıktının son elemanı A007952 dizisinin elemanı N, N-1, ... ,1gibi görünüyor . Bir kanıt bulursanız, golf yanıtınıza eklemeniz veya yorum olarak göndermenizden memnuniyet duyarız.(N+1)th


Bu kanıtı henüz kimse kanıtlamadı mı?
Connor Clark

Yanıtlar:


20

Jöle , 6 5 bayt

:‘×µ\

@Dennis önce ilk Jelly cevabı uyanır ve beni yener. Çevrimiçi deneyin!

açıklama

:          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

-1 bayt için @Dennis teşekkür ederiz.


4
:‘×µ\bir bayt kaydeder.
Dennis,

20
@Dennis Oh kahretsin uyandı
Dennis van Gils

9

JavaScript (ES6), 28

Düzenleme @Patrick Roberts tarafından önerildiği pgibi, başlatılmamış bir parametre olabilir. Aynı bayt sayısı, ancak genel bir değişken kullanmaktan kaçının

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

ÖLÇEK

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>


Sana içinde yaptığı gibi modulo kullanarak birkaç byte kaydedebilirsiniz düşünüyorum Cevabıma .
saat

P = 0 atlamaz mısın? Birden fazla listede birden fazla çalıştırmak için ihtiyacınız var ama soru sadece tek bir liste için
Charlie Wynn

1
Bir değişkeni başlatmazsanız @ CharlieWynn tanımsız değişken için hata alırsınız. Şans eseri değişken zaten mevcutsa (bir web sayfasının ortamında kolayca olabilirdi), yanlış bir değeri olabilirdi.
edc65

@ edc65 yeterince, p zaten bu sayfada tanımlanmış!
Charlie Wynn

1
Tekrar düşünme @PatrickRoberts, hala globals önlemek olabilir: f=a=>a.map(n=>a+=n-a%n,a=0). Ama bu benim algoritmam değil (aptal ben) bu yüzden benimki gibi kendimi koruyacağım ve çok fazla oy alacağım
edc65

6

Python 2, 67 64 bayt

İlk önce kod-golf oynamaya çalışın, bu nedenle ipuçlarını takdir edin.

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

Merhaba, satırın her birini 2 bayt (Windows kullanarak?) Sayarsınız, ancak bu sitede her satırın tek bayt olarak sayıldığını düşünüyorum. Yani puanın aslında 65 byte. ( Emin değilseniz , kodunuzu mothereff.in/byte-counter içine kopyalayıp yapıştırabilirsiniz .) Ayrıca, başka bir baytı kaydetmek print lyerine bunu yapabilirsiniz return l. İyi iş!
mathmandan

Teşekkürler, satır dönüşlerini bilmiyordum. Bu neden her zaman farklı bayt sayımları olduğumu açıklıyor. Üstelik, baskının yeterli olduğunu ve listeyi geri vermek zorunda olmadığını bile düşünmedim.
Taronyu

Sorun değil! BTW, "ipuçları takdir edilir" dediğinizden , codegolf.stackexchange.com/questions/54/… adresinde gezinmekle ilgilenebilirsiniz . Keyfini çıkarın!
mathmandan

5

PHP, 55 46 42 41 bayt

ISO 8859-1 kodlamasını kullanır.

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

Bu şekilde koş ( -dyalnızca estetik için eklendi):

php -d error_reporting=30709 -r 'for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,~ß;' 10 10 8
  • Ismael Miguel'e 1 byte thx tasarruf etti.
  • Yer yerine modulo kullanılarak 8 bayt kurtarıldı
  • Ismael Miguel'e 4 bayt tx kaydedilen (foreach yerine)
  • Boşluk bırakmak için kullanarak bir bayt kaydedildi .

Ben değiştirmek düşünüyorum $a+0ile +$a. Ayrıca, girişin hiçbir zaman alamayacağını da varsayabilirsiniz 0, bu nedenle, yerine $a+0&&printbasitçe ile yapabilirsiniz +$a&print. Aslında, $a&printPHP'den beri bile yapabilirdiniz "0" == 0 == 0.0 == false. Ama echobence sadece kullanmanız gerekmeyebilir .
Ismael Miguel,

İkili and(mantık yerine) çalışmayacak ve bu şekilde çalışmayı da yankılamayacaktır. CLI'dan girdi aldığımdan beri, ilk argüman -sıfıra yazdırmak yerine yakalamak istediğimdir. Dene php -r 'print_r($argv);' foo. Yine de ilk önerinizle 1 bayt kaydedildi, thx.
saat

1
Ne dersiniz for(;$a=$argv[++$i];)echo$l+=$a-$l%$a,' ';? 42 byte uzunluğundadır ve ilk elemanı atlar.
Ismael Miguel,

Güzel, thx @IsmaelMiguel
Şubat'taki

Rica ederim. Gerçekten garip olmak istiyorsan, boşluğun yerini alabilirsin a^A, ama bu çok fazla uyarı verir (uyarılar göz ardı edilir). Bayt sayısını hiçbir şekilde değiştirmez, ancak surelly farklı görünüyor.
Ismael Miguel,

4

Haskell (30 28 25 bayt)

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

Genişletilmiş sürüm

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)

açıklama

scanl1bir listeyi katlamanıza ve tüm ara değerleri başka bir listeye eklemenize olanak sağlar. scanlAşağıdaki türden bir uzmanlık alanıdır:

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

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

Bu nedenle, ihtiyacımız accolan tek şey, listemizdeki son öğeyi ( genişletilmiş sürümde) iki tane ( genişletilmiş sürümde) işlemek istediklerimizi ( nextgenişletilmiş sürümde) alan ve uygun bir sayı döndüren uygun bir işlevdir .

Akümülatörü bir sonrakine bölerek ve sonucu döşeyerek bu sayıyı kolayca türetebiliriz. divBununla ilgilenir. Daha sonra 1listenin gerçekten artmasını sağlamak için eklemeliyiz 0.


İşleve bir isim vermene gerek yok. Ayrıca yerini alabilir ( ... )ile $ ...ve senin atlanabilir nihai satırsonu saydım düşünüyorum: scanl1$\x y->y*div x y+y24 bayt.
nimi

@ nimi: Gerçekten mi? İfadeler sayılır? Olduğu söyleniyor, (...)vs ile herhangi bir bayt tasarruf etmiyorum $, çünkü $\ operatör olarak ayrıştırılıyor ve sonra tek bir alana ihtiyacım var $.
Zeta

adlandırılmamış işleve varsayılan olarak izin verilir ve scanl1(...)adlandırılmamış bir işlevdir. İlgili $VS. (): haklısın, benim hatam.
nimi

4

C ++ 63 60 57 bayt

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

Bir dizi verilen yerinde çalışır [first, last). Başlangıçta şablon değişkeni olarak yazılmış, ancak daha uzun oldu:

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

Genişletilmiş versiyon

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 bayt

q~{\_p1$/)*}*

CJam tarzı bir liste olarak giriş yapın. Çıktı satır beslenir.

Burada test et.

açıklama

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

Son değer yığında bırakılır ve sonunda otomatik olarak yazdırılır.


3

Mathematica, 36 32 bayt

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

Ölçek

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

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

Gerektirir -pve -lbayraklar:

$ 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

Açıklama:

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

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

Ölçek

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

Önceki çözüm

bazı özyinelemeli çözümler ama daha büyük

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

Ayrıca, yerine, r+=[…]kullanabilirsinizr+=…,
Cyoce

@Cyoce değişiklikler yapıyorum ama r=[0]varsayılan parametrede tanımlandığımda ryerel değil
Erwan

haklısın, Python'un varsayılan parameleri nasıl ele aldığını unuttum. Diğer ipucu olsa çalışmalı
Cyoce

@Cyoce evet püf noktaları için teşekkürler
Erwan

3

Brachylog , 12 bayt

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

Her değişkeni bir sayı ile çarpmaya çalışmak yeterince garip, 2 ile 0 veya 1 ile çarpmaya çalışmakla başlayacaktır.

açıklama

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

Çevrimiçi deneyin!


2

Brachylog , 54 bayt

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

açıklama

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

Test odası

Bir kümülatif azaltma yapar, ile başlayan tüm ara değerleri döndüren bir azaltma yapar 0. Girişin yalnızca pozitif tamsayıları içerdiği garanti edildiğinden, bu sorun değil. Her adımda eski değeri alır, yeni değere böler ve ekleriz 1, sonra yeni değerle çarparız.


2

C, 79 bayt

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

Çalışmaz p=p/x*x+xmıydın?
Neil

@Neil Evet, bu işe yarar. Kesinlikle bu biraz abarttı :)
Cole Cameron

2

PowerShell, 26 bayt

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

Açık bir dizi örn olarak girdi Alır > .\sort-by-multiplying.ps1 @(6,5,4,3,2,1)üzeri $args[0].

Daha sonra bununla |%{...}tekrar başlarız ve her yineleme sihir yapar . Hayır, sadece şaka yapıyoruz, diğer cevaplarla aynı modulo numarasını kullanıyoruz (@aross için sahne alıyoruz çünkü önce orada gördüm ).

Kapsülleyici parenler (...), matematik işleminin sonucunun boru hattına yerleştirilmesini ve böylece çıktının alınmasını sağlar. $lBunları bıraksak , değişken bittikten sonra çöp toplandığından hiçbir şey çıkmaz.

Örnek

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

1

Japt, 11 bayt

Uå@Y*-~(X/Y

Çevrimiçi test edin!

Nasıl çalışır

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

Kod:

R`[=sŽDŠ/ò*

Çevrimiçi deneyin!

Açıklama:

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

CP-1252 kodlamasını kullanır.


1

Minkolang 0.15 , 17 bayt

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

Burada dene!

açıklama

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

Temel olarak, kayıt listesi yükselen listenin en son üyesini tutar ve bu girdi ile bölünür ve bir sonraki üyenin çarpanını almak için artırılır. Minkolang'ın kod alanının toroidal özelliği, ihtiyaç duymadan ()veya []döngüye gerek kalmadan yatay olarak döndüğü anlamına gelir .


1

Brachylog , 21 bayt

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

Çevrimiçi deneyin!

Giriş değerlerinin toplamını olarak kullanır. C katsayıları için üst sınır . Oldukça yavaştır, giriş listesi uzunlukları 5 veya 6'nın üzerindeki TIO'da zaman aşımına uğramıştır (değerlerin toplamına bağlı olarak). Ancak, zaman aşımına uğramamak için 3 değere kadar minik listeler gerektiren minik değerler içeren orijinal sürümüm kadar yavaş değil:

21 bayt

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

Çevrimiçi deneyin!



1

Python 2 , 53 bayt

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

Çevrimiçi deneyin!

k*x>yima eder k>y/x; yani en küçük kolabilir k=floor(y/x)+1. Python 2.7’de olduğundan, tamsayı bölme zaten flooristediğimiz k=y/x+1gibi ve olarak alınmıştır k*x = (y/x+1)*x = y/x*x+x.


0

Oracle SQL 11.2, 210 bayt

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;

Un-golfed

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 Şeması (140 Bayt)

Golf Sürümü:

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

Ungolfed Sürümü:

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

Çevrimiçi Deneyin!


* m(car l)olabilir *(car l)m.
Jonathan Frech

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.