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.