Trasforma le grandi rocce in piccole rocce


22

Benvenuto nella smerigliatrice.

Il tuo compito è quello di trasformare grandi rocce in piccole rocce macinandole.

Prendi un input di una grande roccia di dimensioni n > 3 e macinalo.

Continua a macinare le rocce scaricandole nel macinacaffè fino a quando le dimensioni di tutte le rocce sono 2.

le rocce sono sempre macinate in metà uguali. Se il risultato di una macinatura è dispari, prendi risultato - 1.

Stampa l'output di ogni rettifica mentre procedi.

Esempi

ingresso: 5

produzione: 22

Il risultato sono due rocce di dimensione 2

ingresso: 50

produzione:

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

il risultato è 16 rocce di dimensione 2

ingresso: 30

produzione:

1414
6666
22222222

il risultato è 8 rocce di dimensione 2

Questo è quindi vince il codice più corto! Buon divertimento e buona fortuna!


Puoi aspettarti che sia sopra il 3
jacksonecac il

Dobbiamo usare il tuo formato (tutti i numeri concatenati) o possiamo usare cose come le liste? Alcune risposte sembrano invece farlo.
Fatalizza il

Finché l'output mostra ogni iterazione, il formato non deve essere come sopra.
jacksonecac,

1
Direi che un array 2d lo fa e un 1d no, ma dipende da te.
Jonathan Allan,

1
Anche @ user902383 va bene se non specificato nella sfida come da meta consenso . Per quanto riguarda l'input e l'output, entrambi vanno bene - vedi questo post .
Jonathan Allan,

Risposte:



8

MUCCA, 297 291 byte

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Provalo online!

Il codice stampa ogni numero sulla propria riga e separa le iterazioni con una nuova riga aggiuntiva. Stampa anche la prima iterazione da sola, seguita da una nuova riga. Quindi un input di 5 darebbe un output simile a quello 5 2 2con le newline invece degli spazi. Di 50seguito viene fornito un esempio di output per .

Albero di spiegazione:

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

Uscita di esempio per l'ingresso 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
Non ho parole
jacksonecac il

Non ho ancora parole
jacksonecac,

Non ho parole
Edeki Okoh

Adoro come due anni e mezzo dopo, questo terrorizza ancora le persone.
Gabriel Benamy,

7

05AB1E , 12 11 byte

¸[4÷·€D=¬<#

Provalo online!

Spiegazione

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

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

Dividi per 4 e sposta a sinistra per 1 per ottenere la divisione speciale


4

Haskell, 75 71 60 50 47 byte

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

Provalo online! Modifica: poiché ora è consentito che l'output sia un elenco che include l'input, possibile salvare 10 13 byte.

Uso:

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

Versione originale a 60 byte:

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

Provalo online!Grazie a Christian Sievers per aver sottolineato la formula più breve.

Uso:

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

Puoi solo fare z<-2*div n 4.
Christian Sievers,

3

JavaScript (ES6) 64 59 57 byte

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


se inserisco il tuo codice in mothereff.in/byte-counter ottengo 59 byte?
Tschallacka,

@Tschallacka Penso che il f=ma sia solo per la demo
LarsW

Ah ok. Ciò rende chiaro :-) ancora devo avere 2 byte fuori myne poi
Tschallacka

3

Python 2, 48 47 byte

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

s=s/4*2funzionerà per il salvataggio di 1 byte.
Jonathan Allan,

3

Java, 85 byte

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

Nota: non so perché, Ideone continua a dare errori interni, quindi test su di esso è un problema. Per testare, basta copiare / incollare ed eseguire l'IDE Java standard. (Funziona lì, me ne sono assicurato;))


ideone funziona bene con il tuo codice. A volte danno un errore interno quando fanno manutenzione (penso). L'avevo già visto quando ho guardato indietro alle mie vecchie risposte. +1 a proposito, non vedo nulla che possa essere golfato di più. Oh, e mi piace il tuo n=n/4*2trucco. :)
Kevin Cruijssen il

3

C #, 88 86 83 byte

Salvato 3 byte grazie a Skorm

Ho salvato un altro byte cambiando whilein afor ciclo che include dichiarazioni di variabili

Salvato 1 byte grazie a 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;};

Funzione anonima che restituisce una stringa composta dal risultato di ogni rettifica.

Programma completo con metodo non golfizzato e casi di test [prima dell'ultima modifica!]:

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
Pensa di poter salvare 1 byte nel ciclo for facendofor(i=0;i++<c;)
Yodle

Puoi ancora salvare 1 byte, come hai già detto cambiando il tuo secondo infor (i = 0; i++ < c;)
MX D

Hai dimenticato di aggiornare il post. Aggiornato ora :)
adrianmp il

1
Puoi aggiornare il tuo contatore per iniziare da 2 e * = 2 ogni iterazione per salvare 1 byte e spostare la nuova riga aggiunta. È quindi possibile spostare n = n / 4 * 2 nel secondo loop e rimuovere le parentesi graffe per salvarne altri 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 byte

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

Provalo online! (Come una suite di test.)

Spiegazione

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 byte

WhQ=Q*2my/d4\n

* \nè una nuova riga
Spiegazione:

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

Prova qui


2

MATL , 13 byte

`K/kEthttH>]x

Provalo 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 byte

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

Prende argomento dalla riga di comando. Corri con -r.


2

Gelatina , 13 12 11 byte

:4Ḥx2µȦпṖY

TryItOnline!

Nota: l'OP ha dichiarato che l'ingresso potrebbe anche essere nell'uscita.

Come?

: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

Versione senza input visualizzato per 12 byte: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 byte

Corri con la -nbandiera

-4 byte grazie a @Dada

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

Provalo online!

Perl legge automaticamente l'input nella variabile $_quando -nè impostato. $.è una variabile speciale impostata 1all'inizio del programma dall'interprete, quindi posso usarla come base per il raddoppio. Ogni iterazione del whileloop si sposta $_verso il basso ed esegue un AND logico contro il negativo di se stesso meno uno per cancellare quei bit.


Puoi giocare a golf fino a 31 byte: perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'(forse questo può essere golfato ancora di più, non ci ho passato molto tempo).
Dada,

2

PowerShell 3+, 58 54 byte

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

Grazie TimmyD per avermi salvato 4 byte!

Ungolfed leggermente (formattazione)

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

Spiegazione

Sto usando la stessa divisione per 4 moltiplicare per 2 prese come molte altre risposte, ma ho riscontrato un problema. PowerShell converte i numeri in virgola mobile, se necessario, durante la divisione e per il golf è fastidioso perché $v/4*2diventa qualcosa di non illuminante [int]($v/4)*2. L'ho aggirato usando bitshifting per la divisione con -shr.

Per calcolare quante volte stampare un'iterazione prendo semplicemente (2^$i)-1che funziona bene e ha l'effetto aggiunto di tralasciare il valore di input. Cercare di moltiplicare per 2 era problematico perché a partire da 0 rende difficile aumentare il valore con just $i*=2e a partire da 1 richiede troppa correzione per ottenere il numero giusto.

Poiché PowerShell non ha un operatore per questo, e volevo evitarlo [Math]::Pow(), mi sono affidato nuovamente al bitshifting per i miei poteri di 2.


@TimmyD whoops ha dimenticato di menzionare la versione e un buon consiglio; Grazie!
Briantist,

1

Python 2, 47 byte

Dato che l'OP ha affermato che un array 1D che includeva l'input andava bene, ho sviluppato questa funzione ricorsiva, che purtroppo si lega solo all'attuale vincitore di 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[]) per 46
Jonathan Allan,

1

Perl, 47 byte

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

Nessuna opzione da riga di comando, questa volta (insolitamente per Perl). L'idea di base è che, dato che tutte le rocce in un determinato passaggio hanno le stesse dimensioni, registriamo solo le dimensioni (in $a) e il numero (in $_), anziché registrare l'intero elenco. Non sono riuscito a trovare un modo per liberarmi dello spazio (o +) dopo say; puoi spostare il 2*ma non analizzerà correttamente se è seguito da una parentesi aperta.

Non posso fare a meno di scuotere la sensazione che ciò sia migliorabile, ma non riesco a vedere come.


Se provo a giocarci troppo, finisco sempre con la risposta di Gabriel Benamy. Giusto per mostrare alcuni passaggi: la diesensazione chiaramente non è ottimale. Ma abbiamo ancora bisogno di un modo per controllare se abbiamo bisogno di fermarsi o meno -> una soluzione è quella di utilizzare un po 'al posto del for: while$a>1. Ma dobbiamo trovare un sostituto per $_: qualsiasi variabile unitaria può farlo: sostituire 1<<$_con 1<<++$x. Quindi ora $_è libero di essere usato, quindi possiamo usare -ne sostituire ognuno $acon un $_, e la prima istruzione diventa $_>>=1. Dal momento che abbiamo -n, $.è impostato, quindi possiamo sostituirlo 1<<++$lcon $.*=2.
Dada,

Fare tutte quelle modifiche produrrà perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 byte). Quindi notare che $_>>=1viene fatto due volte, quindi possiamo provare a sbarazzarci di uno (il primo). Cercando di liberarmene, ho ottenuto say$_ x($.*=2)while($_>>=1)/2>1(mettendoli entrambi nella whilecondizione). Ma il risultato è sbagliato ( $_può essere strano) e, cercando di assicurarmi che sia pari, alla fine while$_=$_>>1&~1. Quindi il codice è ora say$_ x($.*=2)while($_=$_>>1&~1).
Dada,

Mi mancava che ci fosse già una risposta al Perl. Immagino che se questo golf lo trasforma in un duplicato, non ha molto senso modificarlo. D'altra parte, in realtà non è sbagliato, quindi non ha molto senso eliminarlo. Probabilmente è meglio lasciarlo solo come testimonianza dei miei poteri di golf Perl inferiori.

Sono d'accordo, è abbastanza diverso dall'altra soluzione Perl, e con i miei commenti precedenti, ho provato a dimostrare che l'unico modo in cui avrei potuto giocare a golf lo avrebbe trasformato nell'altra soluzione. Quindi lasciarlo così com'è sembra la soluzione giusta.
Dada,

1

Vim 61 54 byte

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

Fortunatamente vim si tronca automaticamente su x / 2.


1

JavaScript, 71 63 59 58 byte

Bene, ho trovato questa soluzione javascript. Totalmente nuovo nel golf, ma ho trovato questa una sfida divertente

Salvato 4 byte grazie al suggerimento Titus usando un ciclo for.

base non golfata:

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

Versione golfizzata

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

Sono aperto a suggerimenti su come migliorarlo / imparare a giocare a golf

tester di input


1
È possibile salvare due byte con un forciclo: for(o=i=30;i>2;console.log(...)){...}. E combinando le due configurazioni di rettifica in una, è possibile rimuovere le parentesi graffe: i=i/4<<1;(-5). Non sono sicuro se i=i/4*2;farà lo stesso.
Tito

1
Scommetto che non l'hai provato.
Tito

non ancora, sono dovuto scappare dal PC per catturare i miei figli
Tschallacka,

1

BASH, 81 byte

n=$1
h=1
while [ ${n//2} ];do
printf -v s %$[h=h*2]s
echo ${s// /$[n=n/4*2]}
done

1

Rapido, 84 byte

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 byte

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

Provalo online!

Spiegazione

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

Primo codice golf, ho pensato di provare. (Non è molto buono).

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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.