Отработать изменение [закрыто]

10

Вы пишете программу для автоматического кассового аппарата. Пользователь должен измениться с наименьшим количеством монет. Напишите программу, которая берет сумму (скажем, 1,53 доллара США) и дает изменение в деноминациях США - в данном случае: 1 банкнота достоинством один доллар, 1 x пятьдесят центов и 3 x один цент. Самая короткая программа - победитель. Бонусные баллы за поддержку других валют (например, деноминации Великобритании) и необычных валют (1, 2, 3 цента?)

У вас есть эти номиналы в США: 1 цент, 5 центов, 10 центов, 25 центов, 50 центов, 1 доллар (банкнота или монета), 2 доллара, 5 долларов, 10 долларов.

У вас есть следующие деноминации в Великобритании: 1 пенсов, 2 пенсов, 5 пенсов, 10 пенсов, 20 пенсов, 50 пенсов, £ 1, £ 2, £ 5 (банкнота или монета), £ 10.

Томас О
источник
3
Это, вероятно, нуждается в небольшом уточнении. Во-первых, вы, вероятно, должны указать, что мы хотим наименьшее количество монет (что делает бонусный вопрос несколько более интересным, например, {1c, 49c, 50c} и 98c нарушают наивный алгоритм). Во-вторых, формат ввода / вывода полезен. Специфика обработки недостижимых значений (для вымышленных валют) поможет. Наконец, вы можете перечислить деноминации здесь, чтобы людям не приходилось искать их, если они не знакомы с ними.
Наб
Как работают бонусные баллы? Просто есть ли галстук для самой короткой программы?
Гнибблер
@gnibber, цитируя Стивена Фрая: «[баллы] беспристрастно определяются демографически отобранным консультантом по обслуживанию клиентов с разбивкой по возрасту и полу - то есть я».
Томас О
Я собираюсь попросить 50 центов, поскольку я еще не видел монету в 50 центов. Но, очевидно, они существуют: usmint.gov/kids/coinnews/circulation/50centCoin.cfm
Мартин Йорк,

Ответы:

2

Windows PowerShell, 108 111 117

Самая первая попытка, пока не разгаданная

$i=+("$input"-replace'[^\d.]')
$args|%{0d+$_}|sort -des|%{$a=[math]::floor($i/$_)
if($a){$i-=$a*$_
"$a×$_"}}

Замечания по реализации:

  1. Принимает количество для возврата через трубопровод
  2. Принимает список наименований валют через командную строку
  3. Количество может быть дано со знаком валюты; это будет раздето (фактически, все нечисловое).
  4. Список конфессий не нужно сортировать.
  5. Программа выведет наибольшее изменение, меньшее, чем запрошенное количество, достижимое с данными номиналами, то есть 1,5 для 1,53, если монета в 1 цент отсутствует.

Если 3 и 4 не нужно удовлетворять (т.е. я контролирую формат ввода ;-)), тогда достаточно следующей программы (71):

$i=+"$input"
$args|%{$a=[math]::floor($i/$_)
if($a){$i-=$a*$_
"$a×$_"}}
детеныш
источник
2

Mathematica: 110 символов

Sort[IntegerPartitions[Rationalize@#,Infinity,{10,5,2,1,1/2,1/4,1/10,5/100,1/100}],
    Length@#1<Length@#2&][[1]]&  

Применение

%[0.98]  
{1/100, 1/100, 1/100, 1/10, 1/10, 1/4, 1/2}  

Или

Tally@Sort[IntegerPartitions[Rationalize@#,Infinity,
                             {10,5,2,1,1/2,1/4,1/10,5/100,1/100}],
     Length@#1<Length@#2&][[1]]&  

(6 символов больше) дает

{{1/100, 3}, {1/10, 2}, {1/4, 1}, {1/2, 1}}

Для других конфессий просто измените таблицу рациональных чисел {10, ...., 5 / 100,1 / 100}

Доктор Велизарий
источник
2

D: 225 символов

import std.algorithm,std.conv,std.stdio;void main(string[]args){auto m=args[1].findSplit(".");void p(T,S)(T t,T u,S s){foreach(v;[u,10,5,1]){writefln("%s %s%s",t/v,v,s);t-=(t/v)*v;}}p(to!int(m[0]),20,"");p(to!int(m[2]),25,"/100");}

Более разборчиво:

import std.algorithm,std.conv,std.stdio;

void main(string[] a)
{
    auto m = a[1].findSplit(".");

    void p(T, S)(T t, T u, S s)
    {
        foreach(v; [u, 10, 5, 1])
        {
            writefln("%s %s%s", t / v, v, s);
            t -= (t / v) * v;
        }
    }

    p(to!int(m[0]), 20, "");
    p(to!int(m[2]), 25, "/100");
}

Только обрабатывает валюту США. Принимает значение как значение с плавающей запятой в командной строке (должен иметь начальный 0 для значений менее 1 доллара). Не принимает $ как часть значения. Выводит количество каждого типа купюры / монеты в отдельной строке. Например, ввод 1,53 приводит к:

0 20
0 10
0 5
1 1
2 25/100
0 10/100
0 5/100
3 1/100

Джонатан М Дэвис
источник
1

Mathematica, 51 байт

#~NumberDecompose~{10,5,2,1,.5,.25,.1,.05,.01}&

вход

[1,53]

вывод

{0, 0, 0, 1, 1, 0, 0, 0, 3.}


Mathematica, 82 байта - С БОНУСОМ -

(s=#~NumberDecompose~#2;Row@Flatten@Table[Table[#2[[i]]"+",s[[i]]],{i,Length@s}])&

вход

[37,6, {15, 7, 2,5, 1, 0,88, 0,2, 0,01}]

вывод

15 + 15 +7 + 0,2 + 0,2 + 0,2 +

J42161217
источник
Хм, этот вопрос использует разные наименования из дубликата.
ericw31415
OP не указывает формат ввода / вывода.
J42161217
Этот вопрос не использует 100 долларовых купюр, и нет бонуса.
ericw31415
ok.fixed и сохранил несколько байтов! Что касается бонуса, я прошу вас снова прочитать вопрос. Особенно часть .. "Бонусные баллы за поддержку других валют"
J42161217
Ой, наверное, я тогда этого не видел!
ericw31415
1

Javascript, 84 83 байта

(n,v=[10,5,2,1,.5,.25,.1,.05,.01],l=[])=>{for(i in v)l[i]=n/v[i]|0,n%=v[i];return l}

(n,v=[10,5,2,1,.5,.25,.1,.05,.01],l=[])=>eval("for(i in v)l[i]=n/v[i]|0,n%=v[i];l")

Использует жадный алгоритм.

ericw31415
источник
0

APL (Дьялог) , 19 байт

Запрашивает желаемое количество, а затем номиналы, выраженные в наименьших единицах (пенни / центы).

CY'dfns'
 stamps

Попробуйте онлайн!

⎕CY'dfns'С о р у рабочее пространствоdfns

⎕ stamps⎕ попросить входы и использовать в качестве аргументов в stampsфункцию

Адам
источник