ATM'den biraz para yatır


26

Görev basit. Bana biraz alın 1000, 500ve 100notlar.

Nasıl ? sorabilirsin. Endişelenmeyin, kredi kartınızı kabul eden bir ATM olduğu için bankayı soymaya gerek yok. Ancak kredi limitiniz görev için yeterli, bu nedenle para çekme işlemlerine dikkat etmeniz gerekiyor.

Meydan okuma

Sayısını göz önüne alındığında 1000, 500ve 100notlar gerekli, en azından o sayıda not almak için gereken spesifik çekme hesaplayın. Her para çekme işleminde ATM, notların her birini aşağıdaki kurallara göre tükürebilir:

  • Çekilmiş olan miktar ( A),5000
    • Eğer A%1000 == 0öyleyse, ATM 1 500not, 5 100not ve kalan 1000notları tükürürse
    • Aksi takdirde A%500 == 0, ATM 5 100not tükürür , geri kalan 1000notlar
    • Aksi takdirde A%1000 < 500, ATM floor(A/1000) 1000notları tükürür ve 100notları dinler.
    • Aksi takdirde A%1000 > 500, ATM floor(A/1000) 1000notlar tükürür , 1 500ve diğer 100notlar
  • Çekilen miktar eşittir büyüktür 5000
    • Eğer A%1000 == 0öyleyse, ATM 2 500nota atar ve kalan 1000notaları
    • Aksi takdirde, A%500 == 0ATM 1 500not yayınlar ve dinlenme 1000notları alır.
    • Aksi takdirde A%1000 < 500, ATM floor(A/1000) 1000notları tükürür ve 100notları dinler.
    • Aksi takdirde A%1000 > 500, ATM floor(A/1000) 1000notlar tükürür , 1 500ve diğer 100notlar

Açıklığa kavuşturmak için, işte tüm olası tutarlar için geri çekilen tam bir not çizelgesidir ( 7000daha fazla para çekebilirsiniz, ancak kalıp daha sonra değişmez). Sıra şudur <1000> <500> <100>:

 100 => 0 0 1                  2500 => 2 0 5                   4800 => 4 1 3
 200 => 0 0 2                  2600 => 2 1 1                   4900 => 4 1 4
 300 => 0 0 3                  2700 => 2 1 2                   5000 => 4 2 0
 400 => 0 0 4                  2800 => 2 1 3                   5100 => 5 0 1
 500 => 0 0 5                  2900 => 2 1 4                   5200 => 5 0 2
 600 => 0 1 1                  3000 => 2 1 5                   5300 => 5 0 3
 700 => 0 1 2                  3100 => 3 0 1                   5400 => 5 0 4
 800 => 0 1 3                  3200 => 3 0 2                   5500 => 5 1 0
 900 => 0 1 4                  3300 => 3 0 3                   5600 => 5 1 1
1000 => 0 1 5                  3400 => 3 0 4                   5700 => 5 1 2
1100 => 1 0 1                  3500 => 3 0 5                   5800 => 5 1 3
1200 => 1 0 2                  3600 => 3 1 1                   5900 => 5 1 4
1300 => 1 0 3                  3700 => 3 1 2                   6000 => 5 2 0
1400 => 1 0 4                  3800 => 3 1 3                   6100 => 6 0 1
1500 => 1 0 5                  3900 => 3 1 4                   6200 => 6 0 2
1600 => 1 1 1                  4000 => 3 1 5                   6300 => 6 0 3
1700 => 1 1 2                  4100 => 4 0 1                   6400 => 6 0 4
1800 => 1 1 3                  4200 => 4 0 2                   6500 => 6 1 0
1900 => 1 1 4                  4300 => 4 0 3                   6600 => 6 1 1
2000 => 1 1 5                  4400 => 4 0 4                   6700 => 6 1 2
2100 => 2 0 1                  4500 => 4 0 5                   6800 => 6 1 3
2200 => 2 0 2                  4600 => 4 1 1                   6900 => 6 1 4
2300 => 2 0 3                  4700 => 4 1 2                   7000 => 6 2 0
2400 => 2 0 4

Martin tarafından sağlanan liste

Yakalayış

Kredi kartınızdaki kredi limiti yeterli olduğu için , para çekme işleminde çekilen toplam tutarın , verilen giriş / şart notları için mümkün olan minimum miktar olduğundan emin olmanız gerekir .

Giriş

Giriş değerinin gerekli notları sayısına tekabül eden üç sayılar için uygun bir biçimde olabilir 1000, 500ve 100. Bu sırayla mutlaka değil.

Çıktı

Çıktı, yeni bir satıra ayrılmış her işlemde çekilecek miktardır.

Örnekler

Giriş (format <1000> <500> <100>):

3 4 1

Çıktı:

600
600
600
3600

birkaç:

7 2 5
5000
3500

1 2 3
600
1700

21 14 2
600
600
600
1600
5000
5000
5000
5000
5000

Varsayımlar

  • ATM'nin her bir miktar için sonsuz sayıda nota sahip olduğunu varsayabilirsiniz.
  • Ayrıca, istediğiniz sayıda işlem yapabileceğinizi de varsayabilirsiniz.
  • Ayrıca, bazı girdi değerlerinin çözümü benzersiz olmayabilir, bu nedenle mümkün olan minimum miktarı ve minimum gerekli koşulları sağlayan çözümün herhangi birini 1 olarak verebilirsiniz.

Her zamanki gibi, STDIN / ARGV üzerinden tam bir okuma programı girişi yazıp STDOUT'a çıktı yazdırabilir veya argümanlar aracılığıyla girdi alan bir fonksiyon yazabilir ve miktarlara karşılık gelen bir tamsayı listesi veya yeni bir satırla ayrılmış miktarlara sahip bir dize döndürür.

Bu kod-golf yani bayt cinsinden en kısa kod kazanır.


@ nutki gerçekten. Düzenlenen.
Doktor

Herhangi bir hız kısıtlaması var mı? Son test durumu 21 14 2makul bir sürede bitmeli mi?
Jakube

1
@Jakube Makul bir sürede - evet (5-6 saatten daha az). Ancak bu şekilde, bu kod golf olduğu için sınır yok.
Doktor

Yani, eğer 0'ı geri çekersem, bana beş 100 not verecek mi?
AJMansfield

Tabii ki @ AJMansfield. 0 para çekemezsiniz
Doktor

Yanıtlar:


7

JavaScript, 184 148

function g(a,b,c){x=[];while(a>0||b>0||c>0){i=b<3||a<4?a:4;a-=i;if(i>3&&b>1){b-=2;i++}else{i+=(c--<b&&i>4?0:.1)+(b-->0?.5:0)}x.push(i*1e3)}return x}

http://jsfiddle.net/vuyv4r0p/2/

para çekme miktarlarına karşılık gelen tam sayıların listesini döndürür


Dene g(5,1,1). Bir iyi bir çözüm: 5600.
jimmy23013

şimdi düzeltilmesi gerekir
hoffmale

g(5,1,0)Çözelti,: 5500.
jimmy23013

bu da düzeltilmeli ^ ^ ^
belirtdiğin

g(5,2,0)Çözelti,: 6000.
jimmy23013

1

Perl 5: 223

Düzenle

Bu çözüm, 7K'nın ATM limiti olduğu varsayımıyla yanlış yapıldı. Bu aslında, görevi dinamik programlama gerektirdiğinden daha ilginç kılıyordu (hareket düzeni oldukça düzenliydi, ancak zor kodlama yapmak benim yaptığım gibi canlı hesaplamaktan daha uzun olurdu). Mümkün olan herhangi bir miktar olduğunda, hareket düzeni o kadar düzenli olur ki, onu zorlaştırması çok önemlidir. @Hoffmale'in çözümünün şimdi doğru olup olmadığını bilmiyorum, ama bu çizgiler arasında olacak. Maalesef, önce birisinin bir çözüm bulduğu, sonra da bir kazanmak için bir golf diline taşındığı başka bir görev olacak.

Orijinal çözümden biraz daha yavaş (ancak 100'ün altındaki parametreler için hala ikinci saniye).

#!perl -pa
$c{0,0}=$f=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/.(?=.$)/>($n=$c{$i-$`,$j-$'})||${$r=\$c{$i,$j}}<($x=$n+$&)&&$$r
or$f=$$r="$x $n".($'.$&+5*$`)."00
"for 204..206,105,106,11..15,110..114}}$_=$f."100
"x($c-$f+3);s/.*\b3//

Daha hızlı 259 çözüm.

#!perl -pa
$c{0,0}=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/\B./<($%=$c{$i-$&,$j-$'}+$`)&&(!${$r=\$c{$i,$j}}||$$r>$%)and$d{$i,$j}=$_,$$r=$%for
qw/024 025 026 015 016/,101..105,110..114}}
$d{$b,$a}=~/\B./,$c-=$`,$b-=$&,$a-=$',print$'.$`+5*$&,"00
"while$a+$b;$_="100
"x$c

STDIN kullanır:

$perl atm.pl <<<"21 14 2"
5000
5000
5000
5000
5000
600
600
600
1600

Dene 10 0 0. Daha iyi bir çözüm: 10100.
jimmy23013

@ user23013 ayy, bu soruyu yanlış anladım.
7k'nin
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.