Faites de gros rochers en petits rochers


22

Bienvenue dans le moulin.

Votre tâche consiste à transformer de gros rochers en petits rochers en les broyant.

Prenez une entrée d'un gros rocher de taille n > 3 et broyez-le.

Continuez à broyer les roches en les déversant dans le broyeur jusqu'à ce que la taille de toutes les roches soit 2.

les roches sont toujours broyées en deux moitiés égales. Si le résultat d'un broyage est impair, prenez le résultat - 1.

Imprimez la sortie de chaque rectification au fur et à mesure.

Exemples

contribution: 5

sortie: 22

Le résultat est deux roches de taille 2

contribution: 50

sortie:

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

le résultat est 16 roches de taille 2

contribution: 30

sortie:

1414
6666
22222222

le résultat est 8 roches de taille 2

C'est le donc le code le plus court gagne! Amuse-toi bien et bonne chance!


Vous pouvez vous attendre à ce qu'il soit supérieur à 3.
jacksonecac

Doit-on utiliser votre format (tous les nombres sont concaténés) ou pouvons-nous utiliser des choses comme des listes? Certaines réponses semblent le faire à la place.
Fatalize

Tant que la sortie affiche chaque itération, le format n'a pas besoin d'être comme ci-dessus.
jacksonecac

1
Je dirais qu'un tableau 2d le fait et qu'un 1d ne le fait pas, mais c'est à vous de décider.
Jonathan Allan

1
@ user902383 soit bien, sauf indication contraire dans le défi selon le méta-consensus . En ce qui concerne l'entrée et la sortie, encore une fois les deux sont très bien - voir ce post .
Jonathan Allan

Réponses:



8

COW, 297 291 octets

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Essayez-le en ligne!

Le code imprime chaque numéro sur sa propre ligne et sépare les itérations par une nouvelle ligne supplémentaire. Il imprime également la première itération par lui-même, suivi d'une nouvelle ligne. Ainsi, une entrée de 5 donnerait une sortie qui ressemble, 5 2 2sauf avec des sauts de ligne au lieu d'espaces. Un exemple de sortie pour 50est donné ci-dessous.

Arbre d'explication:

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

Exemple de sortie pour l'entrée 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
Je n'ai pas de mots
jacksonecac

Je n'ai toujours pas de mots
jacksonecac

Je n'ai pas de mots
Edeki Okoh

J'adore la façon dont deux ans et demi plus tard, cela horrifie toujours les gens.
Gabriel Benamy

7

05AB1E , 12 11 octets

¸[4÷·€D=¬<#

Essayez-le en ligne!

Explication

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

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

Divisez par 4 et décalage à gauche par 1 pour obtenir la division spéciale


4

Haskell, 75 71 60 50 47 octets

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

Essayez-le en ligne! Modifier: Comme la sortie est désormais autorisée à être une liste comprenant l'entrée, 10 13 octets peuvent être enregistrés.

Usage:

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

Version originale de 60 octets:

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

Essayez-le en ligne! Merci à Christian Sievers d'avoir souligné la formule plus courte.

Usage:

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

Vous pouvez simplement faire z<-2*div n 4.
Christian Sievers du

3

JavaScript (ES6) 64 59 57 octets

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


si je mets votre code dans mothereff.in/byte-counter j'obtiens 59 octets?
Tschallacka

@Tschallacka Je pense que le f=mais est juste pour la démo
LarsW

Ah ok. Cela rend clair :-) dois encore obtenir 2 octets de moins alors
Tschallacka

3

Python 2, 48 47 octets

s=input()
n=1
while s>3:s=s/4*2;n*=2;print`s`*n

s=s/4*2fonctionnera pendant 1 octet de sauvegarde.
Jonathan Allan

3

Java, 85 octets

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

Test et non golfé

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

Remarque: je ne sais pas pourquoi, Ideone continue de donner des erreurs internes, donc les tester est un problème. Pour tester, copiez / collez et exécutez simplement dans votre IDE Java standard. (Ça marche là-bas, je m'en suis assuré;))


ideone fonctionne très bien avec votre code. C'est parfois une erreur interne quand ils font de la maintenance (je pense). Je l'ai déjà eue quand j'ai repensé à mes anciennes réponses. +1 btw, je ne vois rien qui puisse être joué plus. Oh, et j'aime ton n=n/4*2truc. :)
Kevin Cruijssen

3

C #, 88 86 83 octets

Enregistré 3 octets grâce à Skorm

Enregistré un autre octet en changeant le whileen une forboucle qui inclut des déclarations de variables

1 octets enregistrés grâce à 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;};

Fonction anonyme qui renvoie une chaîne composée du résultat de chaque broyage.

Programme complet avec méthode non golfée et cas de test [avant la dernière édition!]:

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
Pensez que vous pouvez enregistrer 1 octet dans la boucle for en faisantfor(i=0;i++<c;)
Yodle

Vous pouvez toujours enregistrer 1 octet, comme mentionné ci-dessus, en changeant votre deuxième pourfor (i = 0; i++ < c;)
MX D

Vous avez oublié de mettre à jour le message. Mise à jour maintenant :)
adrianmp

1
Vous pouvez mettre à jour votre compteur pour commencer à 2 et * = 2 à chaque itération pour enregistrer 1 octet et déplacer la nouvelle ligne en annexe. Vous pouvez ensuite déplacer le n = n / 4 * 2 dans la deuxième boucle et retirer les accolades pour enregistrer 2 autres. 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 octets

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

Essayez-le en ligne! (En tant que suite de tests.)

Explication

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 octets

WhQ=Q*2my/d4\n

* \nest une nouvelle ligne
Explication:

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

Essayez ici


2

MATL , 13 octets

`K/kEthttH>]x

Essayez-le en ligne!

`       % 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 octets

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

Prend l'argument de la ligne de commande. Courez avec -r.


2

Gelée , 13 12 11 octets

:4Ḥx2µȦпṖY

TryItOnline!

Remarque: l'OP a indiqué que l'entrée peut également être dans la sortie.

Comment?

: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 sans entrée affichée pour 12 octets: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 octets

Courir avec le -ndrapeau

-4 octets grâce à @Dada

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

Essayez-le en ligne!

Perl lit automatiquement l'entrée dans la variable $_lorsqu'elle -nest définie. $.est une variable spéciale définie 1au début du programme par l'interpréteur, donc je peux l'utiliser comme base pour doubler. À chaque itération de la whileboucle, il $_rétrograde et effectue un ET logique contre le négatif de lui-même moins un pour annuler le bit de l'un.


Vous pouvez perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'jouer au golf jusqu'à 31 octets: (peut-être que cela peut être joué encore plus loin, je n'y ai pas passé beaucoup de temps).
Dada

2

PowerShell 3+, 58 54 octets

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

Merci TimmyD de m'avoir sauvé 4 octets!

Légèrement non golfé (formatage)

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

Explication

J'utilise la même astuce diviser par 4 multiplier par 2 que beaucoup d'autres réponses, mais j'ai rencontré un problème. PowerShell convertit les nombres en virgule flottante si nécessaire pendant la division, et pour le golf, c'est ennuyeux parce que cela $v/4*2devient quelque chose d'inesthétique [int]($v/4)*2. J'ai contourné cela en utilisant le décalage de bits pour la division avec -shr.

Pour calculer combien de fois imprimer une itération, je prends simplement (2^$i)-1ce qui fonctionne bien et a pour effet supplémentaire de laisser de côté la valeur d'entrée. Essayer de multiplier simplement par 2 était problématique, car à partir de 0, il est difficile d'augmenter la valeur avec juste $i*=2et à partir de 1 nécessite trop de correction pour obtenir le bon nombre.

Étant donné que PowerShell n'a pas d'opérateur pour cela, et je voulais éviter [Math]::Pow(), j'ai compté à nouveau sur le décalage de bits pour mes pouvoirs de 2.


@TimmyD whoops a oublié de mentionner la version et une bonne astuce; Merci!
briantist

1

Python 2, 47 octets

Depuis l'OP a dit qu'un tableau 1D qui comprenait l'entrée était bien, j'ai trouvé cette fonction récursive, qui malheureusement ne se lie qu'avec le gagnant actuel de 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[]) pour 46
Jonathan Allan

1

Perl, 47 octets

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

Aucune option de ligne de commande, cette fois (exceptionnellement pour Perl). L'idée de base est que, comme toutes les roches à une étape donnée ont la même taille, nous enregistrons simplement la taille (en $a) et le nombre (en $_), plutôt que d'enregistrer toute la liste. Je n'ai pas pu trouver un moyen de me débarrasser de l'espace (ou +) après say; vous pouvez déplacer le 2*mais il ne sera pas analysé correctement s'il est suivi d'une parenthèse ouvrante.

Je ne peux pas m'empêcher de secouer le sentiment que cela peut être amélioré, mais je ne vois pas comment.


Si j'essaye de jouer trop, je me retrouve à chaque fois avec la réponse de Gabriel Benamy. Juste pour montrer quelques étapes: la diesensation est clairement sous-optimale. Mais nous avons encore besoin d' un moyen de vérifier si nous devons arrêter ou non -> une solution est d'utiliser un certain temps au lieu de for: while$a>1. Mais nous devons trouver un remplaçant pour $_: n'importe quelle variable unitialisée peut le faire: remplacer 1<<$_par 1<<++$x. Alors maintenant, il $_est libre d'être utilisé, nous pouvons ensuite utiliser -net remplacer chaque $apar un $_, et la première instruction devient $_>>=1. Puisque nous avons -n, $.est défini, nous pouvons donc le remplacer 1<<++$lpar $.*=2.
Dada

Faire toutes ces modifications produira perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 octets). Notez ensuite que cela $_>>=1se fait deux fois, afin que nous puissions essayer de nous en débarrasser (le premier). En essayant de m'en débarrasser, j'ai réussi say$_ x($.*=2)while($_>>=1)/2>1(mettez les deux à l'intérieur de la whilecondition). Mais le résultat est faux ( $_peut être étrange), et en essayant de s'assurer qu'il est égal, je me retrouve avec while$_=$_>>1&~1. Le code est donc maintenant say$_ x($.*=2)while($_=$_>>1&~1).
Dada

J'ai raté qu'il y avait déjà une réponse Perl. Je suppose que si jouer au golf en fait un doublon, il ne sert à rien de le modifier. D'un autre côté, ce n'est pas vraiment faux, donc il n'y a pas grand intérêt à le supprimer non plus. Nous sommes probablement mieux lotis de le laisser comme un témoignage de mes pouvoirs de golf Perl inférieurs.

Je suis d'accord, c'est assez différent de l'autre solution Perl, et avec mes commentaires précédents, j'ai essayé de montrer que la seule façon de jouer au golf le transformerait en l'autre solution. Donc, le laisser tel quel semble être la bonne solution.
Dada

1

Vim 61 54 octets

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

TryItOnline!

Non imprimables:

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

Heureusement, vim tronque automatiquement sur x / 2.


1

JavaScript, 71 63 59 58 octets

Eh bien, j'ai trouvé cette solution javascript. Totalement nouveau au golf, mais je trouve ça un défi amusant

Enregistré 4 octets grâce à la suggestion de Titus en utilisant une boucle for.

base non golfée:

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

Version golfée

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

Je suis ouvert aux suggestions pour l'améliorer / apprendre le golf

testeur d'entrée


1
Vous pouvez enregistrer deux octets avec une forboucle: for(o=i=30;i>2;console.log(...)){...}. Et en combinant les deux affectations de broyage en une seule, vous pouvez supprimer les accolades: i=i/4<<1;(-5). Je ne sais pas si i=i/4*2;cela fera de même.
Titus

1
Je parie que vous n’avez pas testé cela.
Titus

pas encore, a dû courir à partir du PC pour attraper mes enfants
Tschallacka

1

BASH, 81 octets

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 octets

func g(n:Int){var n=n,i=2;while n>2{n=n/4*2;print(Array(repeating:n,count:i));i*=2}}

Non golfé

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 octets

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

Essayez-le en ligne!

Explication

&           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 octets

Premier code de golf, pensais que j'aurais un essai. (Ce n'est pas très bon).

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

Non minifié:

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);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.