24
\$\begingroup\$

Welcome to the grinder.

Your task is to make big rocks into small rocks by grinding them.

Take an input of a big rock of size n > 3 and grind it.

Continue to grind the rocks by dumping them into the grinder until the size of all the rocks are 2.

rocks are always grinded into equal even halves. If the result of a grinding is odd take result - 1.

Print the output of each grinding as you proceed.

Examples

input: 5

output: 22

The result are two rocks of size 2

input: 50

output:

2424 //two rocks of size 24
12121212 //four rocks of size 12
66666666 //8 rocks of size 6
2222222222222222

the result is 16 rocks of size 2

input: 30

output:

1414
6666
22222222

the result is 8 rocks of size 2

This is so the shortest code wins! Have fun and good luck!

\$\endgroup\$
10
  • \$\begingroup\$ You can expect it to be above 3. \$\endgroup\$ Dec 2, 2016 at 13:33
  • \$\begingroup\$ Do we have to use your format (all numbers concatenated) or can we use things like lists? Some answers seem to do that instead. \$\endgroup\$
    – Fatalize
    Dec 2, 2016 at 14:01
  • \$\begingroup\$ As long as the output displays each iteration the format does not need to be like above. \$\endgroup\$ Dec 2, 2016 at 14:03
  • 1
    \$\begingroup\$ I would say a 2d array does and a 1d does not , but it's up to you so OK. \$\endgroup\$ Dec 2, 2016 at 14:15
  • 1
    \$\begingroup\$ @user902383 either is fine unless specified in the challenge as per meta consensus. As for input and output, again both are fine - see this post. \$\endgroup\$ Dec 2, 2016 at 20:17

24 Answers 24

12
\$\begingroup\$

TSQL, 61 59 bytes

DECLARE @ int=50

,@x int=1WHILE @>2SELECT @=@/4*2,@x*=2PRINT replicate(@,@x)

Try it out

\$\endgroup\$
8
\$\begingroup\$

COW, 297 291 bytes

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Try it online!

The code prints each number on its own line, and separates iterations with an additional newline. It also prints the first iteration by itself, followed by a newline. So an input of 5 would give an output that looks like 5 2 2 except with newlines instead of spaces. Sample output for 50 is given below.

Explanation tree:

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoom ;Store 10 in [0], 1 in [1], and integer input in [3]
mOoMoO                                        ;Store 1 in [2]
MOO                                           ;Loop while [2] is non-zero
   moOMMMmoOMMMmoOOOOMoOmOo                   ;   Copy [3] to [4], clear contents of [5], and store 1 in [5]
   MOO                                        ;   Loop while [4] is non-zero
      MOomoOmoO                               ;      Decrement 4 and move to 6
      MOO                                     ;      Loop while [6] is non-zero
         MOomOoMOomoO                         ;         Decrement [5] and [6]
      moo                                     ;      End loop once [6] is empty
      mOoMMMOOOMoOmoOMMMmOomOo                ;      Copy [5] to [6], and reset [5] to 1, then move back to [4]
   moo                                        ;   End loop now that [4] is empty.  [6] now contains the parity of [3]
   moOmoO                                     ;   Navigate to [6]
   MOO                                        ;   Loop while [6] is non-empty
      MOomOomOomOoMOomoOmoOmoO                ;      Decrememnt [3] and [6]
   moo                                        ;   End loop now that [6] is empty.  [3] now contains the largest even number less than the previous iteration.
   mOomOomOomOomOoMMMmoOMMM                   ;   Copy [1] to [2]
   MOO                                        ;   Loop while [2] is non-empty
      MOomoOOOMmOomOoMoOmoO                   ;      Decrement [2], increment [1], and print the number in [3].
   moo                                        ;   End loop now that [2] is empty
   mOomOoMoo                                  ;   Print a new line
   moOmoOmoO                                  ;   Navigate to [3]
   MOO                                        ;   Loop while [3] is non-empty
      MOoMOomoOMoOmOo                         ;      Decrement [3] twice and increment [4] once
   moo                                        ;   [4] now contains half of [3]
   moOMMMOOOmOoMMM                            ;   Copy [4] to [3] and clear [4]
   MMMmOoMMMMOo                               ;   Copy [3] to [2] and decrement once
moo                                           ;End loop now that [2] is empty

Sample output for input 50:

50

24
24

12
12
12
12

6
6
6
6
6
6
6
6

2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
\$\endgroup\$
4
  • 2
    \$\begingroup\$ I have no words \$\endgroup\$ Dec 5, 2016 at 12:11
  • \$\begingroup\$ I still have no words \$\endgroup\$ Dec 19, 2016 at 12:15
  • \$\begingroup\$ I don't have any words \$\endgroup\$
    – Edeki Okoh
    May 9, 2019 at 23:45
  • \$\begingroup\$ I love how two and a half years later, this still horrifies people. \$\endgroup\$ May 11, 2019 at 0:08
7
\$\begingroup\$

05AB1E, 12 11 bytes

¸[4÷·€D=¬<#

Try it online!

Explanation

¸             # wrap input in a list
 [            # start infinite loop
  4÷          # elementwise integer divison by 4
    ·         # elementwise multiplication by 2
     €D       # duplicate each element in the list
       =      # print it
        ¬     # get the first element of the list
         <    # decrease it by 1
          #   # if true: exit loop
\$\endgroup\$
6
\$\begingroup\$

Python 2, 55 53 bytes

n=input()
while n[0]>2:n=len(n)*2*[n[0]/4<<1];print n

Divide by 4 and left shift by 1 to get the special division

\$\endgroup\$
0
4
\$\begingroup\$

Haskell, 75 71 60 50 47 bytes

f 0=[]
f n|x<-f$2*div n 4=show n:zipWith(++)x x

Try it online! Edit: As the output is now allowed to be a list including the input, 10 13 bytes can be saved.

Usage:

Prelude> f 50
["50","2424","12121212","66666666","2222222222222222"]

Original 60 byte version:

2%x=""
n%x|z<-2*div n 4=([1..x]>>show z)++"\n"++z%(x*2)
(%2)

Try it online! Thanks to Christian Sievers for pointing out the shorter formula.

Usage:

Prelude> (%2)50
"2424\n12121212\n66666666\n2222222222222222\n"
\$\endgroup\$
1
  • \$\begingroup\$ You can just do z<-2*div n 4. \$\endgroup\$ Dec 2, 2016 at 17:00
3
\$\begingroup\$

JavaScript (ES6) 64 59 57 Bytes

f=s=>{for(n=1;s>2;)console.log(`${s=s/4<<1}`.repeat(n*=2))}

console.log(f.toString().length); 
f(5);
f(50);
f(30);                                  

\$\endgroup\$
3
  • \$\begingroup\$ if I put your code into mothereff.in/byte-counter I get 59 bytes? \$\endgroup\$ Dec 3, 2016 at 9:40
  • \$\begingroup\$ @Tschallacka I think the f= but is just for the demo \$\endgroup\$
    – LarsW
    Dec 3, 2016 at 11:58
  • \$\begingroup\$ Ah, okay. That makes it clear :-) still gotta get 2 bytes off myne then \$\endgroup\$ Dec 3, 2016 at 12:19
3
\$\begingroup\$

Python 2, 48 47 bytes

s=input()
n=1
while s>3:s=s/4*2;n*=2;print`s`*n
\$\endgroup\$
1
  • \$\begingroup\$ s=s/4*2 will work for 1 byte save. \$\endgroup\$ Dec 2, 2016 at 13:50
3
\$\begingroup\$

Java, 85 bytes

n->{String s="";for(int q=2,i;n>2;q*=2,s+="\n")for(i=q,n=n/4*2;i-->0;)s+=n;return s;}

Testing and ungolfed

import java.util.function.*;

class Ideone {
  public static void main(String[] args) throws java.lang.Exception {
    Function<Integer, String> f = number -> {
      String result = "";
      for (int quantity = 2, i; number > 2; quantity *= 2) {
        number = number / 4 * 2; // Make sure that the next is half or half - 1 if odd
        for (i = quantity; i > 0; i--) { // copy "quantity" times.
          result += number;
        }
        result += "\n"; // append new line
      }
      return result;
    };
    System.out.println(f.apply(50));
  }
}

Note: I don't know why, Ideone keeps giving internal error, so testing on it is a problem. To test, just copy/paste and run in your standard Java IDE. (It works there, I made sure of it ;) )

\$\endgroup\$
1
  • \$\begingroup\$ ideone works fine with your code. It's somtimes giving an internal error when they are doing maintenance (I think). I've had it before when I looked back at old answers of mine. +1 btw, I don't see anything that can be golfed more. Oh, and I like your n=n/4*2 trick. :) \$\endgroup\$ Dec 14, 2016 at 11:44
3
\$\begingroup\$

C#, 88 86 83 bytes

Saved 3 bytes thanks to Skorm

Saved another byte by changing the while to a for loop which includes variable declarations

Saved 1 bytes thanks to Yodle

n=>{var r="";for(int i,c=2;n>2;c*=2,r+="\n")for(i=0,n=n/4*2;i++<c;)r+=n;return r;};

Anonymous function which returns a string composed of the result of each grinding.

Full program with ungolfed method and test cases [before the last edit!]:

using System;
                    
public class Program
{
    public static void Main()
    {
        Func<int, string> f =
        n =>
        {
            var r = "";
            for (int i, c = 1; n > 2; )  // iterator and counter variable
            {
                    n = n/4 * 2;    // make sure the result if even
                    c *= 2;         // keep track of the number of rocks
                    for (i = 0; i++ < c; )  // store the current line made of [c] rocks of size [n]
                        r += n;
                    r += "\n";      // add a trailing newline to the string resulted from this step
            }
            return r;       // return the entire history
        };
            
        //test cases:
        Console.WriteLine(f(5));
        Console.WriteLine(f(50));
        Console.WriteLine(f(30));
    }
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Think you can save 1 byte in the for loop by doing for(i=0;i++<c;) \$\endgroup\$
    – Yodle
    Dec 2, 2016 at 15:03
  • \$\begingroup\$ You can still save 1 byte, as yoddle mentioned by changing your second for to for (i = 0; i++ < c;) \$\endgroup\$
    – MX D
    Dec 2, 2016 at 15:54
  • \$\begingroup\$ Forgot to update the post. Updated now :) \$\endgroup\$
    – adrianmp
    Dec 2, 2016 at 16:02
  • 1
    \$\begingroup\$ You can update your counter to start at 2 and *=2 each iteration to save 1 byte, and move the new line append. You can then move the n = n / 4 * 2 into the second loop and remove the braces to save 2 more. n=>{var r="";for(int i,c=2;n>2;c*=2,r+="\n")for(i=0,n=n/4*2;i++<c;)r+=n;return r;} \$\endgroup\$
    – Skorm
    Dec 2, 2016 at 17:05
2
\$\begingroup\$

CJam, 21 bytes

l~]{{2/-2&_}%_n_2-}g;

Try it online! (As a test suite.)

Explanation

l~]      e# Read input, evaluate and wrap it in a singleton list.
{        e# Do while...
  {      e#   Map this block over the list of rocks.
    2/   e#   Halve the rock.
    -2&  e#   Bitwise AND with -2, clearing the least-significant bit and
         e#   rounding down to an even integer.
    _    e#   Duplicate.
  }%
  _n     e# Print a copy of the current list of rocks.
  _2-    e# Continue if the current list of rocks contains values that aren't 2.
}g
;        e# Discard the final result to prevent printing it again.
\$\endgroup\$
2
\$\begingroup\$

Pyth, 18 16 13 bytes

WhQ=Q*2my/d4\n

* \n is a new line
Explanation :

W              # While
 hQ            # first element of Q - 0 is falsy
   =Q          # assign to Q
     *2        # the double of the (list) that is returned
       m       # form this \/ map
         /d4   # divide every element by 4
        y      # and double
            \n # print Q

Try here

\$\endgroup\$
2
\$\begingroup\$

MATL, 13 bytes

`K/kEthttH>]x

Try it online!

`       % Do...while
  K/k   %   Divide by 4 and round down. Takes input implicitly in the first iteration
  E     %   Multiply by 2
  th    %   Attach a copy of itself (creates a longer array)
  t     %   Duplicate. This copy will be used for further grinding, keeping the original
  tH>   %   Duplicate. True if the values exceed 2. Used as loop condition
]       % End. The loop exits if the latest array contains 2
x       % Delete last copy. Implicitly display the entire stack
\$\endgroup\$
2
\$\begingroup\$

PHP, 72 67 64 bytes

for($n=$argv[$k=1];$n>2;)echo str_repeat($n=$n/2&~1,$k*=2),"\n";

Takes argument from command line. Run with -r.

\$\endgroup\$
2
\$\begingroup\$

Jelly, 13 12 11 bytes

:4Ḥx2µȦпṖY

TryItOnline!

Note: the OP stated that the input may also be in the output.

How?

:4Ḥx2µȦпṖY - Main link: rockSize
     µ      - monadic separation
       п   - loop collect intermediate results while
      Ȧ     - any
:4          -     integer division (vectorises) by 4
  Ḥ         -     double (vectorises)
   x2       -     repeat the elements 2 times
         Ṗ  - pop (remove the trailing list of zeros)
          Y - join with line feeds

Version without the input displayed for 12 bytes: :4Ḥḟ0x2µÐĿḊG

\$\endgroup\$
2
\$\begingroup\$

Perl, 40 35 30 + 1 = 31 bytes

Run with the -n flag

-4 bytes thanks to @Dada

say$_ x($.*=2)while$_=$_>>1&~1

Try it online!

Perl automatically reads the input into the variable $_ when -n is set. $. is a special variable set to 1 at the beginning of the program by the interpreter, so I can use it as a base for doubling. Every iteration of the while loop, it bit-shifts $_ down and performs a logical AND against the negative of itself minus one to cancel out the ones bit.

\$\endgroup\$
1
  • \$\begingroup\$ You can golf it down to 31 bytes : perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1' (maybe this can be golfed even further, I didn't spent a lot of time on it). \$\endgroup\$
    – Dada
    Dec 2, 2016 at 19:04
2
\$\begingroup\$

PowerShell 3+, 58 54 bytes

for($s=$input;$s;$s=($s-shr2)*2){"$s"*(2-shl($i++)-1)}

Thanks TimmyD for saving me 4 bytes!

Slightly Ungolfed (formatting)

for ( $s = $input ; $s ; $s = ( $s -shr 2 ) * 2 ) {
    "$s" * (2 -shl ($i++)-1)
}

Explanation

I'm using the same divide by 4 multiply by 2 trick as a lot of the other answers, but I ran into a problem. PowerShell converts numbers to floating point if needed during division, and for golfing that's annoying because $v/4*2 becomes something unsighlty like [int]($v/4)*2. I got around that using bitshifting for the division with -shr.

For calculating how many times to print an iteration I just take (2^$i)-1 which works nicely and has the added effect of leaving out the input value. Trying to just multiply by 2 was problematic because starting from 0 makes it hard to increase the value with just $i*=2 and starting from 1 requires too much correction to get the number right.

Since PowerShell doesn't have an operator for it, and I wanted to avoid [Math]::Pow(), I relied on bitshifting again for my powers of 2.

\$\endgroup\$
1
  • \$\begingroup\$ @TimmyD whoops forgot to mention version, and good tip; thanks! \$\endgroup\$
    – briantist
    Dec 5, 2016 at 19:35
1
\$\begingroup\$

Python 2, 47 Bytes

Since the OP said that a 1D array which included the input was fine I have come up with this recursive function, which unfortunately only ties with the current Python winner.

f=lambda s,n=1:[s]*n+(f(s/4*2,n*2)if s>3else[])
\$\endgroup\$
1
  • \$\begingroup\$ f=lambda r,n=1:[r]*n+(r>3and f(r/4*2,n*2)or[]) for 46 \$\endgroup\$ Dec 2, 2016 at 20:09
1
\$\begingroup\$

Perl, 47 bytes

$a=<>>>1;say 2*(($a>>=1)||die)x(1<<$_)for 1..$a

No command-line options, this time (unusually for Perl). The basic idea is that as all the rocks at any given step are the same size, we just record the size (in $a) and the number (in $_), rather than recording the whole list. I couldn't find a way to get rid of the space (or +) after say ; you can move the 2* but it won't parse correctly if it's followed by an opening parenthesis.

I can't help but shake the feeling that this is improvable, but I can't see how.

\$\endgroup\$
4
  • \$\begingroup\$ If I try to golf it to much, I end up with Gabriel Benamy's answer every time. Just to show a few steps: the die clearly feels sub-optimal. But we still need a way to check if we need to stop or not -> a solution is to use a while instead of the for: while$a>1. But we need to find a replacement for $_: any unitialized variable can do it: replace 1<<$_ by 1<<++$x. So now $_ is free to be used, we can then use -n and replace every $a with a $_, and the first instruction becomes $_>>=1. Since we have -n, $. is set, so we can replace 1<<++$l with $.*=2. \$\endgroup\$
    – Dada
    Dec 2, 2016 at 22:17
  • \$\begingroup\$ Doing all those modifications will produce perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1' (39 bytes). Then notice that $_>>=1 is done twice, so we can try to get rid of one (the first one). Trying to get rid of it, I got say$_ x($.*=2)while($_>>=1)/2>1 (put both of them inside the while condition). But the result is wrong ($_ can be odd), and trying to make sure it's even, I end up with while$_=$_>>1&~1. So the code is now say$_ x($.*=2)while($_=$_>>1&~1). \$\endgroup\$
    – Dada
    Dec 2, 2016 at 22:18
  • \$\begingroup\$ I missed that there was a Perl answer already. I guess if golfing this down turns it into a duplicate, there's not much point in editing it. On the other hand, it's not actually wrong, so there's not much point in deleting it either. We're probably best off just leaving it as a testament to my inferior Perl golfing powers. \$\endgroup\$
    – user62131
    Dec 2, 2016 at 22:36
  • \$\begingroup\$ I agree, it's different enough from the other Perl solution, and with my previous comments, I tried to show that the only way I could golf it would turn it into the other solution. So leaving it as it is feels like the right solution. \$\endgroup\$
    – Dada
    Dec 2, 2016 at 22:39
1
\$\begingroup\$

Vim 61 54 bytes

qqYpPJ0yw:s;\d*;="/2
;g
:let @t=(">7)+1
@tkjjG@qq@q

TryItOnline!

Unprintables:

qqYpPJ0yw:s;\d*;^R=^R"/2
;g
:let @t=(^R">7)+1
@tkjjG@qq@q

Luckily vim automatically truncates on x/2.

\$\endgroup\$
1
\$\begingroup\$

JavaScript, 71 63 59 58 Bytes

Well, I came up with this javascript solution. Totally new at golfing, but I foudn this a fun challenge

Saved 4 bytes thanks to Titus suggestion using a for loop.

ungolfed basis:

for(o = i = 30; i > 1; i= i/4<<1) {
   console.log(`${i}`.repeat(o / i));
}

Golfed version

for(o=i=30;i>1;i=i/4<<1){console.log(`${i}`.repeat(o/i));}

I'm open for suggestions how to improve it / learn golfing

input tester

function test(a){
var el = document.getElementById('output');
var text = []; 
for(o = i = parseInt(a); i > 1; i= i/4<<1) {
   text.push(`${i}`.repeat(o / i));
}
  el.innerText = text.join('\n');
}
<input type="input" onchange="test(this.value)"><button>run</button>
<pre id="output">
</pre>

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You can save two bytes with a for loop: for(o=i=30;i>2;console.log(...)){...}. And with combining the two grinding assigments to one, you can remove the braces: i=i/4<<1; (-5). Not sure if i=i/4*2; will do the same. \$\endgroup\$
    – Titus
    Dec 3, 2016 at 9:06
  • 1
    \$\begingroup\$ I bet you haven´t tested that. \$\endgroup\$
    – Titus
    Dec 3, 2016 at 12:44
  • \$\begingroup\$ not yet, had to run from pc to catch my kids \$\endgroup\$ Dec 3, 2016 at 12:48
1
\$\begingroup\$

BASH, 81 bytes

n=$1
h=1
while [ ${n//2} ];do
printf -v s %$[h=h*2]s
echo ${s// /$[n=n/4*2]}
done
\$\endgroup\$
1
\$\begingroup\$

Swift, 84 Bytes

func g(n:Int){var n=n,i=2;while n>2{n=n/4*2;print(Array(repeating:n,count:i));i*=2}}

Ungolfed

func grind(rockSize: Int) {
    var rockSize = rockSize
    var rockCount = 1

    while rockSize > 2 {
        rockSize = rockSize / 4 * 2
        rockCount *= 2

        let output = Array(repeating: rockSize, count: rockCount)
        print(output)
    }
}
\$\endgroup\$
1
\$\begingroup\$

Befunge, 45 bytes

&1vg0_\:.\v
:\<  ^!:-1<p00:*2\.:*2/4,+55_@#`2

Try it online!

Explanation

&           read the rock size
1           initialise the count
<           start of main loop going right to left

  \         swap the size to the top of the stack
  :2`#@_    if size is not > 2 then exit
  55+,      output a line break
  4/2*      size = size/4*2, i.e. split into even halves
  :.        output the size
  \         swap the count to the top of the stack
  2*        count = count*2
  :00p      save count for later

  <         start of inner loop
    1-      decrement the count
    :!^_    break out of the loop if the count is zero
    \       swap the size to the top of the stack
    :.      output the size
    \       swap the count to the top of the stack
    v       back to the start of the inner loop    

  0g        restore the saved count
  v         back to the start of the main loop
\$\endgroup\$
1
\$\begingroup\$

Javascript, 106 bytes

First code golf, thought I'd have a go. (It's not very good).

for(;i[i.length-1]>3;){for(var x=0;x<i.length;x++)i[x]/=2,i[x]%2===1&&i[x]--;i=i.concat(i),console.log(i)}

Unminified:

while (input[input.length - 1] > 3) {
    for (var x = 0; x < input.length; x++) {
        input[x] /= 2;
        if (input[x] % 2 === 1) input[x]--;
    }
    input = input.concat(input);
    console.log(input);
}
\$\endgroup\$

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.