Faça pedras grandes em pedras pequenas


22

Bem-vindo ao moedor.

Sua tarefa é transformar pedras grandes em pedras pequenas, moendo-as.

Pegue uma entrada de uma pedra grande n > 3 e triture-a.

Continue a triturar as pedras, despejando-as no moedor até o tamanho de todas as rochas 2.

pedras são sempre trituradas em partes iguais iguais. Se o resultado de uma retificação for ímpar, obtenha o resultado - 1.

Imprima a saída de cada retificação à medida que avança.

Exemplos

entrada: 5

saída: 22

O resultado são duas pedras do tamanho 2

entrada: 50

saída:

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

o resultado são 16 pedras de tamanho 2

entrada: 30

saída:

1414
6666
22222222

o resultado são 8 pedras de tamanho 2

Isso é então o código mais curto vence! Divirta-se e boa sorte!


Você pode esperar que ele seja acima 3.
— jacksonecac

Temos que usar seu formato (todos os números concatenados) ou podemos usar coisas como listas? Algumas respostas parecem fazer isso.
— Fatalize

Desde que a saída exiba cada iteração, o formato não precisa ser como o descrito acima.
— jacksonecac

1
Eu diria que uma matriz 2D faz e uma 2D não, mas depende de você.
— Jonathan Allan

1
@ user902383 está bom, a menos que especificado no desafio conforme meta consenso . Quanto à entrada e saída, novamente ambas estão bem - veja este post .
— Jonathan Allan

Respostas:



8

VACA, 297 291 bytes

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Experimente online!

O código imprime cada número em sua própria linha e separa as iterações com uma nova linha adicional. Ele também imprime a primeira iteração por si só, seguida por uma nova linha. Portanto, uma entrada 5 daria uma saída parecida, 5 2 2exceto com novas linhas em vez de espaços. A saída de amostra para 50é fornecida abaixo.

Árvore de explicação:

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

Saída de amostra para a 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
Não tenho palavras
— jacksonecac

Eu ainda não tenho palavras
— jacksonecac

Eu não tenho nenhuma palavra
— Edeki Okoh

Eu amo como dois anos e meio depois, isso ainda horroriza as pessoas.
— Gabriel Benamy

7

05AB1E , 12 11 bytes

¸[4÷·€D=¬<#

Experimente online!

Explicação

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

Divida por 4 e shift à esquerda por 1 para obter a divisão especial


4

Haskell, 75 71 60 50 47 bytes

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

Experimente online! Editar: Como a saída agora pode ser uma lista incluindo a entrada, 10 13 bytes podem ser salvos.

Uso:

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

Versão original de 60 bytes:

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

Experimente online! Agradecemos a Christian Sievers por apontar a fórmula mais curta.

Uso:

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

Você pode apenas fazer z<-2*div n 4.
— Christian Sievers


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

Testando e não-destruído

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: Não sei por que, o Ideone continua apresentando erros internos, portanto, testar é um problema. Para testar, basta copiar / colar e executar no seu Java IDE padrão. (Funciona lá, eu tenho certeza disso;))


O ideone funciona bem com o seu código. Às vezes está dando um erro interno quando eles estão fazendo manutenção (eu acho). Eu já tive isso antes quando olhei para as minhas antigas respostas. Com +1, não vejo nada que possa ser jogado mais. Ah, e eu gosto do seu n=n/4*2truque. :)
— Kevin Cruijssen

3

C #, 88 86 83 bytes

Economizou 3 bytes graças ao Skorm

Salvo outro byte, alterando o whilepara um forloop que inclui declarações de variáveis

Guardado 1 bytes graças 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;};

Função anônima que retorna uma string composta pelo resultado de cada retificação.

Programa completo com método não destruído e casos de teste [antes da última edição!]:

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
Pense que você pode economizar 1 byte no loop for fazendofor(i=0;i++<c;)
— Yodle

Você ainda pode salvar 1 byte, como mencionado anteriormente, alterando o seu segundo parafor (i = 0; i++ < c;)
— MX D

Esqueceu de atualizar a postagem. Atualizado agora :)
— adrianmp

1
Você pode atualizar seu contador para iniciar em 2 e * = 2 em cada iteração para economizar 1 byte e mover o novo acréscimo de linha. Em seguida, você pode mover n = n / 4 * 2 para o segundo loop e remover as chaves para economizar mais 2. 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;

Experimente online! (Como uma suíte de teste.)

Explicação

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

Pitão, 18 16 13 bytes

WhQ=Q*2my/d4\n

* \né uma nova linha
Explicação:

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

Experimente aqui


2

MATL , 13 bytes

`K/kEthttH>]x

Experimente 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

2

PHP, 72 67 64 bytes

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

Recebe argumento da linha de comando. Corra com -r.


2

Geléia , 13 12 11 bytes

:4Ḥx2µȦпṖY

TryItOnline!

Nota: o OP afirmou que a entrada também pode estar na saída.

Quão?

: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

Versão sem a entrada exibida para 12 bytes: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 bytes

Corra com a -nbandeira

-4 bytes graças a @Dada

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

Experimente online!

O Perl lê automaticamente a entrada na variável $_quando -nestá definido. $.é uma variável especial definida 1no início do programa pelo intérprete, para que eu possa usá-la como base para duplicação. A cada iteração do whileloop, ele muda $_um pouco e executa um AND lógico contra o negativo de si mesmo menos um para cancelar os bits.


Você pode jogar até 31 bytes: perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'(talvez isso possa ser jogado ainda mais, eu não gastei muito tempo nele).
— Dada

2

PowerShell 3 ou mais, 58 54 bytes

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

Obrigado TimmyD por me salvar 4 bytes!

Ligeiramente não destruído (formatação)

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

Explicação

Estou usando a mesma divisão por 4, multiplique por 2, como muitas outras respostas, mas tive um problema. O PowerShell converte números em ponto flutuante, se necessário, durante a divisão e, para o golfe, isso é irritante porque $v/4*2se torna algo desagradável [int]($v/4)*2. Eu contornei isso usando o deslocamento de bits para a divisão -shr.

Para calcular quantas vezes para imprimir uma iteração, basta usar o (2^$i)-1que funciona bem e tem o efeito adicional de deixar de fora o valor de entrada. Tentar apenas multiplicar por 2 era problemático, porque começar de 0 dificulta o aumento do valor com just $i*=2e começar de 1 requer muita correção para acertar o número.

Como o PowerShell não tem um operador para isso, e eu queria evitar [Math]::Pow(), contei com o deslocamento de bits novamente para meus poderes de 2.


Opa, TimmyD, esqueceu de mencionar versão e boa dica; obrigado!
— Briantist

1

Python 2, 47 bytes

Como o OP disse que uma matriz 1D que incluía a entrada era boa, criei essa função recursiva, que infelizmente só se relaciona com o atual vencedor do 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

Não há opções de linha de comando, desta vez (excepcionalmente para Perl). A idéia básica é que, como todas as rochas em uma determinada etapa são do mesmo tamanho, apenas registramos o tamanho (pol $a) e o número (pol $_), em vez de gravar a lista inteira. Não consegui encontrar uma maneira de me livrar do espaço (ou +) depois say; você pode mover o 2*mas não será analisado corretamente se for seguido por um parêntese de abertura.

Não posso deixar de abalar a sensação de que isso é improvável, mas não vejo como.


Se eu tentar jogar muito, acabo sempre com a resposta de Gabriel Benamy. Apenas para mostrar alguns passos: o dieclaramente parece sub-ideal. Mas ainda precisamos de uma maneira de verificar se temos de parar ou não -> a solução é usar um tempo em vez do for: while$a>1. Mas precisamos encontrar um substituto para $_: qualquer variável unitializada pode fazê-lo: substituir 1<<$_por 1<<++$x. Portanto, agora que $_é livre para ser usado, podemos usar -ne substituir every $apor a $_, e a primeira instrução se torna $_>>=1. Desde que temos -n, $.está definido, para que possamos substituir 1<<++$lpor $.*=2.
— Dada

Fazer todas essas modificações produzirá perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 bytes). Então observe que isso $_>>=1é feito duas vezes, para que possamos tentar nos livrar de um (o primeiro). Tentando me livrar disso, consegui say$_ x($.*=2)while($_>>=1)/2>1(coloquei os dois dentro da whilecondição). Mas o resultado está errado ( $_pode ser estranho) e, tentando garantir que seja uniforme, acabo com isso while$_=$_>>1&~1. Então, o código é agora say$_ x($.*=2)while($_=$_>>1&~1).
— Dada

Perdi que já havia uma resposta Perl. Eu acho que se jogar golfe transformá-lo em duplicado, não há muito sentido em editá-lo. Por outro lado, não está realmente errado, então não há muito sentido em excluí-lo. Provavelmente, é melhor deixá-lo como uma prova dos meus poderes inferiores no golfe Perl.

Concordo que é bastante diferente da outra solução Perl e, com meus comentários anteriores, tentei mostrar que a única maneira de jogar golfe seria transformá-la na outra solução. Portanto, deixá-lo como está parece ser a solução certa.
— Dada

1

Vim 61 54 bytes

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

TryItOnline!

Não imprimíveis:

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

Felizmente, o vim trunca automaticamente em x / 2.


1

JavaScript, 71 63 59 58 bytes

Bem, eu vim com esta solução javascript. Totalmente novo no golfe, mas eu sou um desafio divertido

Economizou 4 bytes graças à sugestão de Titus usando um loop for.

base não destruída:

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

Versão Golfed

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

Estou aberto a sugestões de como melhorá-lo / aprender golfe

testador de entrada


1
Você pode salvar dois bytes com um forloop: for(o=i=30;i>2;console.log(...)){...}. E, combinando as duas atribuições de retificação em uma, é possível remover as chaves: i=i/4<<1;(-5). Não tenho certeza se i=i/4*2;fará o mesmo.
— Titus

1
Aposto que você não testou isso.
— Titus

ainda não, teve que correr a partir do PC para pegar meus filhos
— 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

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

1

Befunge, 45 bytes

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

Experimente online!

Explicação

&           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

Primeiro código de golfe, pensei em tentar. (Não é muito bom).

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

Desminificado:

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);
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.