Convertir rocas grandes en rocas pequeñas


22

Bienvenido al molinillo.

Su tarea es convertir rocas grandes en rocas pequeñas moliéndolas.

Tome una entrada de una gran roca de tamaño n > 3 y muélala.

Continúe moliendo las rocas vertiéndolas en el molino hasta que tengan el tamaño de todas las rocas 2.

las rocas siempre se muelen en mitades iguales iguales. Si el resultado de una molienda es impar, tome el resultado - 1.

Imprima el resultado de cada rectificado a medida que avanza.

Ejemplos

entrada: 5

salida: 22

El resultado son dos rocas de tamaño 2.

entrada: 50

salida:

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

el resultado son 16 rocas de tamaño 2

entrada: 30

salida:

1414
6666
22222222

el resultado son 8 rocas de tamaño 2

Este es el por lo que gana el código más corto. ¡Diviértete y buena suerte!


Puede esperar que sea superior a 3.
jacksonecac

¿Tenemos que usar su formato (todos los números concatenados) o podemos usar cosas como listas? Algunas respuestas parecen hacer eso en su lugar.
Fatalize

Mientras el resultado muestre cada iteración, el formato no necesita ser como el anterior.
jacksonecac

1
Yo diría que una matriz 2d sí y una 1d no, pero depende de usted, así que está bien.
Jonathan Allan

1
@ user902383 está bien, a menos que se especifique en el desafío según el meta consenso . En cuanto a entrada y salida, nuevamente ambos están bien, vea esta publicación .
Jonathan Allan

Respuestas:



8

VACA, 297 291 bytes

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Pruébalo en línea!

El código imprime cada número en su propia línea y separa las iteraciones con una nueva línea adicional. También imprime la primera iteración por sí misma, seguida de una nueva línea. Por lo tanto, una entrada de 5 daría una salida que se parece 5 2 2excepto con líneas nuevas en lugar de espacios. La salida de muestra para 50se da a continuación.

Árbol de explicaciones:

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

Salida de muestra para la entrada 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

2
No tengo palabras
jacksonecac

Todavía no tengo palabras
jacksonecac

No tengo palabras
Edeki Okoh

Me encanta cómo dos años y medio después, esto todavía horroriza a las personas.
Gabriel Benamy

7

05AB1E , 12 11 bytes

¸[4÷·€D=¬<#

Pruébalo en línea!

Explicación

¸             # 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

6

Python 2, 55 53 bytes

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

Divide entre 4 y desplaza a la izquierda por 1 para obtener la división especial


4

Haskell, 75 71 60 50 47 bytes

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

Pruébalo en línea! Editar: como la salida ahora puede ser una lista que incluye la entrada, 10 se pueden guardar 13 bytes.

Uso:

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

Versión original de 60 bytes:

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

Pruébalo en línea!Gracias a Christian Sievers por señalar la fórmula más corta.

Uso:

Prelude> (%2)50
"2424\n12121212\n66666666\n2222222222222222\n"

Solo puedes hacer z<-2*div n 4.
Christian Sievers

3

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);                                  


si pongo su código en mothereff.in/byte-counter obtengo 59 bytes?
Tschallacka

@Tschallacka Creo que el f=pero es solo para la demo
LarsW

Ah bien. Eso deja en claro :-) todavía
tengo

3

Python 2, 48 47 bytes

s=input()
n=1
while s>3:s=s/4*2;n*=2;print`s`*n

s=s/4*2funcionará para guardar 1 byte.
Jonathan Allan

3

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;}

Prueba y sin golf

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));
  }
}

Nota: No sé por qué, Ideone sigue dando errores internos, por lo que probarlo es un problema. Para probar, simplemente copie / pegue y ejecute en su Java IDE estándar. (Funciona allí, me aseguré de eso;))


ideone funciona bien con tu código. A veces se produce un error interno cuando realizan tareas de mantenimiento (creo). Lo tuve antes cuando volví a mirar las viejas respuestas mías. +1 por cierto, no veo nada que se pueda jugar más al golf. Ah, y me gusta tu n=n/4*2truco. :)
Kevin Cruijssen

3

C #, 88 86 83 bytes

Guardado 3 bytes gracias a Skorm

Se guardó otro byte cambiando el whilea un forbucle que incluye declaraciones de variables

Guardado 1 bytes gracias a 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;};

Función anónima que devuelve una cadena compuesta por el resultado de cada molienda.

Programa completo con método no protegido y casos de prueba [¡antes de la última edición!]:

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));
    }
}

2
Cree que puede guardar 1 byte en el bucle for haciendofor(i=0;i++<c;)
Yodle

Todavía puede guardar 1 byte, como lo mencionó yoddle al cambiar su segundo porfor (i = 0; i++ < c;)
MX D

Olvidé actualizar la publicación. Actualizado ahora :)
adrianmp

1
Puede actualizar su contador para comenzar en 2 y * = 2 cada iteración para guardar 1 byte y mover la nueva línea anexar. Luego puede mover el n = n / 4 * 2 al segundo bucle y quitar las llaves para ahorrar 2 más. 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;}
Skorm

2

CJam , 21 bytes

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

Pruébalo en línea!(Como un conjunto de pruebas).

Explicación

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.

2

Pyth, 18 16 13 bytes

WhQ=Q*2my/d4\n

* \nes una nueva línea
Explicación:

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

Intenta aquí


2

MATL , 13 bytes

`K/kEthttH>]x

Pruébalo en línea!

`       % 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

2

PHP, 72 67 64 bytes

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

Toma el argumento de la línea de comando. Corre con -r.


2

Jalea , 13 12 11 bytes

:4Ḥx2µȦпṖY

TryItOnline!

Nota: el OP indicó que la entrada también puede estar en la salida.

¿Cómo?

: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

Versión sin la entrada mostrada para 12 bytes: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 bytes

Corre con la -nbandera

-4 bytes gracias a @Dada

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

Pruébalo en línea!

Perl lee automáticamente la entrada en la variable $_cuando -nse establece. $.es una variable especial establecida al 1principio del programa por el intérprete, por lo que puedo usarla como base para duplicar. Cada iteración del whilebucle, se desplaza $_hacia abajo y realiza un AND lógico contra el negativo de sí mismo menos uno para cancelar el bit unos.


Puedes jugar golf hasta 31 bytes: perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'(tal vez esto se pueda jugar aún más, no pasé mucho tiempo en él).
Dada

2

PowerShell 3+, 58 54 bytes

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

Gracias TimmyD por salvarme 4 bytes!

Ligeramente sin golf (formateo)

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

Explicación

Estoy usando el mismo truco dividir por 4 multiplicar por 2 como muchas de las otras respuestas, pero me encontré con un problema. PowerShell convierte los números en coma flotante si es necesario durante la división, y para jugar al golf es molesto porque se $v/4*2convierte en algo desagradable [int]($v/4)*2. Lo solucioné usando el desplazamiento de bits para la división con-shr .

Para calcular cuántas veces imprimir una iteración, simplemente tomo lo (2^$i)-1que funciona bien y tiene el efecto agregado de omitir el valor de entrada. Intentar multiplicar por 2 fue problemático porque comenzar desde 0 hace que sea difícil aumentar el valor con solo$i*=2 y comenzar desde 1 requiere demasiada corrección para obtener el número correcto.

Como PowerShell no tiene un operador para ello, y quería evitarlo [Math]::Pow(), volví a confiar en el cambio de bits para mis poderes de 2.


@TimmyD whoops olvidó mencionar la versión, y un buen consejo; ¡Gracias!
briantist

1

Python 2, 47 bytes

Dado que el OP dijo que una matriz 1D que incluía la entrada estaba bien, se me ocurrió esta función recursiva, que desafortunadamente solo se vincula con el ganador actual de Python.

f=lambda s,n=1:[s]*n+(f(s/4*2,n*2)if s>3else[])

f=lambda r,n=1:[r]*n+(r>3and f(r/4*2,n*2)or[]) para 46
Jonathan Allan

1

Perl, 47 bytes

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

No hay opciones de línea de comandos, esta vez (inusualmente para Perl). La idea básica es que, como todas las rocas en cualquier paso dado tienen el mismo tamaño, solo registramos el tamaño (en $a) y el número (en $_), en lugar de registrar la lista completa. No pude encontrar una manera de deshacerme del espacio (o +) después say; puedes mover el2* pero no se analizará correctamente si va seguido de un paréntesis de apertura.

No puedo evitar sacudir la sensación de que esto es mejorable, pero no puedo ver cómo.


Si trato de jugar al golf demasiado, termino con la respuesta de Gabriel Benamy cada vez. Solo para mostrar algunos pasos: dieclaramente se siente subóptimo. Pero todavía tenemos una manera de comprobar si tenemos que dejar o no -> una solución es utilizar un tiempo en lugar de la for: while$a>1. Pero necesitamos encontrar un reemplazo para $_: cualquier variable unitaria puede hacerlo: reemplazar 1<<$_por 1<<++$x. Así que ahora $_es libre de usar, luego podemos usar -ny reemplazar cada uno $acon a $_, y la primera instrucción se convierte $_>>=1. Como tenemos -n, $.está configurado, por lo que podemos reemplazar 1<<++$lcon $.*=2.
Dada

Hacer todas esas modificaciones producirá perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 bytes). Luego observe que $_>>=1se hace dos veces, para que podamos tratar de deshacernos de uno (el primero). Intentando deshacerme de él, lo conseguí say$_ x($.*=2)while($_>>=1)/2>1(los puse a ambos dentro de la whilecondición). Pero el resultado es incorrecto ( $_puede ser extraño), y al tratar de asegurarme de que sea uniforme, termino con while$_=$_>>1&~1. Entonces el código es ahora say$_ x($.*=2)while($_=$_>>1&~1).
Dada

Extrañaba que ya hubiera una respuesta de Perl. Supongo que si jugar golf hacia abajo lo convierte en un duplicado, no tiene mucho sentido editarlo. Por otro lado, en realidad no está mal, por lo que tampoco tiene mucho sentido eliminarlo. Probablemente sea mejor dejarlo como un testimonio de mis poderes de golf Perl inferiores.

Estoy de acuerdo, es lo suficientemente diferente de la otra solución de Perl, y con mis comentarios anteriores, traté de demostrar que la única forma en que podría jugar golf sería convertirla en la otra solución. Así que dejarlo como está se siente como la solución correcta.
Dada

1

Vim 61 54 bytes

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

TryItOnline!

No imprimibles

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

Afortunadamente, vim se trunca automáticamente en x / 2.


1

JavaScript, 71 63 59 58 Bytes

Bueno, se me ocurrió esta solución de JavaScript. Totalmente nuevo en el golf, pero creo que es un desafío divertido

Guardado 4 bytes gracias a la sugerencia de Titus usando un bucle for.

base sin golf:

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

Versión de golf

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

Estoy abierto a sugerencias sobre cómo mejorarlo / aprender golf

probador de entrada


1
Puede guardar dos bytes con un forbucle: for(o=i=30;i>2;console.log(...)){...}. Y al combinar las dos asignaciones de molienda en una, puede quitar las llaves: i=i/4<<1;(-5). No estoy seguro si i=i/4*2;hará lo mismo.
Titus

1
Apuesto a que no lo has probado.
Titus

todavía no, tuve que correr de la PC para atrapar a mis hijos
Tschallacka

1

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

1

Rápido, 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}}

Sin golf

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)
    }
}

1

Befunge, 45 bytes

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

Pruébalo en línea!

Explicación

&           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

1

Javascript, 106 bytes

Primer código de golf, pensé que tendría una oportunidad. (No es muy bueno).

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)}

No minificado:

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);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.