Zrób duże skały w małe skały


22

Witamy w szlifierce.

Twoim zadaniem jest przekształcenie dużych kamieni w małe skały poprzez ich zmielenie.

Weź wkład dużego kamienia wielkości n > 3 i zmiel go.

Kontynuuj mielenie skał, wrzucając je do młynka, aż rozmiar wszystkich skał będzie 2.

skały są zawsze mielone na równe, nawet połówki. Jeśli wynik szlifowania jest nieparzysty, weź wynik - 1.

W miarę postępów drukuj dane wyjściowe każdego szlifowania.

Przykłady

wkład: 5

wydajność: 22

Rezultatem są dwie skały wielkości 2

wkład: 50

wydajność:

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

wynikiem jest 16 kamieni wielkości 2

wkład: 30

wydajność:

1414
6666
22222222

wynikiem jest 8 kamieni wielkości 2

To jest więc wygrywa najkrótszy kod! Baw się dobrze i powodzenia!


Można się spodziewać, że będzie powyżej 3.
jacksonecac

Czy musimy użyć twojego formatu (wszystkie liczby połączone) lub czy możemy używać takich rzeczy jak listy? Niektóre odpowiedzi wydają się to robić zamiast tego.
Fatalize

Dopóki dane wyjściowe wyświetlają każdą iterację, format nie musi być taki jak powyżej.
jacksonecac

1
Powiedziałbym, że tablica 2d robi, a 1d nie, ale to zależy od ciebie, więc OK.
Jonathan Allan,

1
@ user902383 albo jest w porządku, chyba że określono w wyzwaniu zgodnie z meta konsensusem . Jeśli chodzi o dane wejściowe i wyjściowe, znowu oba są w porządku - zobacz ten post .
Jonathan Allan,

Odpowiedzi:



8

COW, 297 291 bajtów

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Wypróbuj online!

Kod drukuje każdą liczbę w osobnym wierszu i oddziela iteracje dodatkowym nowym wierszem. Drukuje również samą pierwszą iterację, a następnie nową linię. Zatem wejście 5 dałoby wynik, który wygląda jak 5 2 2oprócz znaków nowej linii zamiast spacji. Przykładowe dane wyjściowe dla 50podano poniżej.

Drzewo objaśnień:

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

Przykładowe dane wyjściowe dla wejścia 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
Nie mam słów
jacksonecac

Nadal nie mam słów
jacksonecac,

Nie mam słów
Edeki Okoh

Uwielbiam to, jak dwa i pół roku później to wciąż przeraża ludzi.
Gabriel Benamy

7

05AB1E , 12 11 bajtów

¸[4÷·€D=¬<#

Wypróbuj online!

Wyjaśnienie

¸             # 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 bajtów

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

Podziel się przez 4 i przesuń w lewo przez 1, aby uzyskać specjalną dywizję


4

Haskell, 75 71 60 50 47 bajtów

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

Wypróbuj online! Edycja: Ponieważ wyjściem może być teraz lista zawierająca dane wejściowe, można zapisać 10 13 bajtów.

Stosowanie:

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

Oryginalna 60-bajtowa wersja:

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

Wypróbuj online! Dzięki Christian Sievers za wskazanie krótszej formuły.

Stosowanie:

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

Możesz po prostu zrobić z<-2*div n 4.
Christian Sievers



3

Java, 85 bajtów

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

Testowanie i nie golfista

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

Uwaga: nie wiem dlaczego, Ideone wciąż podaje błąd wewnętrzny, więc testowanie go jest problemem. Aby przetestować, po prostu skopiuj / wklej i uruchom w standardowym środowisku Java IDE. (Działa tam, upewniłem się o tym;))


ideone współpracuje z kodem. Czasami daje błąd wewnętrzny, kiedy przeprowadzają konserwację (tak myślę). Miałem to już wcześniej, kiedy spojrzałem na moje stare odpowiedzi. +1 btw, nie widzę nic, co można by bardziej zagrać w golfa. Och, i podoba mi się twoja n=n/4*2sztuczka. :)
Kevin Cruijssen,

3

C #, 88 86 83 bajtów

Zaoszczędzono 3 bajty dzięki Skorm

Zapisano kolejny bajt, zmieniając while do forpętli, która zawiera deklaracje zmiennych

Zaoszczędzono 1 bajt dzięki 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;};

Anonimowa funkcja, która zwraca ciąg znaków złożony z wyniku każdego mielenia.

Pełny program z niepoznaną metodą i przypadkami testowymi [przed ostatnią edycją!]:

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
Pomyśl, że możesz zaoszczędzić 1 bajt w pętli for, wykonującfor(i=0;i++<c;)
Yodle

Nadal możesz zapisać 1 bajt, jak wspomniano w yoddle, zmieniając sekundę nafor (i = 0; i++ < c;)
MX D

Zapomniałem zaktualizować posta. Zaktualizowano teraz :)
adrianmp,

1
Możesz zaktualizować licznik, aby zaczynał się od 2 i * = 2 każdej iteracji, aby zapisać 1 bajt i przenieść nową linię dołączającą. Następnie możesz przenieść n = n / 4 * 2 do drugiej pętli i usunąć nawiasy klamrowe, aby zaoszczędzić jeszcze 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 bajtów

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

Wypróbuj online! (Jako zestaw testowy.)

Wyjaśnienie

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 bajtów

WhQ=Q*2my/d4\n

* \nto nowa linia
Objaśnienie:

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

Wypróbuj tutaj


2

MATL , 13 bajtów

`K/kEthttH>]x

Wypróbuj 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 bajtów

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

Pobiera argument z wiersza poleceń. Uruchom z -r.


2

Galaretka , 13 12 11 bajtów

:4Ḥx2µȦпṖY

TryItOnline!

Uwaga: OP stwierdził, że dane wejściowe mogą również znajdować się w danych wyjściowych.

W jaki sposób?

: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

Wersja bez danych wejściowych wyświetlanych dla 12 bajtów: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 bajtów

Uruchom z -nflagą

-4 bajty dzięki @Dada

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

Wypróbuj online!

Perl automatycznie odczytuje dane wejściowe do zmiennej, $_gdy -njest ustawiona. $.jest specjalną zmienną ustawioną 1na początku programu przez interpretera, więc mogę go użyć jako podstawy do podwojenia. Przy każdej iteracji whilepętla przesuwa $_się nieco w dół i wykonuje logiczne ORAZ względem swojej negatywnej minus jeden, aby anulować jeden bit.


Możesz zagrać w golfa do 31 bajtów: perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'(może to można pograć jeszcze bardziej, nie spędziłem na tym dużo czasu).
Dada,

2

PowerShell 3+, 58 54 bajtów

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

Dzięki TimmyD za uratowanie mnie 4 bajtów!

Nieznacznie niepolecany (formatowanie)

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

Wyjaśnienie

Używam tego samego podziału przez 4, pomnóż przez 2 lewę, jak wiele innych odpowiedzi, ale napotkałem problem. PowerShell konwertuje liczby na zmiennoprzecinkowe, jeśli jest to potrzebne podczas podziału, a do gry w golfa jest to denerwujące, ponieważ $v/4*2staje się czymś niefortunnym [int]($v/4)*2. Obejrzałem to za pomocą bitshiftingu do podziału -shr.

Aby obliczyć, ile razy wydrukować iterację, po prostu biorę, (2^$i)-1która działa ładnie i ma dodatkowy efekt polegający na pominięciu wartości wejściowej. Próba pomnożenia tylko przez 2 była problematyczna, ponieważ rozpoczęcie od 0 utrudnia zwiększenie wartości za pomocą just$i*=2 a rozpoczęcie od 1 wymaga zbyt dużej korekty, aby uzyskać poprawną liczbę.

Ponieważ PowerShell nie ma do tego operatora, a chciałem tego uniknąć [Math]::Pow(), ponownie polegałem na przesunięciu bitów dla moich mocy 2.


@ TimmyD whoops zapomniał wspomnieć o wersji i dobrą wskazówkę; dzięki!
briantist

1

Python 2, 47 bajtów

Ponieważ OP powiedział, że tablica 1D zawierająca dane wejściowe jest w porządku, wymyśliłem tę funkcję rekurencyjną, która niestety wiąże się tylko z obecnym zwycięzcą Pythona.

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[]) za 46
Jonathan Allan,

1

Perl, 47 bajtów

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

Tym razem brak opcji wiersza poleceń (wyjątkowo w Perlu). Podstawową ideą jest to, że ponieważ wszystkie skały na danym etapie mają ten sam rozmiar, po prostu rejestrujemy rozmiar (cal $a) i liczbę (cal $_), zamiast rejestrować całą listę. Nie mogłem znaleźć sposobu na pozbycie się przestrzeni (lub +) później say; możesz przenieść2* ale nie zostanie on poprawnie przeanalizowany, jeśli nastąpi po nim nawias otwierający.

Nie mogę się oprzeć wrażeniu, że można to poprawić, ale nie widzę, jak to zrobić.


Jeśli za bardzo spróbuję zagrać w golfa, za każdym razem otrzymam odpowiedź Gabriela Benamy'ego. Wystarczy pokazać kilka kroków: diewyraźnie wydaje się nieoptymalny. Ale wciąż musimy sposób na sprawdzenie, czy musimy się zatrzymać, czy nie -> rozwiązaniem jest użycie czasu zamiast for: while$a>1. Ale musimy znaleźć zamiennik $_: każda zmienna zunifikalizowana może to zrobić: zastąpić 1<<$_przez 1<<++$x. Więc teraz $_można go używać, możemy następnie użyć -ni zastąpić każdy $az $_, a pierwsza instrukcja staje się $_>>=1. Ponieważ mamy -n, $.jest ustawiony, więc możemy zastąpić 1<<++$lz $.*=2.
Dada,

Doing all those modifications will produce perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1' (39 bytes). Then notice that $_>>=1 is done twice, so we can try to get rid of one (the first one). Trying to get rid of it, I got say$_ x($.*=2)while($_>>=1)/2>1 (put both of them inside the while condition). But the result is wrong ($_ can be odd), and trying to make sure it's even, I end up with while$_=$_>>1&~1. So the code is now say$_ x($.*=2)while($_=$_>>1&~1).
Dada

I missed that there was a Perl answer already. I guess if golfing this down turns it into a duplicate, there's not much point in editing it. On the other hand, it's not actually wrong, so there's not much point in deleting it either. We're probably best off just leaving it as a testament to my inferior Perl golfing powers.

I agree, it's different enough from the other Perl solution, and with my previous comments, I tried to show that the only way I could golf it would turn it into the other solution. So leaving it as it is feels like the right solution.
Dada

1

Vim 61 54 bytes

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

TryItOnline!

Unprintables:

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

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

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);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.