Аддитивная стойкость


20

Самый короткий код для прохождения всех возможностей выигрывает.

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

Пример использования 84523:

84523
8 + 4 + 5 + 2 + 3 = 22
2 + 2 = 4

It took two repetitions to find the single digit number.
So the additive persistence of 84523 is 2.

Вам будет дана последовательность положительных целых чисел, из которых вы должны рассчитать аддитивную стойкость. Каждая строка будет содержать другое целое число для обработки. Ввод может быть любым стандартным методом ввода / вывода .

Для каждого целого числа вы должны вывести целое число, затем один пробел и его аддитивное постоянство. Каждое обработанное целое число должно быть в отдельной строке.

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


Ввод, вывод

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0

1
Ваши тестовые примеры включают в себя некоторые значения, которые превышают 2 ^ 64, и ваша спецификация говорит, что программа должна обрабатывать только значения до 2 ^ 32. Может быть, стоит это прояснить.
Питер Тейлор

@ Питер Тейлор, забыл снять эти ограничения. Если программа может обрабатывать вводимые мной данные, у нее не должно быть проблем с ограничениями.
Кевин Браун

5
Разве не 999999999999 настойчивость 2 вместо 3?
Eelvex

@Evelex, это было неправильное изменение в последнюю минуту, я думаю. Исправлена.
Кевин Браун

Несколько ответов здесь не делают вывод на stdout, а скорее используют «интерактивный» вывод J, возвращая результаты после ввода командной строки. (Это включает в себя 2 других ответа J и, я предполагаю, ответ К.). Это считается законным? Потому что я могу пролить 18-ти иероглифные символы, если это так.
Джесси Милликен

Ответы:


6

К - 29 символов

Ввод - это имя файла, переданное в качестве аргумента, 29 символов, не включая имя файла.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Удалить внешнюю функцию.
  • 31 -> 29: удалить паренсы.

1
-1+#=>#1_
Стритстер

4

Python 84 символа

while 1:
 m=n=int(raw_input());c=0
 while n>9:c+=1;n=sum(map(int,str(n)))
 print m,c

Задача: 06234.. результат успешного вызова :-)
Quixotic

@Debanjan Спасибо. Исправленный.
fR0DDY


4

Python (93 байта)

f=lambda n,c:n>9and f(sum(map(int,str(n))),c+1)or c
while 1:n=int(raw_input());print n,f(n,0)

я думаю, что вы можете удалить пробел между 9и ошибаться ...and
STOLE

@ st0le: Спасибо :-)
Quixotic

и input()вместо int(raw_input())....
st0le

@ st0le: Попробуйте этот вход с этой модификацией: 06234.
Quixotic

4

Шелуха , 10 15 байт

+5 байт для ужасного требования ввода / вывода

m(wΓ·,LU¡oΣdr)¶

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

объяснение

Для поддержки нескольких входов нам нужно использовать m(₁r)¶(где функция, выполняющая интересные вычисления):

m(₁r)¶  -- expects newline-separated inputs: "x₁␤x₂␤…␤xₙ"
     ¶  -- split on newlines: ["x₁","x₂",…,"xₙ"]
m(  )   -- map over each string
 ( r)   -- | read integer: [x₁,x₂,…,xₙ]
 (₁ )   -- | apply the function described below

Функция выполняет следующие действия:

wΓ·,LU¡(Σd)  -- input is an integer, eg: 1234
      ¡(  )  -- iterate the following forever and collect results in list:
       ( d)  -- | digits: [1,2,3,4]
       (Σ )  -- | sum: 10
             -- : [1234,10,1,1,1,…
     U       -- keep longest prefix until repetition: [1234,10,1]
 Γ           -- pattern match (x = first element (1234), xs = tail ([10,1])) with:
  · L        -- | length of xs: 2
   ,         -- | construct tuple: (1234,2)
w            -- join with space: "1234 2"

3

Баш, 105 символов

while read x
do
for((i=0,z=x;x>9;i++))do
for((y=0;x>0;y+=x%10,x/=10))do :
done
x=$y
done
echo $z $i
done

Едва ли это связано с гольфом, но я не вижу, как его улучшить.



3

Рубин, 85 символов

puts $<.map{|n|v=n.chop!;c=0;[c+=1,n="#{n.sum-n.size*48}"] while n[1];[v,c]*' '}*"\n"

Мне пришлось позаимствовать идею «сумма-размер * 48» у Алекса, потому что она слишком аккуратна, чтобы ее пропустить (по крайней мере, в Ruby).



3

J - 45 символов

Читает со стандартного ввода

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3

Я пытался использовать ^:a:себя, но я не мог найти надлежащую документацию ... какие-либо подсказки?
Eelvex

1
Запись словаря для и ^: п есть информация о его использовании , но это немного плотная. ^: a: похож на любой другой призыв к власти, но он собирает результаты и заканчивается, когда аргумент последовательных вызовов одинаков (сходится).
isawdrones

1
@Eelvex FWIW Я обнаружил с a:помощью ^:a:трюка в J Reference Card [PDF]
JB

@JB: Это единственное упоминание о ^:a:том, что я знал: D
Eelvex

@ Двенадцать У меня был противоположный опыт тогда. Я обнаружил функциональность в словаре и ^:(<'')сначала использовал ее в качестве некоторого варианта (вероятно, для Kaprekar), пока не заметил его в карточке, и узнал об a:этом случае.
JB

3

с - 519

(или 137, если вы отдаете мне должное за рамки ...)

Вместо того, чтобы решать только эту операцию, я решил создать основу для решения всех постоянных проблем .

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char*(*O)(char*);
char*b(char*s){long long int v=0,i,l=0;char*t=0;l=strlen(s);t=malloc(l+2);
for(i=0;i<l;i++)v+=s[i]-'0';snprintf(t,l+2,"%lld",v);return t;}
int a(char**s,O o){int r;char*n;n=o(*s);r=!strcmp(*s,n);free(*s);
*s=n;return r;}
int main(int c, char**v){size_t l, m=0;char *d,*n=0;O o=b;FILE*f=stdin;
while(((l=getline(&n,&m,f))>1)&&!feof(f)){int i=0;n=strsep(&n,"\n");
d=strdup(n);while(!a(&n,o))i++;printf("%s %d\n",d,i);free(d);free(n);n=0;m=0;}}

Только две строки, начиная с, char*bявляются уникальными для этой проблемы.

Он обрабатывает входные данные как строки, что означает, что начальные «0» не передаются перед выходным каскадом.

Выше были добавлены комментарии, проверка ошибок и отчеты, а также чтение файла (входные данные должны поступать со стандартного ввода) из:

/* persistence.c
 *
 * A general framework for finding the "persistence" of input strings
 * on opperations.
 *
 * Persistence is defined as the number of times we must apply
 *
 *    value_n+1 <-- Opperation(value_n)
 *
 * before we first reach a fixed point.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../getline.h"

/* A function pointer type for operations */
typedef char*(op_func)(char*);
typedef op_func* op_ptr;
/* Op functions must
 * + Accept the signature above
 * + return a point to a newly allocated buffer containing the updated str
 */

char* addop(char*s){
  int i,l=0;
  long long int v=0;
  char *t=NULL;
  /* protect against bad input */
  if (NULL==s) return s;
  /* allocate the new buffer */
  l = strlen(s);
  t = malloc(l+2);
  if (NULL==t) return t;
  /* walk the characters of the original adding as we go */
  for (i=0; i<l; i++) v += s[i]-'0';
  //fprintf(stderr,"   '%s' (%d) yields %lld\n",s,l,v);
  snprintf(t,l+2,"%lld",v);
  //fprintf(stderr,"   %lld is converted to '%s'\n",v,t);
  return t;
}

/* Apply op(str), return true if the argument is a fixed point fo
 * falsse otherwise,
 */ 
int apply(char**str, op_ptr op){ 
  int r;
  char*nstr;
  /* protect against bad input */
  if ( NULL==op ) exit(1); 
  if ( NULL==*str ) exit(4); 
  /* apply */
  nstr = op(*str); 
  /* test for bad output */
  if ( NULL==nstr ) exit(2); 
  r = !strcmp(*str,nstr); 
  /* free previous buffer, and reasign the new one */
  free(*str); 
  *str = nstr; 
  return r; 
}

int main(int argc, char**argv){
  size_t len, llen=0;
  char *c,*line=NULL;
  op_ptr op=addop;
  FILE *f=stdin;
  if (argc > 1) f = fopen(argv[1],"r");
  while( ((len=getline(&line,&llen,f))>1) && line!=NULL && !feof(f) ){
    int i=0;
    line=strsep(&line,"\n"); // Strip the ending newline
    /* keep a copy for later */
    c = strdup(line);
    /* count necessary applications */
    while(!apply(&line,op)) i++;
    printf("%s %d\n",c,i);
    /* memory management */
    free(c);
    free(line);
    line=NULL;
    llen=0;
  }
}

Немного больше можно было бы спасти, если бы мы хотели утратить память, как сито. Точно так же, #defineвозвращая и тому подобное, но на данный момент я не хочу, чтобы это было еще страшнее.



2

J, 74 знака

i=:<;._2(1!:1)3
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i

Правки

  • (86 → 83) Некоторые заглавные [:буквы к Ats@
  • (83 → 79) Ненужные скобки
  • (79 → 75) Изменение 0".к ".упрощает вещи
  • (75 → 74) Лучшая резка

Например

i=:<;._2(1!:1)3
74621
39
2677889
0
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i
74621 2  
39 2     
2677889 3
0 0  

Выходные данные неправильно отформатированы для нескольких входов. Смотрите "один пробел"
Джесси Милликен

@Jesse: я не вижу ничего плохого. Не могли бы вы написать пример, пожалуйста?
Eelvex

Я понятия не имею, я вижу вещи, которые я думаю.
Джесси Милликен

1

Я думаю, что это лучшее из того, что я могу придумать.

Ruby 101 Chars

f=->(n){n.sum-n.size*48}
$<.each{|l|i=0;i+=1 while(i+=1;n=f[(n||l.chop!).to_s])>10
puts "#{l} #{i}"}

На самом деле, нарезать! вместо того, чтобы грызть! дает мне один символ сбережений. 97 символов
Алекс Бартлоу

Просто сделал еще несколько игр в гольф - 91 символ.
Алекс Бартлоу

1

PARI / GP 101 Чарс

s(n)=r=0;while(n>0,r+=n%10;n\=10);r
f(n)=c=0;while(n>9,c++;n=s(n));c
while(n=input(),print(n," ",f(n)))

К сожалению, для GP нет функции ввода, так что я думаю, что в ней отсутствует часть ввода-вывода. :( Исправлено: Спасибо Eelvex! :)


Конечно, есть: input():)
Eelvex

@ Двенадцать, готово. :)
st0le

1

Javascript - 95

i=prompt();while(i>9){i=''+i;t=0;for(j=0;j<i.length;j++)t+=parseInt(i.charAt(j));i=t;}alert(t);

РЕДАКТИРОВАТЬ: Whoops не делает несколько строк


1
Просто заметил, что это не выводит правильно.
Кевин Браун

1

J, 78

f=:[:+/"."0&":
r=:>:@$:@f`0:@.(=f)
(4(1!:2)~LF,~[:":@([,r)".@,&'x');._2(1!:1)3

Рекурсивное решение. Читает со стандартного ввода. Пишет в stdout , так что не торопись - для этого нужны лишние 18-ти символьные символы.


1

Perl - 77 символов

sub'_{split//,shift;@_<2?0:1+_(eval join'+',@_)}chop,print$_,$",(_$_),$/for<>

1

JavaScript , 57 47 байт

-10 байт благодаря @ l4m2!

f=(s,c=0)=>s>9?f(eval([...s+""].join`+`),++c):c

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


f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x*1+y*1),++c):c
4

f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x- -y),++c):c
м2 18

1
f=(s,c=0)=>s>9?f(eval([...s+""].join`+`)),++c):c
м2 18

@ l4m2 Спасибо! s>9и evalбыли отличные идеи. Я думаю, что у вас там был лишний паренон, то есть всего 10 байт, которые вы спасли меня :-)
Оливер

Обратите внимание на строгий ввод / вывод;)
Shaggy

1

05AB1E , 13 байтов

ε.µΔSO¼}¾}<ø»

Ввод в виде списка целых чисел.

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

Объяснение:

ε     # Map each integer in the (implicit) input to:
    #  Reset the counter variable to 0
 Δ    #  Loop until the integer no longer changes:
  S   #   Convert it to a list of digits
   O  #   And take the sum of those
  ¼   #   Increase the counter variable by 1
    #  After the inner loop: Push the counter variable
}<    # After the map: decrease each value by 1
  ø   # Zip/transpose it with the (implicit) input to create a paired list
   »  # Join each pair by a space, and then each string by newlines
      # (after which the result is output implicitly)

1

MathGolf , 11 байт

hÅ_Σ]▀£(k ?

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

Невероятно неэффективно, но нас это не волнует. В основном, используя тот факт, что аддитивная стойкость числа меньше или равна самому числу.

Используется тот факт, что аддитивная стойкость меньше или равна количеству цифр числа. Теперь легко проходит все тесты.

Формат ввода, хотя и неоптимальный для некоторых языков, на самом деле является стандартным методом принятия нескольких тестовых случаев в качестве входных данных в MathGolf. Каждая строка ввода обрабатывается как собственное выполнение программы, а вывод отделяется одной новой строкой для каждого выполнения.

Объяснение (использование n = 6234)

h             push length of number without popping (6234, 4)
 Å            loop 4 times using next 2 operators
  _           duplicate TOS
   Σ          get the digit sum
    ]         wrap stack in array
              this gives the array [6234, 15, 6, 6, 6]
     ▀        unique elements of string/list ([6234, 15, 6])
      £       length of array/string with pop (3)
       (      decrement (2)
        k ?   push input, space, and rotate top 3 elements to produce output (6234 2)

1

К (нгн / к) , 16 байт

Решение:

{x,#1_(+/10\)\x} 

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

Объяснение:

{x,#1_(+/10\)\x} / the solution
{              } / lambda taking implicit x
      (     )\x  / iterate until convergence
         10\     / split into base-10 (123 => 1 2 3)
       +/        / sum
    1_           / drop first result (iterate returns input as first result)
   #             / count length of result
 x,              / prepend x (original input)

1

Stax , 8 11 байт

ªwæMε∞ö?îm⌐

Запустите и отладьте его

+3 байта благодаря @Khuldraeseth (первый ответ не дал совместимого вывода)


1
Я достиг того же решения, но с iна месте u. Придерживаясь драконовских спецификаций ввода / вывода, это становится 11 байтами .
Хулдрасет на'Барья

К сожалению. Я думаю, я не очень хорошо читал требования к IO. Я обновлю свой ответ.
рекурсивный



0

Java (OpenJDK 8) , 79 байт

a->{int d=0;while(a/10>0){int c=0;d++;while(a>0){c+=a%10;a/=10;}a=c;}return d;}

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

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



Опираясь на @JonathanFrech 67 байт
потолок кошка

0

Python 3 , 82 байта

while 1:f=lambda n:n//10and 1+f(sum(map(int,str(n))));i=input();print(i,f(int(i)))

0

Tcl , 95 байт

proc P {v n\ 0} {set V $v
while \$v>9 {set v [expr [join [split $v ""] +]]
incr n}
puts $V\ $n}

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


3
Потому что следующий новый ответ - полные 6 лет, что, я думаю, еще до того, как существовал
TIO

0

Japt , 28 байт

Ë+S+(@D=X©A<D©ì x ªD D<AÃa÷
Ë                            // Map over the inputs and return each, followed by
 +S+                         // a space, followed by the number's persistence.
      D=     ©ì x            // To find it, fold the number up
        X©A<D     ªD         // if we can (handles unfoldable cases),
    (@               D<AÃa   // until it can't be folded up any further.
                          ÷ // Then, join everything up with newlines.

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


0

PHP, 72 + 1 байт

+1 за -Rфлаг.

for($i=0,$a=$argn;$a>9;$i++)$a=array_sum(str_split($a));echo"$argn $i
";

Беги как труба с -R.

  • запуск PHP как pipe будет выполнять код один раз для каждой строки ввода
  • но это не сбрасывает переменные между ними; так $iдолжно быть инициализировано.
    (Кроме того, он не печатает ничего вместо 0одной цифры без инициализации.)

0

Bash + coreutils, 83 байта

[ $1 -le 9 ]&&exit $2
let x=$2+1
for z in `fold -w1<<<$1`
do let y+=$z
done
a $y $x

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

Должен быть сохранен в сценарий , который вызывается aи помещается в систему PATH, так как он вызывает себя рекурсивно. Принимает ввод из командной строки, как a 1999. Возвращает по коду выхода.

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

Выводит ошибку stderrдля ввода, большего, чем могут обработать целые числа bash, но поскольку фактические вычисления выполняются со строками, это все равно дает правильный результат в любом случае.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.