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


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.