Maksimum Zincirleme Ürün


11

Bize her biri 1 ile 9 arasında bir değer içeren, p1, ..., pk (mutlaka farklı değil) tamsayılarının bir listesi verilir. P1, ..., pk'nin her birini tam olarak bir kez kullanarak, yeni bir sayı listesi elde etmek için rakamların birleşmelerini oluşturabiliriz; daha sonra bu yeni listenin ürününü çıkarırız. Amaç en iyi rakam dizilerini seçerek bu ürünü en üst düzeye çıkarmaktır.

Örneğin, bize liste verilir: 2 3 2 (boşluklarla ayrılmış). Aşağıdaki birleşimleri oluşturabiliriz:

  • 2 3 2(bu birleşmelerin ürünüdür 12)
  • 23 2(ürün 46)
  • 32 2(ürün 64)
  • 22 3(ürün 66)

Birleştirme oluşturabileceğimiz en büyük ürün 66 olduğu için bunu üretiyoruz.

Kurallar:

  • En az bir çarpma olmalıdır (yani, yalnızca tüm basamakları birleştirip çıktısını veremezsiniz).
  • Çarpma dışında başka işleçler kullanamaz veya parantez ekleyemezsiniz.
  • Verilen tamsayıların listesinin boşluklarla ayrıldığını ve tüm tamsayıların 1 ile 9 arasında değerlere sahip olduğunu varsayın.

En kısa kod (bayt cinsinden) kazanır!

Test senaryoları:

Giriş 1 2 3:; Çıktı: 63(yani, 21*3)

Giriş 2 5 9:; Çıktı: 468( 52*9)

Giriş 1 2 3 4:; Çıktı: 1312( 41*32)


Bütün bir program veya giriş parametrelerini alan ve sonucu döndüren bir fonksiyon yazmalı mıyız?
randomra

@randomra Evet, sorun değil.
Ryan

A, b sayılarının her çifti için a * b. ürünü, ab (= a * 10 ^ (b basamakları) + b) basit birleşiminden daha azdır. Yani sadece 1 ürün (zorunlu olduğu için). Bunu ekleyin: codegolf.stackexchange.com/q/49854/21348
edc65

Yanıtlar:


8

CJam, 32 28 23 12 bayt

0le!f{~*}:e>

CJam yorumlayıcısında çevrimiçi deneyin .

@ User23013'e 16 bayt kurtarmama yardımcı olduğu için teşekkürler!

Fikir

Giriş dizesindeki karakterlere izin vermek, karakterleri boşluklarla ayrılmış tamsayılara (ardışık basamak grupları) böler. Bir sıfıra basarak ve sonra izin verilen giriş dizesini değerlendirerek, iki veya daha fazla tamsayı iteriz. En üstteki ikisini çarpmak ya girişin ürününün tam olarak iki tamsayıya bölünmesine ya da bir miktarın en düşük değerine neden olur.

kod

 le!         e# Push all possible character permutations of the input.
0   f{  }    e# For each permutation:
             e#   Push 0, then the permuted string.
      ~      e#   Evaluate the string. Pushes one or more integers.
       *     e#   Multiply the two topmost integers.
         :e> e# Retrieve the greatest integer in the array.

1
l2%_,,1>\e!m*{~S+m<~*}%$W=.
jimmy23013

2
l2%S+e!{0\~*}%$W=.
jimmy23013

2

CJam, 36 35 bayt

q~]_,([SL]m*{s},\e!\m*{z[s~]:*}%$W=

Oldukça düz ileri. Tüm olası kombinasyonları tekrarlar ve ürüne göre sıralar. Sonra en büyük çıktıyı verir. Bütün bunlar, en az 1 çarpım olması gerektiğini akılda tutarak.

Yakında açıklama ekleyeceğiz.

Buradan çevrimiçi deneyin


1

JavaScript (ES6) 125

Edit @oberon doğru anladı: "her yeni basamak en küçük sayı ile birleştirilmelidir"

Bu cevabı fikrini çalarak değiştirmeyeceğim. ES6'daki uygulama 70 bayt olur (işaret, sayı değil, sayı olarak karşılaştırmak için değiştirildi)

f=l=>l.split(' ').sort().reverse().map(d=>-a>-b?a+=d:b+=d,a=b='')||a*b

Çözümüm

f=l=>(i=>{for(r=0;a=b='',k=--i;r<a*b?r=a*b:0)for(v of l)k&1?a+=v:b+=v,k/=2})(1<<~-(l=l.split(' ').sort().reverse()).length)|r

Yorumlarda söylediğim gibi, a, b sayılarının her bir çifti için a * b ürünü, basit birleştirme ab'den (= a * 10 ^ (b basamakları) + b) daha azdır. Bu nedenle, ürünlerden kaçınmak ve birleştirmeyi tercih etmek daha iyidir, ancak en az 1 ürün istendiği için 2 sayı oluşturmalı ve çoğalmalıyız.

Mümkün olan tüm sayı gruplarını deneyerek çarpmak için bir çift sayı oluşturuyorum. Her sayı, azalan sırada basamaklar alarak açık bir şekilde oluşturulur.

Örneğin, 4 rakamlı bir listeyle [1 2 3 4] - deneyin:

  • 4 * 321
  • 43 * 21
  • 42 * 31
  • 41 * 32
  • 432 * 1
  • 431 * 2
  • 421 * 3

Bu değerin maksimumu ihtiyacımız olan sonuçtur.

Gruplamalar, minimum 0001 değeri ve maksimum 0111 değeriyle (yani 1 << (4 -1) - 1) 4 bitlik bir bitmap üzerinde döngü oluşturarak numaralandırılabilir.

Çok golf değil

f=l=>{
  l = l.split(' '); // string to array
  l.sort().reverse(); // decreasing order 
  m = 1 << (l.length-1); starting value fro loop
  r = 0 
  // loop from m-1 down to 1
  for(i=m; --i; )
  {
    a = b = '';
    k = i;
    for(v of l) // divide the digits base on bits of i
    {
      k & 1 ? a+=v : b+=v;
      k /= 2;
    }
    if (r < a*b) r = a*b; // remember max value in r
  }
  return r
}

Firefox'ta aşağıdaki snippet'i kullanarak test edin.

f=l=>(i=>{for(r=0;a=b='',k=--i;r<a*b?r=a*b:0)for(v of l)k&1?a+=v:b+=v,k/=2})(1<<~-(l=l.split(' ').sort().reverse()).length)|r

t=l=>(i=>{for(x=r='';a=b='',k=--i;r<a*b?(r=a*b,x=' = '+a+'x'+b):0)for(v of l)k&1?a+=v:b+=v,k/=2})
(1<<~-(l=l.split(' ').sort().reverse()).length)|| x

function go()
{
  R.value = f(I.value) // TEST AS IS
   + t(I.value) // Some more info
}

test=['1 2 3 4','1 2 3','2 5 9','8 9 8']

test.forEach(t => O.innerHTML = O.innerHTML + (t + ' -> ' + f(t)) + '\n')
Type your list: <input id=I><button onclick='go()'>-></button><input readonly id=R><br>
<pre id=O></pre>


1

Python 3, 111 bayt

Muhtemelen çok daha golf edilebilir. Çalışma süresini seviyorum, (O ( n log n ), değil mi?).

l=sorted(map(int,input().split()),reverse=1);m=[0,0]
for x in l:i=m[0]>m[1];m[i]=m[i]*10+x
print(m[0]*m[1])

Açıklama ile başa çıkıldı.

# edc65 has already explained that the optimal solution can be found applying a single
# multiplication. thus, given that
#     (10x + d)y > (10y + d)x
# where x, y are the two numbers and d is the next digit to insert, it follows that
#     y > x
# and thus each new digit must be concatenated to the smallest number. obviously, digits
# should be added in descending order.
l = sorted(map(int, input().split()), reverse=1)
m = [0,0]
for x in l:
    i = m[0] > m[1]
    m[i] = m[i]*10 + x
print(m[0] * m[1])

0

Pyth, 25 bayt

eSsmm*ss<dkss>dkr1ld.pcz)

Ben girdinin her permütasyon üzerinde döngü. Daha sonra her optimal kombinasyon iki tamsayıdan oluştuğu için, onu mümkün olan her konuma bölerim ve birleştirilmiş bölmeleri çoğaltırım. Sonra sıralar ve son elemanı alırım.


0

R, 164

function(n){l=length(n);a=sort(n,T);i=1;while(a[i]==a[i+1]&&i<l-2)i=i+2;a[c(i,i+1)]=a[c(i+1,i)];eval(parse(t=paste0(c(a[1:l%%2==1],"*",a[1:l%%2==0]),collapse='')))}

Bir yöntem olarak bunun sağlam olup olmadığından emin değilim. Test ettiğim durumlarda her seferinde işe yarıyor gibi görünüyor. Optimize ediciler çözümüne karşı test etmeyi denedim ve buna karşı Tamam gibi görünüyor. Yanlış kanıtlanmak için daha hazırım :) Golf için yer var, ama önce yöntem hakkında bazı geribildirim almak umuyordum.

Genel süreç:

  • Listeyi azalan düzende sırala
  • Farklı olan ilk tek / çift çifti değiştirin
  • Listenin çift ve tek öğelerini birleştirin
  • İki sonucun çarpımını değerlendirin

Bazı yorumlarla genişletildi

function(n){
    l=length(n);
    a=sort(n,T);    # sort descending order
    # Determine which pair to swap
    i=1;
    while(a[i]==a[i+1]&&i<l-2)i=i+2;
    a[c(i,i+1)]=a[c(i+1,i)];  # swap pair   
    # concatenate the even and odd indices items around a * and evaluate    
    eval(parse(t=paste0(c(a[1:l%%2==1],"*",a[1:l%%2==0]),collapse=''))) 
}

Ve bazı test çalışmaları (g adlı bir fonksiyon olarak uygulanır)

> g(c(1,2,3))
[1] 63
> g(c(2,5,9))
[1] 468
> g(c(1,2,3,4))
[1] 1312
> g(c(1,2,3,5,5,5))
[1] 293132
> g(c(1,5,7,7,9,9))
[1] 946725
> g(c(1,7,8,9,9,9))
[1] 978117
> g(c(7,8,9,9,9))  #Test case provided edc65 to randomra
[1] 97713
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.