Зробіть великі скелі в невеликі скелі


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

Чи потрібно використовувати ваш формат (всі номери об'єднані) чи ми можемо використовувати такі речі, як списки? Деякі відповіді, здається, роблять це натомість.
Фаталізувати

Поки на виході відображається кожна ітерація, формат не повинен бути подібним до вище.
jacksonecac

1
Я б сказав, що 2d масив робить, а 1d - ні, але це залежить від вас.
Джонатан Аллан

1
@ user902383 або добре, якщо не вказано в виклику відповідно до мета-консенсусу . Що стосується введення та виведення, то і те й інше добре - дивіться цей пост .
Джонатан Аллан

Відповіді:



8

КОРО, 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

Ага, гаразд. З цього
випливає


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 btw, я не бачу нічого, що можна більше пограти в гольф. О, і мені подобається твій n=n/4*2фокус. :)
Kevin Cruijssen

3

C #, 88 86 83 байт

Збережено 3 байти завдяки Skorm

Збережено ще один байт, змінивши while на "a"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;};

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

Повна програма з методом unolfolf та тестовими кейсами [до останнього редагування!]:

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 байт, як згадується yoddle, змінивши другий на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

СпробуйтеItOnline!

Примітка: ОП заявило, що вхід може бути і у виході.

Як?

: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, важко збільшувати значення за допомогою just$i*=2 а починаючи з 1 вимагає занадто великої корекції, щоб правильно визначити число.

Оскільки PowerShell не має оператора для цього, і цього я хотів уникнути [Math]::Pow(), я знову покладався на бітшіфтінг для своїх повноважень 2.


@TimmyD whoops забув згадати версію, і хороша порада; Спасибі!
британіст

1

Пітон 2, 47 байт

Оскільки в ОП сказали, що 1D-масив, що включає вхід, добре, я придумав цю рекурсивну функцію, яка, на жаль, пов'язана лише з поточним переможцем 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). Основна ідея полягає в тому, що оскільки всі скелі на будь-якому етапі мають однаковий розмір, ми просто записуємо розмір (in $a) та число (in $_), а не записуємо весь список. Я не міг знайти спосіб позбутися місця (або +) після 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

СпробуйтеItOnline!

Недруковані матеріали:

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

Luckily vim automatically truncates on x/2.


1

JavaScript, 71 63 59 58 Bytes

Well, I came up with this javascript solution. Totally new at golfing, but I foudn this a fun challenge

Saved 4 bytes thanks to Titus suggestion using a for loop.

ungolfed basis:

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

Golfed version

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

I'm open for suggestions how to improve it / learn golfing

input tester


1
You can save two bytes with a for loop: for(o=i=30;i>2;console.log(...)){...}. And with combining the two grinding assigments to one, you can remove the braces: i=i/4<<1; (-5). Not sure if i=i/4*2; will do the same.
Titus

1
I bet you haven´t tested that.
Titus

not yet, had to run from pc to catch my kids
Tschallacka


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

Try it online!

Explanation

&           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

First code golf, thought I'd have a go. (It's not very good).

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.