Выберите из существующего набора весов, чтобы сделать целевую сумму

9

При выполнении тяжелой атлетики я хочу сделать определенный вес, прикрепив несколько пластин к штанге.

У меня есть следующие пластины:

  • 6 тарелок по 1 кг каждая
  • 6 тарелок по 2,5 кг каждая
  • 6 тарелок по 5 кг каждая
  • 6 тарелок по 10 кг каждая

Сам бар весит 10 кг.

Допускается прикреплять пластины только парами - они крепятся на каждом конце стержня, а расположение на двух концах должно быть полностью симметричным (например, прикрепление двух 5-килограммовых плит на одном конце и одной 10-килограммовой плиты в другой конец запрещен по соображениям безопасности).

Сделайте программу или функцию, которая скажет мне, сколько пластин каждого вида я должен использовать, чтобы получить данный общий вес. Ввод целого числа больше 11; на выходе получается список / массив / строка из 4 чисел. Если невозможно объединить существующие пластины, чтобы получить целевой вес, выведите массив нулевой / пустой, недопустимую строку, сгенерируйте исключение или что-то подобное.

Если есть несколько решений, код должен выводить только одно (не заставляйте пользователя выбирать - он слишком занят другими вещами).

Тестовые случаи:

12 -> [2 0 0 0] - 2 plates of 1 kg plus the bar of 10 kg
13 -> [0 0 0 0] - a special-case output that means "impossible"
20 -> [0 0 2 0] - 2 plates of 5 kg + bar
20 -> [0 4 0 0] - a different acceptable solution for the above
21 -> [6 2 0 0] - 6 plates of 1 kg + 2 plates of 2.5 kg + bar
28 -> [0 0 0 0] - impossible
45 -> [0 2 6 0] - a solution for a random number in range
112 -> [2 4 6 6] - a solution for a random number in range
121 -> [6 6 6 6] - maximal weight for which a solution is possible

Если ваш код выводит числа в обратном порядке (от тяжелой до легкой), укажите это явно, чтобы избежать путаницы.

anatolyg
источник
1
Разве это не обман вопроса минимального подсчета монет ? Я не думаю, что тот же самый жадный алгоритм терпит неудачу, за исключением ограничения 6 для одного вида пластины. Я думаю, что не может быть достаточной разницы, но я не уверен.
FryAmTheEggman
1
Жадный алгоритм не работает (не без модификации, по крайней мере) именно потому, что числа ограничены
anatolyg
Связано , но это ASCII
AdmBorkBork
Да, причина, которую я отправил, состояла в том, что я не был уверен, что модификация была достаточно значительной. Я отправил сообщение, чтобы попытаться получить обратную связь от сообщества, и я удалю свой комментарий, если мне кажется, что сообщество не согласно со мной.
FryAmTheEggman
Можем ли мы вывести все решения вместо одного?
Луис Мендо

Ответы:

5

Желе , 22 байта

4ṗạµ×2,5,10,20S€+⁵iƓịḤ

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это работает

4ṗạµ×2,5,10,20S€+⁵iƓịḤ  Main link. No arguments

4                       Set the left argument and initial return value to 4.
 ṗ                      Take the Cartesian power of [1, 2, 3, 4] and 4, i.e.,
                        generate all 4-tuples of integers between 1 and 4.
  ạ                     Take the absolute difference of all integers in the
                        4-tuples and the integer 4. This maps [1, 2, 3, 4] to
                        [3, 2, 1, 0] and places [0, 0, 0, 0] at index 0.
   µ                    Begin a new, monadic chain. Argument: A (list of 4-tuples)
     2,5,10,20          Yield [2, 5, 10, 20].
    ×                   Perform vectorized multiplication with each 4-tuple in A.
              S€        Sum each resulting 4-tuple.
                +⁵      Add 10 to each sum.
                   Ɠ    Read an integer from STDIN.
                  i     Find its first index in the array of sums (0 if not found).
                     Ḥ  Unhalve; yield the list A, with all integers doubled.
                    ị   Retrieve the 4-tuple at the proper index.
Деннис
источник
6

MATL , 29 28 байт

4t:qEZ^!"[l2.5AX]@Y*10+G=?@.

Для входов, которые не имеют решения, это создает пустой вывод (без ошибок).

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

объяснение

4           % Push 4
t:q         % Duplicate 4 and transform into range [0 1 2 3]
E           % Multiply by 2: transform into [0 2 4 6]
Z^          % Cartesian power. Each row is a "combination" of the four numbers
!           % Transpose
"           % For each column
  [l2.5AX]  %   Push [1 2.5 5 10]
  @         %   Push current column
  Y*        %   Matrix multiply. Gives sum of products
  10+       %   Add 10
  G=        %   Compare with input: are they equal?
  ?         %   If so
    @       %     Push current column, to be displayed
    .       %     Break loop
            %   Implicit end
            % Implicit end
            % Implicit display
Луис Мендо
источник
5

Mathematica, 70 байт

Select[FrobeniusSolve[{2,5,10,20},2#-20],AllTrue[EvenQ@#&&#<7&]][[1]]&

Анонимная функция. Принимает число в качестве входных данных и выводит список или ошибки и возвращает, {}[[1]]если решения не существует.

LegionMammal978
источник
4

Желе, 25 байт

×2,5,10,20S+⁵⁼³
4ṗ4’ÇÐfḢḤ

Попробуй это здесь.

Линн
источник
2,5,10,20->2,5,⁵,20
Дрянная Монахиня
правда ... не ,диада? Вся моя жизнь - ложь
Leaky Nun
@LeakyNun ,- это диада, но она также может использоваться для литералов. 2,5,⁵,20не является буквальным , хотя ( 2,5и 20есть, но ,, и ,являются атомы), так что вам нужно что - то , чтобы объединить ссылки.
Деннис
3

Python 3, 112 байт

lambda n:[i for i in[[i//4**j%4*2for j in range(4)]for i in range(256)]if i[0]+2.5*i[1]+5*i[2]+10*i[3]+10==n][0]

Анонимная функция, которая принимает через аргумент ввод целевой массы и возвращает номер каждой пластины в виде списка. Если решения не существует, выдается ошибка. Это чистая грубая сила.

Как это работает

lambda n                                   Anonymous function with input target mass n
...for i in range(256)                     Loop for all possible arrangement indices i
[i//4**j%4*2for j in range(4)]             Create a base-4 representation of the index i,
                                           and multiply each digit by 2 to map from
                                           (0,1,2,3) to (0,2,4,6)
[...]                                      Package all possible arrangements in a list
...for i in...                             Loop for all possible arrangements i
i...if i[0]+2.5*i[1]+5*i[2]+10*i[3]+10==n  Return i if it gives the target mass
[...]                                      Package all solutions in a list
:...[0]                                    Return the first list element. This removes any
                                           multiple solutions, and throws an error if there
                                           being no solutions results in an empty list

Попробуйте это на Ideone

TheBikingViking
источник
2

Брахилог , 50 байт

,L##l4,L:{.~e[0:3]}a:[2:5:10:20]*+:10+?,L:{:2*.}a.

Возвращает, falseкогда это невозможно.

Fatalize
источник
1

Pyth, 34 31 25 байт

h + fqQ +; s * VT [1 2,5 5;) yMM ^ U4 4] * 4] 0 
yMh + fqQ +; s * VT [2 5; y;) ^ U4 4] * 4] 0
yMhfqQ +; s * VT [2 5; y;) ^ U4 4

Тестирование.

Ошибки в невозможности.

По сути, это грубая сила.

Это довольно быстро, так как есть только 256 возможных соглашений.

Дрянная Монахиня
источник
1

Scala, 202 байта

Решил, что Scala здесь не очень нравится, поэтому я представляю (возможно, не оптимальное) решение в Scala.

def w(i:Int){var w=Map(20->0,10->0,5->0,2->0);var x=i-10;while(x>0){
var d=false;for(a<-w.keys)if(a<=x & w(a)<6 & !d){x=x-a;w=w.updated(a,w(a)+2);d=true;}
if(!d){println(0);return;}}
println(w.values);}

Программа выводит данные в обратном порядке и с дополнительным мусором по сравнению с решениями в пост. Если решение не найдено, выдается 0.

Примечание: я не смог удалить ни одной строки или пробела, потому что Scala тупой, поэтому я думаю, чтобы уменьшить размер, метод должен быть переделан, если я не пропустил что-то очевидное.

ejaszewski
источник
1

APL, 40 байт

{2×(4⍴4)⊤⍵⍳⍨10+2×,⊃∘.+/↓1 2.5 5 10∘.×⍳4}

В ⎕IO ← 0. На английском:

  1. 10+2×,∘.+⌿1 2.5 5 10∘.×⍳4: построить массив всех возможных весов, вычисляя 4D внешнюю сумму весов на весовой тип;
  2. ⍵⍳⍨: поиск по индексу заданного. Если не найдено, индекс равен 1 + подсчет массива на шаге 1;
  3. (4⍴4)⊤: представить индекс в базе 4, то есть вычислить координату заданного веса в 4D пространстве;
  4. : вывести результат в проблемное пространство, где координаты следует интерпретировать как половину числа пластин.

Пример: {2 × (4⍴4) ⊤⍵⍳⍨10 + 2 ×, ⊃∘. + / ↓ 1 2.5 5 10∘. × ⍳4} 112 2 4 6 6

Бонус : поскольку APL является языком массивов, можно протестировать несколько весов одновременно. В этом случае результат транспонируется:

      {2×(4⍴4)⊤⍵⍳⍨10+2×,⊃∘.+/↓1 2.5 5 10∘.×⍳4}12 13 20 21 28 45 112 121
2 0 0 6 0 0 2 6
0 0 0 2 0 2 4 6
0 0 2 0 0 2 6 6
0 0 0 0 0 2 6 6
lstefano
источник
1

JavaScript (ES6), 109 байт

n=>`000${[...Array(256)].findIndex((_,i)=>i+(i&48)*9+(i&12)*79+(i&3)*639+320==n*32).toString(4)*2}`.slice(-4)

Возвращает 00-2при ошибке. Альтернативное решение, которое возвращает undefinedошибку, также 109 байт:

n=>[...Array(256)].map((_,i)=>`000${i.toString(4)*2}`.slice(-4)).find(s=>+s[0]+s[1]*2.5+s[2]*5+s[3]*10+10==n)
Нил
источник