17
\$\begingroup\$

Appended Numbers Game

Write a function/program that takes 2 integer parameters integer parameters or integer variables, a start number, and a max iterations count. The code should perform the following game example to construct a new number, and repeat until the number is a single digit left. eg.

3 7 2 = (3 + 7) & (7 + 2) = 10 9
1 0 9 = (1 + 0) & (0 + 9) = 1 9
1 9 = (1 + 9) = 10
1 0 = (1 + 0) = 1

Basically, taking each individual digit and adding it to its neighbour, then appending the result of the next addition as well.

Max iteration count is to safeguard infinite loops, and when the max is hit, code should dump the last 5 number steps. The same output should occur when finishing by reaching a single digit. If less than 5 steps occurred, only output the valid numbers.

Output should appear like (Step: Number) including the last 5 steps of the finished or terminated steps:

func(3541, 50) would produce this exact output format:

6: 1411
7: 552
8: 107
9: 17
10: 8

func(3541, 5) would produce:

1: 895
2: 1714
3: 885
4: 1613
5: 774

The entire calculation being:

1: 895
2: 1714
3: 885
4: 1613
5: 774
6: 1411
7: 552
8: 107
9: 17
10: 8

If there are less than 5 steps, just print those steps taken.

Only use built-in libs, parameters can be from anywhere (whatever's easiest for your language of choice). No limit on maximum integer size, and if there are overflows, let it crash.

Given this isn't too difficult from a puzzle point of view, I will give until Sunday 25th, 8PM (UTC+8) for submissions to be considered for the accepted answer, at which point the shortest of any language will be the winner.

EDIT:

Congratulations to Howard, winning with a 48 GolfScript answer.

Special mention to 2nd place marinus with a 66 APL answer.

My personal favourite (being biased towards JavaScript) was core1024's answer.

\$\endgroup\$
2
  • \$\begingroup\$ I don't understand, is func(3541, 5) supposed to print 5 steps or 10? \$\endgroup\$
    – Tal
    May 20, 2014 at 5:48
  • \$\begingroup\$ 5 steps. It should stop as it hits iteration 5, perform no more iterations and print out the last 5 steps. I just included the full set of steps to show the full calculation process for that particular input. \$\endgroup\$
    – Matt
    May 20, 2014 at 6:11

25 Answers 25

10
\$\begingroup\$

APL (66)

{↑¯5↑{(⍕⍵),': ',⍺}/∆,⍪⍳⍴∆←⍺{(1<⍴⍵)∧⍺>0:∆,(⍺-1)∇⊃∆←,/⍕¨2+/⍎¨⍵⋄⍬}⍕⍵}

The left argument is the maximum iteration count and the right argument is the start number.

Explanation:

  • ∆←⍺{...}⍕⍵: pass the left argument as a number and the right argument as a string to the function that calculates the list of numbers, and store it in :
    • (1<⍴⍵)∧⍺>0:: if the amount of digits is more than 1 and the amount of iterations left is more than 0:
      • ⍎¨⍵: evaluate each digit
      • 2+/: sum each pair
      • ⍕¨: format each number as a string
      • ∆←,/: concatenate the strings and store in
      • ∆,(⍺-1)∇⊃∆: return , followed by the result of applying this function to with one less iteration allowed
    • ⋄⍬: if not, return the empty list
  • ∆,⍪⍳⍴∆: pair each element of with its index in
  • {...}/: for each pair:
    • (⍕⍵),': ',⍺: return a string with the index, followed by :, followed by the number
  • ↑¯5↑: turn the list of strings into a matrix so they display on separate lines, and take the last 5 items

Test:

      5{↑¯5↑{(⍕⍵),': ',⍺}/∆,⍪⍳⍴∆←⍺{(1<⍴⍵)∧⍺>0:∆,(⍺-1)∇⊃∆←,/⍕¨2+/⍎¨⍵⋄⍬}⍕⍵}3541
1: 895 
2: 1714
3: 885 
4: 1613
5: 774 
      50{↑¯5↑{(⍕⍵),': ',⍺}/∆,⍪⍳⍴∆←⍺{(1<⍴⍵)∧⍺>0:∆,(⍺-1)∇⊃∆←,/⍕¨2+/⍎¨⍵⋄⍬}⍕⍵}3541
6: 1411
7: 552 
8: 107 
9: 17  
10: 8  
\$\endgroup\$
2
  • \$\begingroup\$ Does this handle displays of less than 5 steps properly? E.g. 3 {...} 3541. \$\endgroup\$ May 20, 2014 at 14:56
  • \$\begingroup\$ @algorithmshark It does now (it gave extra lines with : first) \$\endgroup\$
    – marinus
    May 20, 2014 at 15:41
5
\$\begingroup\$

Mathematica, 172 characters

This is way too long, thanks to Mathematica's function names and ugly string handling (the actual "game" is only 76 of those characters), but here it is anyway:

""<>ToString/@(f=Flatten)@Take[Thread@{r=Range@Length[s=Rest@Cases[NestList[FromDigits[f@(d=IntegerDigits)[Tr/@Partition[d@#,2,1]]]&,n,m],i_/;i>0]],": "&/@r,s,"\n"&/@r},-5]

It expects the input number in variable n and the maximum number of iterations in m.

With less golf:

"" <> ToString /@
  (f = Flatten)@
   Take[
    Thread@{
      r = Range@Length[
         s = Rest@Cases[
            NestList[                 
             FromDigits[
               f@(d = IntegerDigits)[Tr /@ Partition[d@#, 2, 1]]] &,
             n,
             m
             ],
            i_ /; i > 0
            ]
         ],
      ": " & /@ r,
      s,
      "\n" & /@ r
      },
    -5
    ]
\$\endgroup\$
5
\$\begingroup\$

Ruby, 106 characters

f=->n,m{s=0
$*<<"#{s}: #{n=n.to_s.gsub(/.\B/){eval$&+?++$'[0]}.chop}"until n.to_i<10||m<s+=1
puts$*.pop 5}

I'm not 100% clear on the input rules, but if I can take n as a string I can save 5 characters, and if I can use predefined variables and write a program instead of a function, I can save another 9.

Creates a function f which can be called as follows:

f[3541, 6]

2: 1714
3: 885
4: 1613
5: 774
6: 1411

f[372, 50]

1: 109
2: 19
3: 10
4: 1

f[9999, 10]

6: 99999999999
7: 18181818181818181818
8: 9999999999999999999
9: 181818181818181818181818181818181818
10: 99999999999999999999999999999999999
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Interesting observation that 4 or more "9"s produces a diverging result \$\endgroup\$ May 20, 2014 at 17:11
4
\$\begingroup\$

GolfScript, 48 46 characters

{.`n*[~]n\{:s++s}*;~}*].,,\]zip{': '*}%1>-5>n*

Thank you to Peter Taylor for a two-character improvement.

Expects both numbers on the stack. Try online.

Examples:

> 4 50

> 141 50
1: 55
2: 10
3: 1

> 3541 50
6: 1411
7: 552
8: 107
9: 17
10: 8

> 3541 5
1: 895
2: 1714
3: 885
4: 1613
5: 774
\$\endgroup\$
1
  • \$\begingroup\$ There's a moderate saving by adding a flip after .,, and turning the final map into just {': '*}%. \$\endgroup\$ May 22, 2014 at 15:41
4
\$\begingroup\$

J - 96 92 char

I'd first solved this assuming that all games terminated, and this came back to bite me in the ass during testing. Left argument is the number of steps, right argument is the starting position, which can be given as a number or a string.

([(-@(<.5<.#){.])(#\(,': '&,)&":"0,)@}.@({.~,i.0:)@:".@(<@>:@[(' '-.~[:,@":2+/\"."0@]^:)":))

This is a little too golfed and convoluted to degolf satisfyingly, so I'll say this:

  • (<@>:@[(' '-.~[:,@":2+/\"."0@]^:)":) This part runs the game for the specified number of steps. 2+/\ is responsible for adding each pair of digits, and <@>:@[ in tandem with ^: controls capturing the intermediate steps of the game.
  • (#\(,': '&,)&":"0,)@}.@({.~,i.0:)@:". This part formats all the results as step: result. ({.~,i.0:) is making sure we don't take too many steps, #\ is the step numbers, and the (,': '&,)&":"0 bit adds the colon and space.
  • (-@(<.5<.#){.]) This portion cuts the relevant five-or-less steps out of the full list. <. means 'minimum of'.

It works, but if you start with a large enough number, the game's results quickly start growing in size, which makes J switch from integers to the imprecise doubles. Here are some examples:

   f =: ([(-@(<.5<.#){.])(#\(,': '&,)&":"0,)@}.@({.~,i.0:)@:".@(<@>:@[(' '-.~[:,@":2+/\"."0@]^:)":))
   5 f 3541
1: 895
2: 1714
3: 885
4: 1613
5: 774
   50 f 3541
6: 1411
7: 552
8: 107
9: 17
10: 8
   100 f 372
1: 109
2: 19
3: 10
4: 1
\$\endgroup\$
3
\$\begingroup\$

Javascript 139 144 150

function f(a,n){for(r=[a+=''];n--&&a[1];r.push(a=t))for(t='',i=0;a[++i];)t+=a[i-1]- -a[i];for(i=0;r[++i];)r[i+5]||console.log(i+': '+r[i])}

Ungolfed

function f(a,n)
{
  for (r=[a+='']; n-- && a[1]; r.push(a=t))
  {
    for (t = '', i = 0; a[++i]; )
    {
      t += a[i-1]- -a[i]; /* -char force conversion to number */
    }
  }   
  for (i = 0; r[++i];) r[i+5]||console.log(i+': '+r[i])
}
\$\endgroup\$
3
\$\begingroup\$

Perl, 86 84

With newlines for readability:

$s+=$_=<>;
print+(map$s=~s/.(?=(.|))/~$1?$&+$1:''/eg>1?"$_: $s$/":(),/ /..$')[-5..-1]

+ Edit: No excuse for not using -n command line switch, and then score is 82=81+1:

$s+=$_;
print+(map$s=~s/.(?=(.|))/~$1?$&+$1:''/eg>1?"$_: $s$/":(),/ /..$')[-5..-1]

And, possible integer overflow being OK, it's 81=80+1

$.=$_;
print+(map$.=~s/.(?=(.|))/~$1?$&+$1:''/eg>1?"$_: $.$/":(),/ /..$')[-5..-1]
\$\endgroup\$
1
  • \$\begingroup\$ I learned new tings. Awesome! \$\endgroup\$
    – core1024
    May 20, 2014 at 17:51
2
\$\begingroup\$

Javascript, 247 278 288 307 Characters

 var t=[],q=1;function f(a,c){var x=a.toString().split(''),r='',p=parseInt;for(y in x){var i=p(y);if(i){r+=(p(x[i])+p(x[i-1])).toString();}}if(c!=0&&a>10){t.push(q+++':'+r+'\n');if(q>6){t.shift()}f(r,c-1);}console.log(t.join(',').replace(/,/g,''))}

Formatted

var t = [],
q = 1;

function f(a, c) {
 var x = a.toString().split(''),
    r = '',
    p = parseInt;
 for (y in x) {
    var i = p(y);
    if (i) {
        r += (p(x[i]) + p(x[i - 1])).toString();
    }
 }
 if (c != 0 && a > 10) {
    t.push(q+++':' + r + '\n');
    if (q > 6) {
        t.shift()
    }
    f(r, c - 1);
 }
 console.log(t.join(',').replace(/,/g, ''))
}

Edit 1: Removed ternary

Edit 2: Flipped logic for "skipping" 0 index

Edit 3: Reworked recursive calling.

Fiddle

\$\endgroup\$
1
  • \$\begingroup\$ Don't worry, nothing to see here. Thought it was printing first 5 but it should with your fiddle. Nice work :) \$\endgroup\$
    – Matt
    May 20, 2014 at 4:10
2
\$\begingroup\$

Bash + coreutils, 115 bytes

for((a=$1;++i<=$2&a>9;)){
a=`paste -d+ <(fold -1<<<${a%?}) <(fold -1<<<${a#?})|bc|tr -d '
'`
echo $i: $a
}|tail -n5

Output:

$ ./appended-number.sh 3541 50
6: 1411
7: 552
8: 107
9: 17
10: 8
$ ./appended-number.sh 3541 5
1: 895
2: 1714
3: 885
4: 1613
5: 774
$ 
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ECMAScript 6 Draft) - 134 Characters

f=(x,y,i=0,j=[])=>([m=''].map.call(m+x,(z,p,n)=>m+=p?+z+1*n[p-1]:m),j[i++]=i+': '+m,m.length>1&&i<y?f(m,y,i,j):j.slice(-5).join('\n'))

Examples:

f(372,5)
"1: 109
2: 19
3: 10
4: 1"

f(3541,50)
"6: 1411
7: 552
8: 107
9: 17
10: 8"

f(3541,5)
"1: 895
2: 1714
3: 885
4: 1613
5: 774"
\$\endgroup\$
2
\$\begingroup\$

Husk, 32 bytes

↑_5Ṡz+(mo`+": "sŀ)mṁs↑htU¡oṁdẊ+d

Try it online!

Output format was cumbersome, but I had to answer this in Husk.

Explanation

↑_5Ṡz+(mo`+": "sŀ)mṁs↑htU¡oṁdẊ+d
                               d convert first input to digits
                         ¡       and iterate:
                             Ẋ+  sum overlapping pairs
                           ṁd    convert to digits and flatten
                        U        truncate till fixed point
                      ht         remove first and last element
                     ↑           take second input number of values from that
                  mṁs            convert all the arrays to strings
   Ṡz+(          )               zip and concat that with:
                ŀ                range 1..length(seq)
       mo`+": "s                 convert each to string, append a colon
↑_5                              take the last 5 elements
\$\endgroup\$
1
\$\begingroup\$

Javascript, 182 bytes

function f(I,T){s=[],x=1;for(;;){d=(""+I).split("");l=d.length;if(l==1||x>T)break;for(I="",i=1;i<l;)I+=+d[i-1]+ +d[i++];s.push(x+++": "+I)}s=s.slice(-5);for(i in s)console.log(s[i])}
\$\endgroup\$
1
\$\begingroup\$

Perl, 166 147 138 129 bytes

<>=~/ /;for$i(1..$'){@n=split'',$s||$`;$s=join'',map{$n[$_]+$n[$_+1]}0..@n-2;@o=(@o,"$i: $s");$s<10&&last}print join$/,@o[-5..-1]

Ungolfed:

<> =~ / /;
for $i (1..$') {
    @n = split'', $s||$`;
    $s = join'',map {$n[$_]+$n[$_+1]} 0..@n-2;
    @o = (@o, "$i: $s");
    $s<10 && last
}
print join$/,@o[-5..-1]

I hope it's alright that it prints some extra empty lines if the whole thing takes less than 5 steps.

\$\endgroup\$
3
  • \$\begingroup\$ Replace (('')x5, @o, "$i: $s") with (@o, "$i: $s") and join"\n", @o[-5..0] with join"\n", @o[-5..-1]. Then you'll be 3 bytes ahead ;) \$\endgroup\$
    – core1024
    May 20, 2014 at 13:07
  • \$\begingroup\$ I don't have any problem with extra empty lines. \$\endgroup\$
    – Matt
    May 20, 2014 at 13:26
  • \$\begingroup\$ @core1024 Thanks :) I was going to give you a tip as well, but you already got rid of that long "unless" part \$\endgroup\$
    – Tal
    May 20, 2014 at 13:41
1
\$\begingroup\$

Java     524  405 365 chars [414 bytes]

Golfed version: class A{static int n=0;List<String> s=new ArrayList<>();void c(int b,int r){String d=b+"";if(r==0||b <= 9){int m=s.size();for(int i= m>=5?m-5:0;i<m;i++)System.out.println(s.get(i));return;}String l="";for(int i=0;i<d.length()-1;i++)l+=d.charAt(i)+d.charAt(i+1)-96;s.add(++n+":"+l);c(Integer.valueOf(l),--r);}public static void main(String[] a){new A().c(3541,50);}}

Readable version:

class AddDigits {
static int n = 0;
List<String> steps = new ArrayList<>();

void count(int num, int count) {
    String digits = num + "";
    if (count == 0 || num <= 9) {
        int stepsSize = steps.size();
        for (int i = stepsSize >= 5 ? stepsSize - 5 : 0; i < stepsSize; i++) {
            System.out.println(steps.get(i));
        }
        return;
    }
    String line = "";
    for (int i = 0; i < digits.length() - 1; i++) {
        line += digits.charAt(i) + digits.charAt(i + 1) - 96;
    }
    steps.add(++n + ":" + line);
    count(Integer.valueOf(line), --count);
}

public static void main(String[] args) {
    new AddDigits().count(3541, 50);
}
}
\$\endgroup\$
6
  • \$\begingroup\$ You can shrink this by using 1 char for variable and function names. \$\endgroup\$
    – Lex Webb
    May 20, 2014 at 12:22
  • \$\begingroup\$ Done... also changed logic to stop recursion using num<=9 instead of digits.length==1 (Seen in this thread only... didn't hit me before). \$\endgroup\$
    – user12345
    May 20, 2014 at 13:43
  • \$\begingroup\$ you could reduce length of argument name in yout main method, that will give you additional 3 chatacters \$\endgroup\$
    – user902383
    May 21, 2014 at 14:57
  • \$\begingroup\$ you dont need to converting string to array of characters, you can access single character from string using chatAt method \$\endgroup\$
    – user902383
    May 21, 2014 at 15:01
  • 1
    \$\begingroup\$ and last thing, you dont need to convert your character to string and then parse it, instead Integer.valueOf(digits[i] + "") + Integer.valueOf(digits[i + 1] + ""); you could do (digits[i] + digits[i+1] - 96) \$\endgroup\$
    – user902383
    May 21, 2014 at 15:04
1
\$\begingroup\$

JavaScript 133 bytes

function f(n,g){for(c=r=[];g--;(n=s)&&(r[c++]=c+': '+s))for(i=s='',n+=s;n[++i];s+=n[i]-+-n[i-1]);console.log(r.slice(-5).join('\n'))}

Ungolfed:

function sums(num, guard) {
    for(count = res = [];guard--;(num = sum) && (res[count++] = count + ': ' + sum))
        for(i = sum = '',num += sum;num[++i];sum += num[i] -+- num[i-1]);
    console.log(res.slice(-5).join('\n'))
}
\$\endgroup\$
2
  • \$\begingroup\$ Only problem is the function name is the same as one of your variables :) But the technique is awesome. \$\endgroup\$
    – Matt
    May 22, 2014 at 14:33
  • \$\begingroup\$ Good point! I renamed the function ;) \$\endgroup\$
    – core1024
    May 22, 2014 at 14:52
1
\$\begingroup\$

Java, 341 chars 371 chars

 class a{public static void main(String[] a){p(3541,50);}static void p(int n,int k){Queue<String>q=new LinkedList();int c=0;while(n>9&&c<k){c++;String r="";String p=""+n;for(int i=0;i<p.length()-1;i++)r+=((p.charAt(i)+p.charAt(i+1)-96));n=Integer.parseInt(r);q.add(c+": "+n);if(q.size()>5)q.remove();}for(String s:q){System.out.println(s);}}}

Formatted:

class a {
public static void main(String[] a) {
    p(3541, 50);
}

static void p(int n, int k) {
    Queue<String> q = new LinkedList();
    int c = 0;
    while (n > 9 && c < k) {
        c++;
        String r = "";
        String p = "" + n;
        for (int i = 0; i < p.length() - 1; i++)
            r += ((p.charAt(i) + p.charAt(i + 1) - 96));
        n = Integer.parseInt(r);
        q.add(c + ": " + n);
        if (q.size() > 5)
            q.remove();
    }
    for (String s : q) {
        System.out.println(s);
    }
}}

Thanks to user902383 i was able to reduce the code by 30 chars, by not splitting the String into an Array an using -96 instead of "Integer.valueOf()

\$\endgroup\$
1
  • \$\begingroup\$ you could still reduce some characters, class a{public static void main(String[] a) {p(3541, 50);}static void p(int n,int k){Queue<String> q=new LinkedList();int c=0;while(n>9&&c<k){c++;String r="";String p=""+n;for(int i=0;i<p.length()-1;i++)r+=((p.charAt(i)+p.charAt(i+1)-96));n=Integer.parseInt(r);q.add(c+": "+n);if(q.size()>5)q.remove();}for(String s:q){System.out.println(s);}}} \$\endgroup\$
    – user902383
    May 21, 2014 at 14:49
0
\$\begingroup\$

Dart, 602 588 bytes

Dart is probably one of the worst languages to do this in... I'll need to find a better way to do this.

Anyway, Here's my entry:

Input through console

var steps={};void main(a){c(a[0],int.parse(a[1]));}void c(inp,m){int i=0;int n=int.parse(inp);while(++i<=m){n=addUp(n.toString());steps[i]=n;if(n<10)break;}printSteps();}int addUp(n){var ns=[];for(int i=0;i<n.length;i++){try{ns.add(n[i]+n[i+1]);}catch(e){}}return addNumbers(ns);}int addNumbers(ns){var it=ns.iterator;var s="";while(it.moveNext()){int i=0;for(var t in it.current.split('')){i+=int.parse(t);}s=s+i.toString();}return int.parse(s);}void printSteps(){int l=steps.length;for(int i=getStart(l);i<=l;i++){print("${i}:\t${steps[i]}");}}int getStart(l){int m=l-4;return m>0?m:1;}

And the ungolfed, slightly unminified version:

var steps = {};

void main(a)
{
    c(a[0], int.parse(a[1]));
}

void c(String input, int max)
{
    int i = 0;
    int n = int.parse(input);

    while(++i <= max)
    {
        n = addUp(n.toString());

        steps[i] = n;

        if(n < 10)
            break;
    }

    printSteps();
}

int addUp(String n)
{
    List numbers = [];

    for(int i = 0; i < n.length; i++)
    {
        try
        {
            numbers.add(n[i] + n[i + 1]);
        }
        catch(e){}
    }

    return addNumbers(numbers);
}

int addNumbers(List numbers)
{
    Iterator it = numbers.iterator;

    String s = "";

    while(it.moveNext())
    {
        int i = 0;
        for(String s in it.current.split(''))
        {
            i += int.parse(s);
        }

        s = s + i.toString();
    }

    return int.parse(s);
}

void printSteps()
{
    int l = steps.length;

    for(int i = getStart(l); i <= l; i++)
    {        
        print("${i}:\t${steps[i]}");
    } 
}

int getStart(int l)
{
    int m = l - 4;
    return m > 0 ? m : 1;
}
\$\endgroup\$
0
\$\begingroup\$

PERL 135 129/125 125/121 bytes

It has the same bug as Tal's answer

sub c{($e,$l)=@_;print join"\n",(grep/\d$/,map{$s="";{$e=~/(.)(.)/;redo if""ne($e=$2.$')and$s.=$1+$2};++$c.": ".($e=$s)}1..$l)[-5..-1]}

Edit 129 bytes as a function:

sub c{($e,$l)=@_;print join$/,(grep/\d$/,map{$s="";{$e=~/(.)(.)/;redo if""ne($e=$2.$')and$s.=$1+$2}"$_: ".($e=$s)}1..$l)[-5..-1]}

125 bytes as a function:

sub c{($e,$l)=@_;print+(grep/\d$/,map{$s="";{$e=~/(.)(.)/;redo if""ne($e=$2.$')and$s.=$1+$2}"$_: ".($e=$s).$/}1..$l)[-5..-1]}

125 bytes as a console script (without the hashbang):

($e,$l)=@ARGV;print join$/,(grep/\d$/,map{$s="";{$e=~/(.)(.)/;redo if""ne($e=$2.$')and$s.=$1+$2}"$_: ".($e=$s)}1..$l)[-5..-1]

121 bytes as a console script (without the hashbang):

($e,$l)=@ARGV;print+(grep/\d$/,map{$s="";{$e=~/(.)(.)/;redo if""ne($e=$2.$')and$s.=$1+$2}"$_: ".($e=$s).$/}1..$l)[-5..-1]

Expanded:

sub c
{
    ($e, $l) = @_;
    print +(grep /\d$/, map {
        $s="";
        {
            $e =~ /(.)(.)/;
            redo if "" ne ($e = $2.$') and $s .= $1 + $2
        }
        "$_: ".($e = $s).$/
    } 1 .. $l)[-5 .. -1]
}

Test with c(372,4);:

[blank line]
1: 109
2: 19
3: 10
4: 1

Test with c(3541,50);:

6: 1411
7: 552
8: 107
9: 17
10: 8
\$\endgroup\$
4
  • \$\begingroup\$ I believe you're only supposed to print the last 5 steps though. \$\endgroup\$
    – Tal
    May 20, 2014 at 11:24
  • \$\begingroup\$ Got it fixed ;) \$\endgroup\$
    – core1024
    May 20, 2014 at 12:45
  • \$\begingroup\$ And you're still 3 bytes ahead of me... blast it! :p \$\endgroup\$
    – Tal
    May 20, 2014 at 12:50
  • \$\begingroup\$ @Tal We're even now :D \$\endgroup\$
    – core1024
    May 20, 2014 at 14:18
0
\$\begingroup\$

C# - 269

void F(int x,int y){var o=new List<string>();var i=x+"";for(int n=1;n<y&&i.Length>1;n++){var s="";for(int z=0;z<i.Length;z++){int a=i[z]-'0';var t=a+(z+1!=i.Length?i[z+1]-'0':-a);if(t!=0)s+=t;}i=s;o.Add(n+": "+i);}foreach(var p in o.Skip(o.Count-5))Debug.WriteLine(p);}

Readable:

void F(int x,int y){
    var o=new List<string>();
    var i=x+"";
    for(int n=1;n<y&&i.Length>1;n++)
    {
        var s="";
        for(int z=0;z<i.Length;z++){
            int a=i[z]-'0';
            var t=a+(z+1!=i.Length?i[z+1]-'0':-a);
            if(t!=0)
                s+=t;
        }
        i=s;
        o.Add(n+": "+i);
    }
    //Output
    foreach(var p in o.Skip(o.Count-5))
        Debug.WriteLine(p);
}

Usage:

F(3541, 50)

Output:

6: 1411
7: 552
8: 107
9: 17
10: 8
\$\endgroup\$
0
\$\begingroup\$

Cobra - 363

A rather depressing result... but hey, I still beat Java.

It should be immune to integer overflows for practical test cases.

class P
    cue init(a,b)
        base.init
        l=[]
        c=.p(a.toString)
        for x in b
            l.add("")
            y=l.count
            for i in c.count-1,l[y-1]+=(c[i]+c[i+1]).toString
            if l.last.length<2,break
            c=.p(l.last)
        z=if(y>5,y-5,0)
        for x in l[z:y],print"[z+=1]:",x
    def p(n) as List<of int>
        c=List<of int>()
        for i in n,c.add(int.parse(i.toString))
        return c
\$\endgroup\$
0
\$\begingroup\$

Python 2.7, 174 173 158 characters

Using a lot of strings to do the task.

x,n=raw_input().split()
o,i=[],0
while int(n)>i<o>9<x:x="".join(`sum(map(int,x[j:j+2]))`for j in range(len(x)-1));i+=1;o+=[`i`+": "+x]
print"\n".join(o[-5:])

Python 2.7, 155 characters

Version defining a function

def a(x,n):
 o,i,x=[],0,`x`
 while n>i<o>9<int(x):x="".join(`sum(map(int,x[j:j+2]))`for j in range(len(x)-1));i+=1;o+=[`i`+": "+x]
 print"\n".join(o[-5:])

Slightly ungolfed version:

x,n=map(int,raw_input().split())
o,i=[],1
while i<=n and x>9:
  x=int("".join(`sum(map(int,`x`[j:j+2]))` for j in range(len(`x`)-1)))
  o.append("%d: %d"%(i,x))
  i+=1
print "\n".join(o[-5:])
\$\endgroup\$
0
\$\begingroup\$

Haskell, 154

s=show
z=zipWith
m#n=concat.z(\a b->s a++": "++b++"\n")[1..].(\x->drop(length x-n)x).takeWhile(/="").iterate((\x->z(+)x(tail x)>>=s).map(\x->read[x]))$s m

example usage:

λ> 3541#5
"1: 1411\n2: 552\n3: 107\n4: 17\n5: 8\n"

To make it more readable, use putStr:

λ> putStr $ 3541#5
1: 1411
2: 552
3: 107
4: 17
5: 8
\$\endgroup\$
2
  • \$\begingroup\$ You have to list only the last 5 steps out of the computation. Try putStr $ 3541#50 and compare it with the OP's example. Otherwise I'm glad there's a Haskell guy here. \$\endgroup\$
    – core1024
    May 22, 2014 at 17:04
  • \$\begingroup\$ @core1024 It does! Athough I did label them wrong, you're right. I'll fix that tomorrow. \$\endgroup\$
    – Flonk
    May 27, 2014 at 11:29
0
\$\begingroup\$

Groovy - 191 182 chars

Based on Thomas Rüping's solution, ported to Groovy 2.2.1:

f={it as int};n=args[0];s=f args[1];q=[];x=0;while(f(n)>9&&x<s){x++;d=n.split("");n="";for(i in 1..d.length-2)n+=f(d[i])+f(d[i+1]);q << "$x: $n"};q[-1..5].reverse().each{println it}

Execution and output:

bash$ groovy Numbers.groovy 3541 50 
6: 1411
7: 552
8: 107
9: 17
10: 8

Ungolfed:

f = {it as int}
n = args[0]
s = f args[1]

queue = []
stepCounter = 0

while (f(n) > 9 && stepCounter < s) {
    stepCounter++
    digits=n.split("")
    n=""
    for(i in 1..digits.length-2) {
        n += f(digits[i]) + f(digits[i+1])
    }
    queue << "$stepCounter: $n"
}

queue[-1..5].reverse().each{ println it }
\$\endgroup\$
0
\$\begingroup\$

**C 186 179174 **

f(int a,int z){for(int c,d,i,j=0,m[5];m[j++%5]=a,j<=z&&a/10;a=c)for(c=0,i=1;a/10;d=a%10+(a/=10)%10,c+=d*i,i*=d<10?10:100);for(i=j<5?0:j-5;i<j;printf("%d: %d\n",i,m[i++%5]));}

Slightly less golfed (mini-golfed?)

f(int a, int z)
{


for(int c,d,i,j=0,m[5];m[j++%5]=a,j<=z&&a/10;a=c)
    for(c=0,i=1;a/10;d=a%10+(a/=10)%10,c+=d*i,i*=d<10?10:100);

    for(i=j<5?0:j-5;i<j;printf("%d: %d\n",i,m[i++%5]));

}

Just allocate enough memory to store five results cyclically. The outer loop keeps going until we hit the limit or reach a single digit. The inner loop adds the last digit of the number to last digit of 1/10 of the number and adds this, multiplied by the relevant power of 10 to the result. Divide the number you first though of by 10 and repeat to get the total. Then print out up to the last five results.

Next challenge is to see if I can shave off enough to beat some scripting languages at golf.

Edit: Now compiles with warning but five characters shaved off by removing "void " declaration

\$\endgroup\$
1
  • \$\begingroup\$ Golf tips: f(int a, int z) -> f (a,z) and could use t=10 saving 2 more chars. But using a and a/=10 in the same expression is undefined \$\endgroup\$
    – edc65
    May 23, 2014 at 7:54
0
\$\begingroup\$

C# - 309 330 320 306 Bytes

Golfed Version:

private static void F(int aN,int aM){var s=new List<string>();var n=aN.ToString();for(int i=1;i<=aM;i++){int z=n.Length;if(z==1){break;}var a=n;n="";for(int j=0;j<z-1;j++){int r=a[j]-'0'+a[j + 1]-'0';n=n+r;}s.Add(i+": "+n);}int l=s.Count;int p=5;if(l<5){p=l;}for(int k=l-p;k<l;k++){Debug.WriteLine(s[k]);}}

Usage: F(3541,50);

Ungolfed version for readability:

private static void AppendNumbers(int aNum, int aMaxSteps)
    {
        var results = new List<string>();
        var numString = aNum.ToString();
        for (int i = 1; i <= aMaxSteps; i++)
        {
            int stringLength = numString.Length;
            if (stringLength == 1)
            {
                break;
            }
            var a = numString;
            numString = "";
            for (int j = 0; j < stringLength-1; j++)
            {
                int additionResult = a[j]-'0' + (a[j + 1]-'0');
                numString = numString + additionResult;
            }
            results.Add(i+": "+ numString);
        }
        int numberOfResults = results.Count;
        int p = 5;
        if (numberOfResults < 5)
        {
            p = numberOfResults;
        }
        for (int k = numberOfResults - p; k < numberOfResults; k++)
        {
            Debug.WriteLine(results[k]);
        }
    }

Suggestions for improvement are always welcome! ;)

Edit: Removed String.Empty and replaced it with "" to save 10 Bytes.

Edit 2: Thanks to malik for the tipp with the strings!

\$\endgroup\$
2
  • \$\begingroup\$ You dont need .ToCharArray(). A string = char array \$\endgroup\$
    – mnsr
    May 21, 2014 at 0:40
  • \$\begingroup\$ Oh, and another thing you can do is, instead of .ToString(), do +"" \$\endgroup\$
    – mnsr
    May 23, 2014 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.