Сделать большие камни в маленькие камни


22

Добро пожаловать в кофемолку.

Ваша задача - превратить большие камни в маленькие, размолоть их.

Возьмите вход большого размера n > 3 и размолоть его.

Продолжайте шлифовать камни, бросая их в кофемолку, пока размер всех камней не станет равным 2.

камни всегда измельчаются в равные ровные половины. Если результат помола нечетный, принять результат - 1.

Распечатайте результаты каждого измельчения, как вы продолжаете.

Примеры

вход: 5

выход: 22

В результате получились два камня размером 2

вход: 50

выход:

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

результат - 16 камней размером 2

вход: 30

выход:

1414
6666
22222222

результат - 8 камней размером 2

Это поэтому выигрывает самый короткий код! Удачи и удачи!


Вы можете ожидать, что это будет выше 3.
jacksonecac

Нужно ли нам использовать ваш формат (все числа объединены) или мы можем использовать такие вещи, как списки? Некоторые ответы, кажется, делают это вместо этого.
Fatalize

Пока выходные данные отображают каждую итерацию, формат не должен быть таким, как указано выше.
Jacksonecac

1
Я бы сказал, что 2d массив делает, а 1d нет, но все в порядке.
Джонатан Аллан

1
@ user902383 либо подойдет, если не указано иное в соответствии с мета-консенсусом . Что касается ввода и вывода, снова оба в порядке - см. Этот пост .
Джонатан Аллан

Ответы:



8

COW, 297 291 байт

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Попробуйте онлайн!

Код печатает каждое число в отдельной строке и разделяет итерации дополнительной новой строкой. Он также печатает первую итерацию, за которой следует новая строка. Таким образом, ввод 5 даст вывод, который будет выглядеть, 5 2 2за исключением символов новой строки вместо пробелов. Пример вывода для 50приведен ниже.

Дерево объяснений:

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

Пример вывода для ввода 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
У меня нет слов
jacksonecac

У меня до сих пор нет слов
jacksonecac

У меня нет слов
Эдеки Око

Мне нравится, как два с половиной года спустя это все еще ужасает людей.
Габриэль Бенами

7

05AB1E , 12 11 байт

¸[4÷·€D=¬<#

Попробуйте онлайн!

объяснение

¸             # 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 байта

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

Разделите на 4 и сдвиг влево на 1, чтобы получить специальное деление


4

Haskell, 75 71 60 50 47 байтов

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

Попробуйте онлайн! Редактировать: так как вывод теперь может быть списком, включающим ввод, можно сохранить 10 13 байтов.

Использование:

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

Оригинальная 60-байтовая версия:

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

Попробуйте онлайн! Спасибо Кристиану Сиверсу за указание на более короткую формулу.

Использование:

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

Вы можете просто сделать z<-2*div n 4.
Кристиан Сиверс

3

JavaScript (ES6) 64 59 57 байт

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


если я помещу ваш код в mothereff.in/byte-counter, я получу 59 байт?
Чаллака

@ Tschallacka Я думаю, f=но только для демонстрации
LarsW

Ах хорошо. Это проясняет :-) все еще должен получить 2 байта от меня тогда
Tschallacka


3

Java, 85 байт

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

Тестирование и разгул

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

Примечание: я не знаю почему, Ideone продолжает выдавать внутреннюю ошибку, поэтому тестирование на ней является проблемой. Чтобы проверить, просто скопируйте / вставьте и запустите в вашей стандартной Java IDE. (Там работает, я в этом убедился;))


ideone отлично работает с вашим кодом. Иногда они дают внутреннюю ошибку, когда они выполняют техническое обслуживание (я думаю). Я имел это прежде, когда я оглянулся на свои старые ответы. +1 Кстати, я не вижу ничего, что можно больше играть в гольф. Ох, и мне нравится твой n=n/4*2трюк. :)
Кевин Круйссен

3

C #, 88 86 83 байта

Сохранено 3 байта благодаря Skorm

Сохраненная другие байты путем изменения whileкfor цикле , который включает в себя объявления переменных

Сохранено 1 байт благодаря 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;};

Анонимная функция, которая возвращает строку, составленную из результата каждого измельчения.

Полная программа с методом ungolfed и контрольными примерами [перед последним редактированием!]:

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
Думаю, вы можете сохранить 1 байт в цикле for, выполнивfor(i=0;i++<c;)
Yodle

Вы все еще можете сохранить 1 байт, как упоминалось выше, изменив второй параметр наfor (i = 0; i++ < c;)
MX D

Забыл обновить пост. Обновлено сейчас :)
Adrianmp

1
Вы можете обновить свой счетчик, чтобы он начинался с 2 и * = 2 на каждой итерации, чтобы сохранить 1 байт, и переместить добавление новой строки. Затем вы можете переместить n = n / 4 * 2 во второй цикл и удалить фигурные скобки, чтобы сохранить еще 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 байт

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

Попробуйте онлайн!(Как набор тестов.)

объяснение

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 байтов

WhQ=Q*2my/d4\n

* \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

Попробуй здесь


2

MATL , 13 байт

`K/kEthttH>]x

Попробуйте онлайн!

`       % 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 байта

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

Принимает аргумент из командной строки. Беги с -r.


2

Желе , 13 12 11 байт

:4Ḥx2µȦпṖY

TryItOnline!

Примечание: ОП заявил, что вход также может быть на выходе.

Как?

: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

Версия без ввода отображается для 12 байтов: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 байт

Беги с -nфлагом

-4 байта благодаря @Dada

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

Попробуйте онлайн!

Perl автоматически считывает ввод в переменную, $_когда -nона установлена. $.это специальная переменная, установленная 1интерпретатором в начале программы, поэтому я могу использовать ее как основу для удвоения. Каждая итерация whileцикла сдвигает бит $_вниз и выполняет логическое И против самого себя минус один, чтобы исключить биты.


Вы можете perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'сыграть в гольф до 31 байта: (возможно, это может быть сделано еще дальше, я не тратил на это много времени).
Дада

2

PowerShell 3+, 58 54 байта

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

Спасибо TimmyD за то, что сэкономили мне 4 байта!

Слегка разгромленный (форматирование)

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

объяснение

Я использую то же умножение на 4, умножение на 2, как и во многих других ответах, но столкнулся с проблемой. PowerShell преобразует числа в числа с плавающей запятой, если это необходимо во время деления, и для игры в гольф это раздражает, потому что $v/4*2становится чем-то вроде непристойности [int]($v/4)*2. Я обошел это, используя битшифтинг для разделения с-shr .

Для расчета количества раз, чтобы напечатать итерацию, я просто выбрал, (2^$i)-1которая работает хорошо и имеет дополнительный эффект пропуска входного значения. Попытка просто умножить на 2 была проблематичной, потому что начиная с 0 затрудняет увеличение значения с помощью просто, $i*=2а начиная с 1 требуется слишком много коррекции, чтобы получить правильное число.

Поскольку PowerShell не имеет оператора для этого, и я хотел избежать [Math]::Pow(), я снова полагался на сдвиг битов для своих степеней 2.


@TimmyD упс, забыл упомянуть версию и хороший совет; Благодарность!
briantist

1

Python 2, 47 байт

Поскольку ОП сказал, что одномерный массив, включающий входные данные, был в порядке, я придумал эту рекурсивную функцию, которая, к сожалению, связана только с текущим победителем 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[]) для 46
Джонатан Аллан

1

Perl, 47 байт

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

На этот раз без параметров командной строки (необычно для Perl). Основная идея состоит в том, что, поскольку все камни на любом данном этапе имеют одинаковый размер, мы просто записываем размер (в $a) и число (в $_), а не записываем весь список. Я не мог найти способ избавиться от места (или +) после say; Вы можете переместить, 2*но он не будет анализироваться правильно, если за ним следует открывающая скобка.

Я не могу удержаться от ощущения, что это невозможно, но я не понимаю, как это сделать.


Если я попытаюсь сыграть в гольф много, я получу ответ Габриэля Бенами каждый раз. Просто, чтобы показать несколько шагов: dieявно чувствует себя неоптимальным. Но мы по- прежнему нужен способ , чтобы проверить , если нам нужно , чтобы остановить или нет -> а решение использовать какое - то время вместо for: while$a>1. Но нам нужно найти замену $_: любая унитаризованная переменная может это сделать: заменить 1<<$_на 1<<++$x. Так что теперь $_можно свободно использовать, затем мы можем использовать -nи заменить каждое $aна a $_, и первая инструкция становится $_>>=1. Поскольку у нас есть -n, $.установлено, поэтому мы можем заменить 1<<++$lна $.*=2.
Дада

Выполнение всех этих модификаций даст perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 байт). Затем обратите внимание, что $_>>=1это делается дважды, поэтому мы можем попытаться избавиться от одного (первого). Пытаясь от него избавиться, я получил say$_ x($.*=2)while($_>>=1)/2>1(поместил их обоих в whileсостояние). Но результат неправильный ( $_может быть нечетным), и, пытаясь убедиться, что он четный, я получаю в итоге while$_=$_>>1&~1. Так что код сейчас say$_ x($.*=2)while($_=$_>>1&~1).
Дада

Я пропустил, что уже был ответ Perl. Я думаю, если игра в гольф превратит ее в дубликат, нет смысла ее редактировать. С другой стороны, на самом деле это не так, поэтому нет смысла удалять его. Возможно, нам лучше всего оставить это как свидетельство моих слабых способностей в Perl.

Я согласен, это достаточно отличается от другого решения Perl, и с моими предыдущими комментариями я попытался показать, что единственный способ, которым я мог бы играть в гольф, это превратить его в другое решение. Таким образом, оставляя все как есть, кажется правильным решением.
Дада

1

Vim 61 54 байта

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

TryItOnline!

непечатные:

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

К счастью, vim автоматически обрезает х / 2.


1

JavaScript, 71 63 59 58 байт

Ну, я придумал это решение для JavaScript. Абсолютно новичок в гольфе, но я считаю, что это увлекательное испытание

Сохранено 4 байта благодаря предложению Titus с использованием цикла for.

Нежелательная основа:

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

Гольф версия

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

Я открыт для предложений, как улучшить его / научиться играть в гольф

тестер ввода


1
Вы можете сохранить два байта с forконтуром: for(o=i=30;i>2;console.log(...)){...}. И, объединив два шлифовальных инструмента в одно, вы можете удалить фигурные скобки: i=i/4<<1;(-5). Не уверен, i=i/4*2;что сделаю то же самое.
Тит

1
Бьюсь об заклад, вы не проверяли это.
Тит

пока нет, пришлось бежать с компьютера, чтобы поймать моих детей
Tschallacka


1

Swift, 84 байта

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 байт

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

Попробуйте онлайн!

объяснение

&           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 байт

Первый код гольф, думал, что мне пора. (Это не очень хорошо).

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);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.