Machen Sie große Steine ​​zu kleinen Steinen


22

Willkommen in der Mühle.

Ihre Aufgabe ist es, große Steine ​​durch Schleifen in kleine Steine ​​zu verwandeln.

Nehmen Sie eine Eingabe von einem großen Stein der Größe n > 3 und mahlen Sie es.

Mahlen Sie die Steine ​​weiter, indem Sie sie in die Mühle schütten, bis alle Steine ​​so groß sind 2.

Steine ​​werden immer zu gleichen, geraden Hälften geschliffen. Wenn das Ergebnis eines Schleifens ungerade ist, nimm das Ergebnis - 1.

Drucken Sie die Ausgabe jedes Schleifvorgangs aus, während Sie fortfahren.

Beispiele

Eingang: 5

Ausgabe: 22

Das Ergebnis sind zwei Steine ​​der Größe 2

Eingang: 50

Ausgabe:

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

Das Ergebnis sind 16 Steine ​​der Größe 2

Eingang: 30

Ausgabe:

1414
6666
22222222

Das Ergebnis sind 8 Steine ​​der Größe 2

Das ist also gewinnt der kürzeste Code! Viel Spaß und viel Glück!


Sie können erwarten, dass es über 3.
Jacksonecac

Müssen wir Ihr Format verwenden (alle Zahlen verkettet) oder können wir Dinge wie Listen verwenden? Einige Antworten scheinen dies stattdessen zu tun.
Fatalize

Solange die Ausgabe jede Iteration anzeigt, muss das Format nicht wie oben sein.
Jacksonecac

1
Ich würde sagen, ein 2d-Array funktioniert und ein 1d-Array nicht, aber es liegt an Ihnen, also OK.
Jonathan Allan

1
entweder @ user902383 ist in Ordnung in der Herausforderung , wenn nicht anders angegeben , wie pro Meta Konsens . Was die Eingabe und Ausgabe betrifft, sind beide wieder in Ordnung - siehe diesen Beitrag .
Jonathan Allan

Antworten:



8

COW, 297 291 Bytes

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Probieren Sie es online!

Der Code gibt jede Zahl in einer eigenen Zeile aus und trennt die Iterationen durch eine zusätzliche neue Zeile. Es wird auch die erste Iteration selbst gedruckt, gefolgt von einer neuen Zeile. Eine Eingabe von 5 würde also eine Ausgabe ergeben, die 5 2 2außer mit Zeilenumbrüchen anstelle von Leerzeichen aussieht . Die Beispielausgabe für 50ist unten angegeben.

Erklärungsbaum:

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

Beispielausgabe für Eingabe 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
Ich habe keine Worte
Jacksonecac

Ich habe noch keine Worte
Jacksonecac

Ich habe keine Worte
Edeki Okoh

Ich mag, wie zweieinhalb Jahre später die Menschen immer noch entsetzt sind.
Gabriel Benamy

7

05AB1E , 12 11 Bytes

¸[4÷·€D=¬<#

Probieren Sie es online!

Erläuterung

¸             # 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

Teilen Sie durch 4 und verschieben Sie nach links durch 1, um die Sonderteilung zu erhalten


4

Haskell, 75 71 60 50 47 Bytes

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

Probieren Sie es online! Bearbeiten: Da die Ausgabe nun eine Liste einschließlich der Eingabe sein darf, können 10 13 Bytes gespeichert werden.

Verwendung:

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

Ursprüngliche 60-Byte-Version:

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

Probieren Sie es online! Vielen Dank an Christian Sievers für den Hinweis auf die kürzere Formel.

Verwendung:

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

Sie können es einfach tun 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*2funktioniert für 1 Byte speichern.
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;}

Testen und ungolfed

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

Hinweis: Ich weiß nicht warum, Ideone gibt weiterhin interne Fehler aus, daher ist das Testen ein Problem. Zum Testen einfach kopieren / einfügen und in Ihrer Standard-Java-IDE ausführen. (Es funktioniert dort, ich habe dafür gesorgt;))


Ideone funktioniert gut mit Ihrem Code. Manchmal tritt ein interner Fehler auf, wenn Wartungsarbeiten durchgeführt werden (glaube ich). Ich hatte es schon einmal, als ich auf meine alten Antworten zurückblickte. Übrigens sehe ich nichts, was mehr golfen werden könnte. Oh, und ich mag deinen n=n/4*2Trick. :)
Kevin Cruijssen

3

C #, 88 86 83 Bytes

3 Bytes gespart dank Skorm

Ein weiteres Byte wurde gespeichert, indem whilein eine forSchleife gewechselt wurde , die Variablendeklarationen enthält

Dank Yodle 1 Byte gespeichert

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

Anonyme Funktion, die eine Zeichenfolge zurückgibt, die sich aus dem Ergebnis jedes Schleifvorgangs zusammensetzt.

Volles Programm mit ungolfed Methode und Testfällen [vor der letzten Bearbeitung!]:

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
Denken Sie, Sie können 1 Byte in der for-Schleife speichern, indem Sie for(i=0;i++<c;)
Folgendes

Sie können immer noch 1 Byte speichern, wie bereits erwähnt, indem Sie Ihre Sekunde auffor (i = 0; i++ < c;)
MX D

Ich habe vergessen, den Beitrag zu aktualisieren. Jetzt aktualisiert :)
adrianmp

1
Sie können Ihren Zähler so aktualisieren, dass er bei jeder Iteration bei 2 und * = 2 beginnt, um 1 Byte zu sparen, und den neuen Zeilenanhang verschieben. Sie können dann n = n / 4 * 2 in die zweite Schleife verschieben und die Klammern entfernen, um weitere 2 zu sparen. 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;

Probieren Sie es online! (Als Testsuite.)

Erläuterung

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 Bytes

WhQ=Q*2my/d4\n

* \nist eine neue Zeile
Erläuterung:

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

Versuch es hier


2

MATL , 13 Bytes

`K/kEthttH>]x

Probieren Sie es 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";

Übernimmt das Argument von der Kommandozeile. Laufen Sie mit -r.


2

Jelly , 13 12 11 Bytes

:4Ḥx2µȦпṖY

TryItOnline!

Hinweis: Das OP hat angegeben, dass der Eingang auch im Ausgang vorhanden sein kann.

Wie?

: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

Version ohne die Eingabe für 12 Bytes angezeigt: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40, 35, 30 + 1 = 31 Bytes

Laufen Sie mit der -nFlagge

-4 Bytes dank @Dada

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

Probieren Sie es online!

Perl liest die Eingabe automatisch in die Variable, $_wenn -nfestgelegt wird. $.ist eine spezielle Variable, 1die der Interpreter zu Beginn des Programms setzt, damit ich sie als Grundlage für das Verdoppeln verwenden kann. Bei jeder Iteration der whileSchleife wird das Bit $_heruntergeschoben und ein logisches UND gegen das Negative von sich selbst minus eins ausgeführt, um das Einsen-Bit zu löschen.


Sie können bis zu 31 Bytes Golf spielen: perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'(Vielleicht kann man das noch weiter spielen, ich habe nicht viel Zeit damit verbracht).
Dada

2

PowerShell 3+, 58 54 Byte

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

Danke TimmyD , dass du mir 4 Bytes gespart hast!

Leicht ungolfed (Formatierung)

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

Erläuterung

Ich verwende die gleiche Division durch 4 multiplizieren mit 2 Tricks wie viele andere Antworten, aber ich bin auf ein Problem gestoßen. PowerShell wandelt Zahlen bei Bedarf während der Division in Gleitkommazahlen um, und beim Golfen ist das ärgerlich, weil$v/4*2 erforderlich ist [int]($v/4)*2. Ich bin damit umgegangen, indem ich Bitshifting für die Division mit verwendet habe -shr.

Um zu berechnen, wie oft eine Iteration gedruckt werden soll, nehme ich einfach (2^$i)-1 was gut funktioniert und hat den zusätzlichen Effekt, dass der Eingabewert weggelassen wird. Der Versuch, nur mit 2 zu multiplizieren, war problematisch, da es schwierig ist, den Wert bei 0 zu erhöhen, $i*=2und bei 1 zu beginnen, ist zu viel Korrektur erforderlich, um die richtige Zahl zu erhalten.

Da PowerShell keinen Operator dafür hat und ich dies vermeiden wollte [Math]::Pow(), habe ich mich für meine Potenzen von 2 wieder auf die Bitverschiebung verlassen.


@TimmyD whoops vergessen, Version und guten Tipp zu erwähnen; Vielen Dank!
Briantist

1

Python 2, 47 Bytes

Da das OP sagte, dass ein 1D-Array, das die Eingabe enthielt, in Ordnung sei, habe ich mir diese rekursive Funktion ausgedacht, die leider nur mit dem aktuellen Python-Gewinner in Verbindung steht.

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[]) für 46
Jonathan Allan

1

Perl, 47 Bytes

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

Diesmal keine Befehlszeilenoptionen (ungewöhnlich für Perl). Die Grundidee ist, dass, da alle Steine ​​in einem bestimmten Schritt die gleiche Größe haben, wir nur die Größe (in $a) und die Anzahl (in $_) aufzeichnen, anstatt die gesamte Liste aufzuzeichnen. Ich konnte keinen Weg finden, den Raum (oder +) danach loszuwerden say; Sie können die bewegen2* aber es wird nicht korrekt analysiert, wenn es von einer öffnenden Klammer gefolgt wird.

Ich kann nicht anders, als das Gefühl zu erschüttern, dass dies verbesserungsfähig ist, aber ich kann nicht sehen, wie.


Wenn ich zu viel Golf spielen will, habe ich jedes Mal die Antwort von Gabriel Benamy. Nur um ein paar Schritte zu zeigen: Das diefühlt sich eindeutig suboptimal an. Aber wir müssen noch eine Möglichkeit zu überprüfen , ob wir zu stoppen oder nicht brauchen -> eine Lösung ist eine Weile , statt das verwenden for: while$a>1. Aber wir müssen einen Ersatz finden für $_: jede unitialisierte Variable kann es tun: Ersetzen 1<<$_durch 1<<++$x. So, jetzt $_ist es frei, verwendet zu werden, wir können dann -njeden $amit a verwenden und ersetzen $_, und der erste Befehl wird $_>>=1. Da wir haben -n, $.festgelegt ist, so können wir ersetzen 1<<++$lmit $.*=2.
Dada

Wenn Sie all diese Änderungen vornehmen, erhalten Sie perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 Byte). Beachten Sie dann, dass $_>>=1dies zweimal gemacht wird, damit wir versuchen können, einen (den ersten) loszuwerden. Beim Versuch, es loszuwerden, bekam ich say$_ x($.*=2)while($_>>=1)/2>1(lege beide in den whileZustand). Aber das Ergebnis ist falsch ( $_kann seltsam sein), und wenn ich versuche, sicherzustellen, dass es gerade ist, lande ich bei while$_=$_>>1&~1. So ist der Code jetzt say$_ x($.*=2)while($_=$_>>1&~1).
Dada

Ich vermisste, dass es bereits eine Perl-Antwort gab. Ich schätze, wenn Golf daraus ein Duplikat macht, macht es wenig Sinn, es zu bearbeiten. Auf der anderen Seite ist es nicht wirklich falsch, also macht es auch nicht viel Sinn, es zu löschen. Wir sind wahrscheinlich am besten dran, wenn wir es als Beweis für meine unterlegenen Perl-Golffähigkeiten belassen.

Ich stimme zu, es unterscheidet sich genug von der anderen Perl-Lösung, und mit meinen vorherigen Kommentaren habe ich versucht zu zeigen, dass die einzige Möglichkeit, Golf zu spielen, es in eine andere Lösung verwandeln würde. Es so zu lassen, wie es ist, fühlt sich wie die richtige Lösung an.
Dada

1

Vim 61 54 Bytes

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

TryItOnline!

Unbedruckbares:

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

Zum Glück schneidet vim bei x / 2 automatisch ab.


1

JavaScript, 71 63 59 58 Bytes

Nun, ich habe mir diese Javascript-Lösung ausgedacht. Völlig neu im Golfen, aber ich finde das eine lustige Herausforderung

4 Bytes dank Titus-Vorschlag mit einer for-Schleife eingespart.

ungolfed basis:

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

Golf Version

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

Ich bin offen für Verbesserungsvorschläge / Golf lernen

Eingabetester


1
Sie können zwei Bytes mit einer speichern forSchleife: for(o=i=30;i>2;console.log(...)){...}. Wenn Sie die beiden Schleifaufgaben zu einer kombinieren, können Sie die Klammern entfernen: i=i/4<<1;(-5). Ich i=i/4*2;bin mir nicht sicher, ob ich dasselbe tun werde.
Titus

1
Ich wette du hast das nicht getestet.
Titus

Noch nicht, musste vom PC laufen, um meine Kinder zu fangen
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

Schnell, 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

Probieren Sie es online!

Erläuterung

&           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

Erster Code Golf, dachte ich hätte eine Chance. (Es ist nicht sehr gut).

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

Nicht abgeschlossen:

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);
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.