Есть настойчивость
вступление
Найдите результат числового каннибализма.
Почему 6 испугались 7? Becase 7 89.
Ваша программа должна будет найти результат 8многократного применения операции (определенной ниже) к числу.
Связанные , Песочница
Вызов
Ваш ввод будет единственным положительным целым числом n.
Вы должны найти каждый 8в целом, и заменить его на +или -на основании следующих условий.
- удалить все
8s в начале или в конце строки. - Если их несколько
8, сверните их в один8. - \$a\$и \$b\$- это куски слева и справа от
8соответственно. Поскольку8является оператором, числа разделяются символом8. - Если \$ a ≥ b,\$
8становится+. - иначе становится
-.
Затем оцените выражение слева направо и возьмите абсолютное значение.
Если в результате есть какие-либо 8s, повторите вышеуказанные шаги еще раз, пока их не будет.
Например, 12384568789становится:
123 456 7 9
123 < 456: 123 - 456 7 9
456 ≥ 7 : 123 - 456 + 7 9
7 < 9 : 123 - 456 + 7 - 9 = -335
= abs(-335)
= 335
Следовательно, 335 - это окончательный ответ.
Пример ввода и вывода
789 → 2
180 → 1
42312348 → 4231234
2389687 → 66
12384568789 → 335
13749547874394873104972349 → 7309154
808 → 0
7800482 → 13
14458883442 → 1997
88888 → indeterminate
388182 → 2
08182 → 3
Вот тестовые примеры в виде массива:
[789,180,42312348,2389687,12384568789,13749547874394873104972349,808,7800482,14458883442,88888]
Критерии оценки
Это код-гольф . Самый короткий ответ на каждом языке побеждает.
Ответы
05AB1E , 18 14 байт
Δ8¡þDü@1š·<*OÄ
Попробуйте онлайн или проверьте все тестовые примеры .
Пояснение:
Δ # Loop until it no longer changes:
8¡ # Split the integer on 8s
# (which will use the implicit input-integer in the first iteration)
þ # Remove all empty strings by only leaving digits
D # Duplicate this list
ü # For each overlapping pair [a,b]:
@ # Check if a>=b (1 if truthy; 0 if falsey)
1š # Prepend a 1 to this list
· # Double each value
< # Decrease each by 1 (0 has become -1; 1 is still 1)
* # Multiply the values at the same positions in the two lists
O # Sum the list
Ä # And take the absolute value of this sum
# (after which the result is output implicitly)
Желе , 20 18 байт
IŻṠo-×
ṣ8LƇḌÇSAµÐL
Попробуйте онлайн!
Прошел через 5 или 6 других подходов, прежде чем eval оказался единственным, с которым я мог заставить работать ... а затем я попробовал другое вращение во втором подходе, и он на 2 байта короче.
Старая версия: ṣ8LƇḌ<Ɲị⁾_+ż@ƲFVAµÐL
IŻṠo-× Monadic helper link:
Ṡ signs of
I deltas
Ż with prepended 0,
o- replace all 0s with -1s,
× pairwise multiply with argument.
ṣ8LƇḌÇSAµÐL Main link:
ṣ8 split (implicitly converted digit list) on 8s,
LƇ remove empty slices,
Ḍ convert digit lists from decimal,
Ç apply helper link,
S sum,
A abs.
µÐL Loop that whole thing until it doesn't change.
JavaScript (ES6), 76 байт
f=n=>n.replace(p=/[^8]+/g,x=>t-=p<(p=+x)?x:-x,t=0)&&n-(t=t<0?-t:t)?f(t+''):t
Попробуйте онлайн!
Прокомментировал
f = n => // f is a recursive function taking n as a string
n.replace( // we look for ...
p = /[^8]+/g, // ... all groups of consecutive non-eight digits
x => // for each group x:
t -= // update t:
p < (p = +x) ? // if the previous value is less than x:
x // subtract x from t
: // else:
-x, // add x to t
t = 0 // start with t = 0
) && // end of replace()
n - ( // if n is not equal to t,
t = t < 0 ? -t : t // where t is first updated to its absolute value:
) ? //
f(t + '') // do a recursive call with t (coerced back to a string)
: // else:
t // success: return t
Шелуха , 27 26 25 байт
Изменить: -1 байт с использованием Sкомбинатора для повторного использования аргумента функции и перемещения вспомогательной функции в строке, а затем еще -1 байт путем небольшой перестановки, чтобы иметь возможность использовать oкомбинатор вместо()
ω(aΣSz*o:1Ẋȯ`^_1¬<mdfIx8d
Попробуйте онлайн!
Несколько иной подход к шелухи ответ неродственных струны , также 27 байт .
Я ненадолго задержался с публикацией этого сообщения, чтобы дать любому новому Husker'у чистый лист, с которого он мог бы испытать этот вызов ... но теперь Husketition открыт ...
Как? *
mdfIx8d # helper function: splits input on 8s
d # get digits of input
x8 # split on 8
f # remove elements that are falsy for
I # the identity function (so, remove empty elements)
m # map over each element of the list
d # combining digits as decimal number
ωλaΣz*₁¹m`^_1ΘẊo¬<₁ # main program
ω # repeatedly apply function until results are constant
λ # lambda function taking one argument:
a # get the absolute value of
Σ # the sum of all elements of
z* # element-wise multiplication of
₁¹ # (1) helper function applied to input
# (so: the input split on 8s)
m # (2) map this function to all elements of
₁ # helper function applied to input
Θ # (with 0 prepended at the start)
`^_1 # minus one to the power of
Ẋ # the results for each pair of elements
o # combine 2 functions
¬ # NOT
< # second is greater than first
R , 89 122 байтов
Изменить: +33 байта для преобразования в рекурсивную функцию, когда я понял, что он должен повторять 8операцию на своем собственном выходе, пока не закончится 8s. Дох!
f=function(s)`if`(grepl(8,a<-abs(sum(c(1,-sign(diff(n<-sapply((n=el(strsplit(s,8)))[n>-1],as.double))))*n))),f(c(a,'')),a)
Попробуйте онлайн!
Принимает аргумент nкак строку. Ошибки для ns, не содержащих цифр или символов, отличных от 8.
Python 3 , 158 148 145 138 байт
x=input()
while'8'in x:
y=[int(f)for f in x.split('8')if f];x=str(sum([-1,1][y[i-1]<y[i]]*y[i]for i in range(len(y))))
print(abs(int(x)))
Попробуйте онлайн!
-10 байт благодаря @ pavi2410 и мне, что я не идиот и случайно оставил лишнее место из предложения по игре в гольф
и еще -3 благодаря @ pavi2410
и еще -7 благодаря @ pavi2410
С (gcc) , 149 \$\cdots\$ 139 137 байт
Сохранено 2 байта благодаря потолку !!!
Сохранено 8 байт благодаря AZTECCO !!!
R;t=10;m;s;p;c;f(n){R=n;for(s=p=0;n;){for(m=1,c=0;n&&n%t-8;n/=t,m*=t)c+=n%t*m;s+=c>p?p:-p;for(p=c;n%t==8;)n/=t;}p=abs(s+c);R=p-R?f(p):p;}
Попробуйте онлайн!
Объяснение (перед гольфом)
t=10; // golf by storing 10 in t
g(n){ // helper function takes int n
for( ;n;){ // loops until n is zero
s=p=0 // init sum s and previous p to 0
for( // inner loop calculates next rh value
m=1, // init multiplier m to 1
c=0; // and current c to 0
n&& // loop until n is 0
n%t-8; // or most rh digit is 8
n/=t, // knock most rh digit off n
m*=t) // and bump m by 10 each loop
c+=n%t*m; // add next digit to current
// building up number after
// most right-hand 8
s+=c>p?p:-p; // after that's done update sum s
for( // loop to strip off all rh 8's
p=c; // also make previous = current
n%t==8;) // loop until most rh digit isn't an 8
n/=t; // knock most rh 8 off n
} //
p=abs(s+c); // return abs value of sum with
// positive most lh value
} //
f(n){ // recursive main function
x=g(n); // calc first iteration
x=x-g(x)? // is it different to next iteration?
f(x): // if so iterate
x; // else return value
} //
Perl 5 -p , 59 байт
y/8/ /;s/\d+/$&<$'?"$&-":"$&+"/ge;$_=abs eval$_.0;/8/&&redo
Попробуйте онлайн!
J , 53 байта
|@('8'+/@(*_1x^0,2</\])@(,(*@#;._1#".;._1)~[=,)":)^:_
Попробуйте онлайн!
Как это устроено
f^:_: пока результат не изменится, делать ф.'8'…(,g[=,)":: преобразовать ввод в строку, добавить,символ в начало8и выполнитьgс этим в качестве левого аргумента и битовой маской8символов в качестве правого аргумента.(…".;._1)~: разделить строку на группыu;._1, которые начинаются с 1 в битовой маске, и преобразовать их обратно в числа".(исключая8).*@#;._1#: Потому что мы могли бы иметь пустые группы (888), принимает#только те, длину Чьей в#сигнум*равно 1. (Там может быть лучше подход.)2</\]: сравнить<каждую группу со следующей, получая битовую маску.*_1x^0,: Предварять 0 до битовой маски, и вычислитьx*(-1)^yдля каждой группыxсyявляется результатом из сравнения. Итак, получаем3 1 2 -> 3 1 _2.|@…+/: просуммируйте+/результат и возьмите абсолютное значение|.
Scala , 94 90 байт
i=>"[^8]+".r.findAllIn(""+i).map(_.toInt).scanRight(0){(a,b)=>if(a<b.abs)a else-a}.sum.abs
Попробуйте онлайн!
-4 байта, если не использовать проклятый splitметод Java .
i=> //The input
"[^8]+".r //Regex for operands
.findAllIn(""+i) //Get all separate numbers in the input
.map(_.toInt) //Turn them into integers
.scanRight(0){(a,b)=> //Starting at the right,
if(a<b.abs)a else-a} //Replace a with -a if a >= b.abs (this is different from the challenge, but it works because we call abs again later)
.sum //Sum them up
.abs //Take the absolute value
Шелуха , 27 байт
ω(aΣSz*(Ẋȯ`^_1±>Ṡ:←)mdfIx8d
Попробуйте онлайн!
Это не совсем мой первый ответ Husk, но это довольно неуклюжий прямой перевод одного из моих попыток ответов Jelly, так что он может, по крайней мере, послужить удобной отправной точкой для кого-то, кто может налететь и заработать награду.
ω( Iterate until periodic:
a absolute value of
Σ sum of
z* zipwith multiplication on:
d decimal digits
x8 split on 8s
fI with empty slices removed
md and converted back from decimal,
S and the result of that
( Ṡ:←) with its first element duplicated
Ẋ and with neighboring pairs mapped to
`^_1 -1 to the power of
ȯ ±> if the first is less than the second.
Bash , 177 байт
A=($(sed s/8/\ /g<<<$1));B=;while [ ${#A[@]} -ge 2 ];do [ ${A[0]} -ge ${A[1]} ]&&C=+||C=-;B=$B${A[0]}$C;A=(${A[@]:1});done;R=$(bc<<<$B$A|tr -d -);grep -cq 8 <<<$R&&f $R||echo $R
Он должен быть сохранен как функция fили в файле fв текущем рабочем каталоге.
Попробуйте онлайн!
PHP, 290 байт
(Думаю, вам не следует играть в гольф на php. :))
<?php $n=$_SERVER["argv"][1];while(false!==strpos($n,'8')){$n=abs(array_reduce(str_split(preg_replace('|8+|','8',trim($n,'8')).'8'),function($c,$i){if($i!=8){$c[1]*=10;$c[1]+=$i;}else{$c[2]+=$c[1]*((!isset($c[0])||$c[0]>=$c[1])?1:-1);$c[0]=$c[1];$c[1]=0;}return$c;},[null,0,0])[2]);}echo$n;
Попробуйте онлайн
Без гольфа:
<?php
$n = $_SERVER["argv"][1]; $f=function($c, $i){
if($i!=8) { $c[1]*=10;
$c[1]+=$i;
} else {
$c[2] += $c[1] * ( (!isset($c[0]) || $c[0]>=$c[1])?1:-1); $c[0]=$c[1]; $c[1]=0;
}
return $c; }; while(false!==strpos($n,'8')) {
$n = trim($n, '8');
$n = preg_replace('|8+|', '8', $n);
$a = str_split($n.'8');
$n = abs(array_reduce($a, $f, [null, 0, 0])[2]); } echo $n;
Пояснение:
Я использую array_reduce, чтобы пройтись по каждой цифре, и использую массив как перенос, чтобы иметь 3 точки данных: переменные $a, $группа $sum, though they are unnamed as the elements of $c.
Если текущая цифра не 8, я "добавляю" ее к своему "$b", otherwise I first compare $б к $a, add/subtract $б из $sum, and move the content of $b к $ a.
Красный , 142 байта
func[n][while[find to""n"8"][b: to[]load form split to""n"8"forall b[if b/2[b/1:
reduce[b/1 pick[- +]b/1 < b/2]]]n: absolute do form b]to 1 n]
Попробуйте онлайн!
GolfScript , 32 байта
.,{8`%(~:x\{~.x\:x<2*(*-}/abs`}*
Попробуйте онлайн!
Каждый раз, когда выполняется алгоритм, число либо остается неизменным, либо становится короче как минимум на 1 цифру. Это означает, что мы можем выполнять алгоритм один раз для каждого байта вместо проверки, имеет ли он значение 8.
., # Get the number of bytes in the input
{ }* # Execute this block that many times
8`% # Split the string around the 8s and remove the empty strings
# This simultaneously executes the first 3 steps
(~ # Get the first number
:x # Store it in the variable x
\{~ }/ # For each number left in the array
.x # Copy it and push x
\:x # Store the current number in x
< # Compare the two numbers
2*( # 1 if previous<current and -1 if previous>=curret
*- # Multiply and subtract
abs` # Parse the absolute value to a string
Japt , 37 байт
@=q8 f;=äÈn ¨Y?Y:-Y}Ug)x a s ,Uø8}f U
Попробуй это
- принимает ввод как строку, его можно легко изменить, чтобы вводить как число, но он не будет работать с большими числами
'' '
@=q8 f;=äÈn ¨Y?Y:-Y}Ug)x a s ,Uø8}f U
@....}f - return first number which return false when passed through @...
=q8 f; - input splitted on 8 and empties removed
=äÈ...}Ug) - pass each consecutive values through È , but prepend first value before so that they are >=
n ¨Y?Y:-Y - 1st to number compared to 2nd: return 2nd (negated eventually)
x a s - reduce->abs->to string
The above is assigned to U while the funxtion returns..
Uø8 - contains 8? => repeat
Finally we return U
'' '
K (oK) , 60 43 38 байт
-22 байта благодаря Traws
{a|-a:+/{x*1-2*>':x}.:'(~^.)#"8"\$:x}/
Попробуйте онлайн!
Retina 0.8.2 , 68 байт
{`8+
-
^-|-$ \d+ $*
(?=-(1*))(?<=\1)-
+
O`\D1*
\+
1>`-
(1+)-\1
1
Попробуйте онлайн! Ссылка включает меньшие тестовые случаи (Retina должна выполнять вычитание в унарном порядке, что слишком медленно для больших случаев). Пояснение:
{`
Повторяйте, пока не останется 8s.
8+
-
Преобразуйте каждый прогон 8s в a -.
^-|-$
Удалите начальные и конечные -s.
\d+
$*
Преобразуйте оставшиеся числа в унарные.
(?=-(1*))(?<=\1)-
+
Замените каждую букву -, +если следующее число не больше.
O`\D1*
Отсортируйте числа, которые нужно добавить в начало, и числа, которые нужно вычесть, в конец.
\+
Сложите все числа, которые нужно сложить.
1>`-
Сложите все числа, которые нужно вычесть.
(1+)-\1
Возьмите абсолютное значение разницы.
1
Преобразуйте его в десятичное.