Адитивна стійкість


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?
Ельвекс

@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 Chars

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

Випадок виклику: 06234.. результат успішний виклик :-)
Кіхотичний

@Debanjan Дякую Виправлено.
fR0DDY



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"

Мені довелося запозичити ідею "sum-size * 48" у Алекса, бо це просто занадто акуратно, щоб упустити (принаймні, у Рубі).


3

Гольфскрипт, 40 символів

n%{.:${;${48-}%{+}*`:$,}%.,1>\1?+' '\n}%

3

J - 45 символів

Читає від stdin

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

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

1
У словниковому записі для u ^: n є інформація про його використання, але вона трохи щільна. ^: a: як і будь-який інший виклик до влади, але він збирає результати і закінчується, коли аргумент послідовних викликів однаковий (зближується).
isawdrones

1
@Eelvex FWIW я виявив a:через ^:a:трюк в J Reference Card [PDF]
JB

@JB: Це єдине посилання на ^:a:те, що я знав: D
Eelvex

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

3

c - 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) Деякі шапки [:в Атс@
  • (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: Я не бачу нічого поганого. Чи можете ви написати приклад, будь ласка?
Ельвакс

Я поняття не маю, я бачу речі, які я здогадуюсь.
Джессі Мілікан

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 Chars

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 не існує функції введення, тому, мабуть, у цій частині не вистачає частини IO. :( Виправлено: Спасибі 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);

EDIT: Whoops не робить багато рядків


1
Щойно помічено, це не виводить його правильно.
Кевін Браун

1

J, 78

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

Рекурсивне рішення. Читає від stdin. Пишеться в 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
l4m2

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

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

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

Зверніть увагу на суворий
Шагге

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

Стакс , 8 11 байт

ªwæMε∞ö?îm⌐

Запустіть і налагоджуйте його

+3 байти завдяки @Khuldraeseth (перша відповідь не мала сумісного результату)


1
Я дійшов до того ж рішення, але з iзамість u. Дотримуючись драконівських специфікацій вводу-виводу, це стає 11 байтами .
Khuldraeseth na'Barya

На жаль Напевно, я не дуже добре прочитав вимоги 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 байт
roofcat

0

Пітон 3 , 82 байти

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


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 як труба буде виконувати код один раз для кожного вхідного рядка
  • але він не скидає змінні між собою; тому $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.