Задний план:
Стандартные математические операции, такие как базовое сложение и умножение в реальном мире, работают так:
12 + 123 = 135
а также
12 * 123 = 1476
Это не интересно и скучно! Многие школы уже интерпретируют это как практику, практику, практику формальных алгоритмов. Это подразумевает довольно жесткую и скучную математическую диету и не является тем, что предназначено для этой задачи. Приготовьтесь поиграть на нашем любимом сайте.
Рассмотрим процесс сложения двух положительных целых чисел, а затем повторного добавления всех цифр его результата. Повторять с добавлением, пока не будет получена только одна цифра. Например:
- Результат
12 + 123
135. - Сложив все цифры 135 мы получим
1 + 3 + 5 = 9
.
Количество шагов, необходимых для получения однозначного значения 9 в этом повторном сложении, равно 2.
Как и в предыдущем процессе сложения, умножение двух положительных целых чисел следует тому же процессу. Умножьте все цифры результата и повторяйте этот процесс, пока не останется только одна цифра. Возьмите приведенный выше пример:
- Результат
12 * 123
1476. - Умножьте все цифры 1476, которые мы получим
1 * 4 * 7 * 6 = 168
. - Умножьте снова все цифры 168, которые мы получим
1 * 6 * 8 = 48
. - Умножьте снова все цифры 48, которые мы получим
4 * 8 = 32
. - Умножим еще раз все цифры 32, которые мы получим
3 * 2 = 6
.
Количество шагов, необходимых для получения однозначного значения 6 при этом повторном умножении, составляет 5.
Для этой задачи и во избежание любого неправильного использования математических обозначений я ввожу эти два фиктивных обозначения: (+)
и (*)
, но вы можете использовать любые обозначения , которые вам нравятся , которые работают следующим образом:
- Операция повторного сложения процесса для получения единственного значения
12 (+) 123 = 9
. - Операция повторного процесса умножения для получения одного значения
12 (*) 123 = 6
.
Вызов:
Задача состоит в том, чтобы написать либо программу, либо функцию, которая может выполнять обе операции, как описано в разделе фона: (+)
и (*)
.
Входные данные:
Входы программы или функции являются два положительных целых чисел и одну операцию либо (+)
и (*)
. Формат ввода - произвольный выбор программиста . Вы можете форматировать ввод, например, a (+) b
или , F(a, (+), b)
или любой формат , который вы хотите.
Выход:
Выходные данные программы или функции должны содержать результат операции и количество шагов, требуемых для формата вольного стиля, как вы хотите.
Тестовые случаи (игнорируйте формат ввода и вывода):
81 (+) 31 --> (4 ; 2)
351 (+) 14568 --> (6 ; 3)
21 (*) 111 --> (8 ; 3)
136 (*) 2356 --> (0 ; 2)
Основные правила:
- Это код-гольф , так что кратчайший ответ в байтах побеждает.
Не позволяйте esolangs отговаривать вас от публикации ответов на обычных языках. Получите удовольствие от этой задачи, предоставив максимально короткий ответ на своем языке программирования. Если вы разместите умный ответ и четкое объяснение, ваш ответ будет оценен (следовательно, положительные отзывы) независимо от используемого вами языка программирования. - К вашему ответу применяются стандартные правила , поэтому вы можете использовать STDIN / STDOUT, функции / метод с соответствующими параметрами, полные программы и т. Д. Выбор за вами.
- Если возможно, ваша программа может правильно обрабатывать большие числа. Если нет, то все будет хорошо.
источник
Ответы:
Dyalog APL ,
33323029 байтЭто расширяет APL для включения префиксной нотации
+/A n₁ n₂
и×/A n₁ n₂
. (На самом деле, вы можете использовать любую операцию слева от/A
.) Возвращает список {результат, количество повторений}.Попробуй APL онлайн! (
⍎
был эмулирован вe
целях безопасности.)Спасибо @ngn за сохранение байта.
0 байт (в шутку)
Dyalog APL на самом деле уже полностью поддерживает математику Анастасияна; вместо
(+)
и(×)
он использует+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
и×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
.Попробуйте
81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31
и21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111
.источник
⎕FR←1287
(т.е. использовать IEEE 754-2008 128-разрядное десятичное F loating точкой R epresentation) и⎕PP←34
(т.е. использовать 34 символов P Ринт P recision), вы можете использовать целые числа ниже 10³⁴.+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
и×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
еще довольно много байт? Я запутался в том, что это 0 байтов ..: S(+)
был бы Анастасияном. Dyalog APL поддерживает математику Анастасияна, но использует другой многозначный глиф, так же, как*
означает мощность и вам нужно×
для умножения, а/
означает репликацию и вам нужно÷
для деления.(+)
вас есть+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
входные данные, но поскольку OP действительно заявил, что подойдет любой формат ввода, вы можете использовать функцию в качестве параметра. Хм, интересно, возможно ли это и в других языках программирования, которые поддерживают функции ввода.Haskell, 108 байт
Определяет функцию ,
#
которая принимает первыйa
иb
затем операторo
. Интересный факт: это работает с любым оператором (фактически, с любой функцией), который вы хотите!источник
Integer
тип Хаскелла неограничен.Пайк, 16 байт
Попробуй это здесь!
Принимает умножить как
B
и добавить какs
. Два числовых ввода разделены запятыми.источник
JavaScript (ES6), 59
Рекурсивная функция, формат ввода адаптирован для упрощения рекурсивного вызова:
Тест
источник
Python 2, 60 байт
Ввод представляет собой строку , как
81+31
, выход кортеж из строки одноплодной и счетчик (например,('4', 2)
.Проверьте это на Ideone .
источник
f(['81', '31'],'+')
можно сохранить еще один байт, но кажется, что это слишком растянуло правила ...operator.add
operator.mul
Pyth, 16
Принимает ввод как
"+ 123 12"
для сложения, так и"* 123 12"
для умножения. Выходы вродеresult<linefeed>steps
.Попробуйте здесь или запустите Test Suite , но учтите, что это зависит от eval, поэтому в онлайн-интерпретаторе будет работать только вариант дополнения. Умножение работает правильно с автономным переводчиком.
Здесь используется функция кумулятивного сокращения, чтобы создать список промежуточных результатов, так что
"+ 351 14568"
мы получаем[14919, 24, 6]
. Это работает, потому что однозначные числа являются фиксированной точкой сложения и умножения Анастасии. Тогда мы просто получаем последний элемент массива, а также длину массива.Это будет работать для произвольно больших чисел, по крайней мере, до тех пор, пока у вас не закончится память.
источник
R
175167164140134127126119 байтUngolfed:
ifelse
вернулся! Да !Nop
Использование :
Большое спасибо @plannapus за игру в 24 байта!
-7 байт благодаря хорошей идее от @Vlo !
источник
strtoi
! Еще 4 байта, вы меня избили.05AB1E ,
2015 байтобъяснение
Оператор равен 1 для сложения, 0 для умножения.
Попробуйте онлайн
источник
Желе ,
1110 байтВвод представляет собой пару чисел и либо
+
или×
.Попробуйте онлайн! или проверьте все контрольные примеры .
Как это работает
источник
Машинный код ARM, 48 байт
Шестнадцатеричный дамп:
Эта функция не зависит от системных вызовов или библиотечных функций. Это код Thumb-2, представляющий собой кодирование команды переменной длины (2 или 4 байта) для 32-разрядного ARM. Таким образом, максимальное значение, которое он может обработать, составляет 2 ^ 32-1. 2 байта можно было бы отбросить, если бы они не соответствовали AAPCS ( 46 байтов ), поскольку в начале нам не пришлось бы составлять регистры.
Неуправляемая сборка (синтаксис GNU):
Скрипт тестирования в C:
источник
R
130124 символаНесколько иной подход от @ Frédéric 's:
С отступом, с новыми строками:
Строка 4, вероятно, нуждается в дополнительных пояснениях:
Тестовые случаи:
источник
f
являются как именем функции, так и одним из ее аргументов :)Октава, 85 байт
MATLAB, 123, 114, 105, 94 байтаРешил перевести это на Octace, чтобы воспользоваться преимуществами прямой индексации и наращивания возможностей. Принимает данные в форме:,
f(a,operator)
гдеa = [number1, number2]
, иoperator==1
дает продукт, иoperator==2
дает сумму.Пояснения:
g={@prod,@sum}{o}
: Выбирает подходящую функцию, продукт или сумму и назначает ееg
x=g(a)
берет сумму или произведение входовi=1; ... i++
: Инкремент для подсчета количества шаговУдалил две новые строки, пробел и поместил оба входных числа в вектор вместо отдельных аргументов. Это спасло 9 байтов, благодаря Pajonk! Удалено,
k=@(x)...
чтобы сохранить еще 11 байтов, благодаря beaker =) Наконец, все переведено в Octave, чтобы сохранить еще 9 байтов ...источник
Java,
164159146 байтПервый аргумент - просто счетчик, всегда 0
Вторым аргументом является метод, 0 для ADD и 1 для MULTIPLY.
Третий аргумент - это массив строк, который содержит значения для добавления / умножения.
Ungolfed
спасибо @Kevin Cruijssen за сокращение нескольких байтов.
спасибо @milk за бритье 5 байт.
Тестовая программа
источник
m==0
может бытьm<1
иInteger.parseInt
может бытьInteger.decode
.j
var в конце? Двойное встраивание(r+"")
выглядит так, как будто оно побрило бы несколько байтов.Желе , 17 байт
Попробуйте онлайн!
Принимая во внимание такие аргументы, как
x y 1
, это вычисляет сумму Анастасииx (+) y
.Учитывая аргументы, такие как
x y 0
, это вычисляет продукт Анастасииx (*) y
.Выход дан как
[number of steps, result]
.источник
Python,
160146129 байтСкоро выложу объяснение.
Ввод осуществляется в форме
12+12
или5*35
(с нормой+
и*
знаками) и предполагает, что это только два оператора.Он может обрабатывать числовые значения настолько большие, насколько позволяет память вашего компьютера.
Я почти наверняка уверен, что это может быть дальше.
РЕДАКТИРОВАТЬ:
1631 байт сохранены благодаря @Copper.источник
"+" if "+" in s else "*"
его"*+"["+"in s]
, а затем вместо того, чтобы назначить егоt
, просто добавить его вexec
вызове.R, 110 байт
Использование сплиттера @plannapus.
function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)}
Выход
редактировать: я не могу сосчитать
источник
Clojure 126 байтов
Функция называется так:
Вот код без ключа:
Имейте в виду, что Clojure все еще является новым для меня, так что это, вероятно, не лучшее решение. Задача все равно была веселой. Кроме того, код работал с очень большими числами без каких-либо затруднений.
источник
Perl 6 53 байта
Поскольку
( 12, &[+], 123 )
это приемлемо для ввода, я могу уменьшить его до 53 байт.(
&[+]
сокращение от&infix:<+>
которого является «почтением» к оператору сложения числового инфикса)Если бы второй аргумент должен был быть строкой,
(+)
это было бы 87 байтовОбъяснение:
Тест:
Нормальное использование:
источник
Python 2,
10797 байтАнонимная функция, которая принимает входные данные через аргумент первого операнда
a
, оператораo
('+'
или'*'
) и второго операндаb
и возвращает список формы[result, steps]
.Как это работает
Анонимная функция создает строку, объединяя операнды с оператором между ними, а затем оценивает ее; это первый шаг, описанный в вопросе. Затем это значение и оператор передаются рекурсивной функции
g
. Здесь используется счетчикi
, который увеличивается для каждого рекурсивного вызова. Если ввод меньше, чем10
, должна быть достигнута одна цифра, так что это иi
возвращается. Если нет, входные данные преобразуются в строку, и каждый символ в этой строке соединяется с оператором, давая желаемое вычисление, которое затем оценивается и передается функции рекурсивно.Попробуйте это на Ideone
источник
Groovy, 102 байта
Degolfed
объяснение
На основе превосходного решения @Sean Bean для Java.
p
: Замыкание (функция, лямбда, что угодно), которое реализует решениеt
: Текущая глубина вызова (количество итераций)p
всегда должна вызываться сt=1
m
: Операция, которую нужно выполнить,0
для «сложения»,1
для «умножения»d
: Список операндов, каждый операнд является объектом Stringe
: Элементыd
каждого преобразуются в целое числоr
: Сумма или произведениеe
, в зависимости от операцииm
r > 9
:r > 9
), повторно вызвать, увеличить глубинуt
и преобразоватьr
в список строк из цифр (и вернуть результат).r
иt
в виде списка.Тестовая программа
Полученные результаты
источник
Haskell,
7670 байтВозвращает двухэлементный список с результатом и количеством шагов. Работает для произвольных больших чисел. Пример использования:
(351#14568)(+)
->[6,3]
.Изменить: Благодаря @BlackCap за 6 байтов.
источник
(-48+).fromEnum
наread.pure
R, 91 байт
Используя код @ Vlo, который использует сплиттер @ plannapus, и некоторые идеи, которые я сгенерировал, играя в гольф в ответе @ Frédéric, это самый короткий R ответ. (Необычно большое количество ответов R здесь сегодня ...)
Важно, что это требует, чтобы вход для оператора был либо
sum
для (+), либоprod
для (*). По правилам испытания, это, кажется, все в порядке.С отступом:
Основные отличия от ответа @ Vlo:
Reduce
мы полагаемся на то, что входной аргумент является функцией, и просто вызываем его явно. (Yay для функций, являющихся первоклассными объектами!)T
, который оценивается какTRUE
(aka1
), но, поскольку это не зарезервированная переменная, мы можем изменить ее. Таким образом,T+T
есть2
. Таким образом, мы используем это как наш счетчик.cat
вывода мы просто возвращаем его как вектор сc
. Помимо сохранения двух байтов, тот факт, что выходные данные принудительно передаются в вектор, гарантирует егоT
принадлежность к классуnumeric
. Если мы используемcat
, иT
не был увеличен, то мы получаем ошибочный вывод, например1 TRUE
.источник
while
петлю следующим образом , изменения ,F
чтобы быть еще что - то конфликты имен избегать:function(A,O,B){x=O(A,B);while({F=F+1;x>9})x=O(x%/%10^(1:nchar(x)-1)%%10;c(x,F)}}
. Удивительно, сколько трюков с R-гольфом мы придумали за последние несколько лет :)T
иF
счетчика внутри функции фактически недопустимо, так как это означает, что функция может быть вызвана только один раз. Так что этот ответ (и некоторые другие мои!) Являются недействительными, еслиrm(T)
в конце нет явного . Я буду продолжать искать этот пост, чтобы быть уверенным, что я не просто придумал его.T
иF
трюк отлично действует до тех пор , пока вы не изменитеT
илиF
в глобальной среде. например,f=function(){T=T+1;T}
последовательно возвращается2
. Я думаю, что это мета-пост, на который вы ссылаетесь.Рубин, 55 байт
Рекурсивный вызов. Раньше он сильно отличался от ответа JavaScript @ edc65, но, по мере того как я его оптимизировал, он в конечном итоге стал прямым портом, разработанным практически независимо от их ответа, за исключением одной финальной оптимизации, включающей проверку результата eval'ed вместо длины списка операндов, передаваемых в , что позволило мне превзойти их количество байтов.
Ввод - это строка, представляющая оператор, и массив, содержащий операнды.
Попробуйте онлайн.
источник
i=0
и я как бы забыл при рефакторинге.Perl, 38 байт
Включает +2 для
-ap
Запустите с вводом по STDIN и пробелами вокруг оператора:
Вывод цифра и шаги разделены
+A
amath.pl
:Если вывод шагов в унарном порядке, то эта 35-байтовая версия работает лучше:
источник
Mathematica,
10594 байтаКод.
Использование.
Объяснение.
Эти две функции
x
(для (+)) иy
(для (*)) созданы в то же время, заменив параметрыf
иo
вс их соответствующими значениями. Для получения
x
,f
становится#1 + #2
иo
становитсяPlus
; ибоy
они соответственно становятся#1 #2
иTimes
. Переписываем функциюx
для последней части объяснения:источник
Java 7,
203195192 байтаИспользуется
long
(максимальное значение 2 63 с -1). Если бы он использовалint
вместо этого (максимальное значение 2 31 -1), он был бы только на 1 байт меньше ( 191 байт ):Скорее всего, можно играть в гольф немного больше. Необходимость печати шагов, а также ответа для обоих операторов занимает несколько байтов, хотя ..
Использует 0 (для
(+)
) и 1 (для(*)
).Ungolfed & тестовый код:
Попробуй это здесь.
Выход:
источник