Buat batu besar menjadi batu kecil


22

Selamat datang di penggiling.

Tugas Anda adalah membuat batu besar menjadi batu kecil dengan menggilingnya.

Ambil input batu besar n > 3 dan giling.

Lanjutkan untuk menggiling batu dengan membuangnya ke penggiling sampai ukuran semua batu 2.

batu selalu digiling menjadi sama rata. Jika hasil penggilingan aneh, ambil hasil - 1.

Cetak output masing-masing penggilingan saat Anda melanjutkan.

Contohnya

memasukkan: 5

keluaran: 22

Hasilnya adalah dua batu ukuran 2

memasukkan: 50

keluaran:

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

hasilnya adalah 16 batu ukuran 2

memasukkan: 30

keluaran:

1414
6666
22222222

hasilnya adalah 8 batu ukuran 2

Ini adalah sehingga kode terpendek menang! Selamat bersenang-senang dan semoga berhasil!


Anda dapat mengharapkannya berada di atas 3.
jacksonecac

Apakah kita harus menggunakan format Anda (semua angka digabungkan) atau bisakah kita menggunakan hal-hal seperti daftar? Beberapa jawaban tampaknya melakukan itu sebagai gantinya.
Fatalkan

Selama output menampilkan setiap iterasi, formatnya tidak harus seperti di atas.
jacksonecac

1
Saya akan mengatakan array 2d tidak dan 1d tidak, tapi itu terserah Anda.
Jonathan Allan

1
@ user902383 baik-baik saja kecuali dinyatakan dalam tantangan sesuai konsensus meta . Adapun input dan output, lagi-lagi keduanya baik-baik saja - lihat posting ini .
Jonathan Allan

Jawaban:



8

SAPI, 297 291 byte

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Cobalah online!

Kode mencetak setiap angka pada barisnya sendiri, dan memisahkan iterasi dengan baris baru tambahan. Ini juga mencetak iterasi pertama dengan sendirinya, diikuti oleh baris baru. Jadi input 5 akan memberikan output yang terlihat seperti 5 2 2kecuali dengan baris baru, bukan spasi. Contoh output untuk 50diberikan di bawah ini.

Pohon penjelasan:

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

Output sampel untuk input 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
Saya tidak punya kata
jacksonecac

Saya masih tidak memiliki kata
jacksonecac

Saya tidak punya kata
Edeki Okoh

Saya suka bagaimana dua setengah tahun kemudian, ini masih menakutkan orang.
Gabriel Benamy

7

05AB1E , 12 11 byte

¸[4÷·€D=¬<#

Cobalah online!

Penjelasan

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

Bagi dengan 4 dan shift kiri oleh 1 untuk mendapatkan divisi khusus


4

Haskell, 75 71 60 50 47 byte

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

Cobalah online! Sunting: Karena output sekarang diizinkan menjadi daftar termasuk input, 10 13 byte dapat disimpan.

Pemakaian:

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

Versi 60 byte asli:

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

Cobalah online! Terima kasih kepada Christian Sievers karena menunjukkan formula yang lebih pendek.

Pemakaian:

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

Anda bisa melakukannya z<-2*div n 4.
Christian Sievers

3

JavaScript (ES6) 64 59 57 Bytes

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


jika saya memasukkan kode Anda ke mothereff.in/byte-counter saya mendapatkan 59 byte?
Tschallacka

@ Schallacka Saya pikir f=tetapi hanya untuk demo
LarsW

Ah, baiklah. Itu membuatnya jelas :-) masih harus mendapatkan 2 byte dari saya kemudian
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*2akan bekerja untuk menghemat 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;}

Menguji dan tidak berkhianat

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

Catatan: Saya tidak tahu mengapa, Ideone terus memberikan kesalahan internal, jadi mengujinya adalah masalah. Untuk mengujinya, cukup salin / tempel dan jalankan di IDE Java standar Anda. (Ini berfungsi di sana, saya memastikannya;))


ideone berfungsi baik dengan kode Anda. Terkadang memberikan kesalahan internal ketika mereka melakukan pemeliharaan (saya pikir). Saya sudah pernah melakukannya ketika saya melihat kembali jawaban lama saya. +1 btw, saya tidak melihat apa pun yang bisa lebih golf. Oh, dan aku suka n=n/4*2tipuanmu. :)
Kevin Cruijssen

3

C #, 88 86 83 byte

Disimpan 3 byte berkat Skorm

Menyimpan byte lain dengan mengubah whileke forloop yang menyertakan deklarasi variabel

Disimpan 1 byte berkat 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;};

Fungsi anonim yang mengembalikan string yang terdiri dari hasil masing-masing penggilingan.

Program penuh dengan metode ungolfed dan uji kasus [sebelum edit terakhir!]:

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
Pikirkan Anda dapat menyimpan 1 byte dalam for loop dengan melakukanfor(i=0;i++<c;)
Yodle

Anda masih dapat menyimpan 1 byte, seperti yang disebutkan sebelumnya dengan mengubah detik Anda menjadifor (i = 0; i++ < c;)
MX D

Lupa memperbarui pos. Diperbarui sekarang :)
adrianmp

1
Anda dapat memperbarui penghitung Anda mulai dari 2 dan * = 2 setiap iterasi untuk menghemat 1 byte, dan memindahkan baris tambahan ditambahkan. Anda kemudian dapat memindahkan n = n / 4 * 2 ke loop kedua dan menghapus kawat gigi untuk menyimpan 2 lagi. 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;

Cobalah online! (Sebagai suite uji.)

Penjelasan

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

* \nadalah
penjelasan baris baru :

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

Coba di sini


2

MATL , 13 byte

`K/kEthttH>]x

Cobalah 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";

Mengambil argumen dari baris perintah. Jalankan dengan -r.


2

Jelly , 13 12 11 byte

:4Ḥx2µȦпṖY

TryItOnline!

Catatan: OP menyatakan bahwa input mungkin juga dalam output.

Bagaimana?

: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

Versi tanpa input ditampilkan untuk 12 byte: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 byte

Jalankan dengan -nbendera

-4 byte terima kasih kepada @Dada

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

Cobalah online!

Perl secara otomatis membaca input ke dalam variabel $_ketika -ndiatur. $.adalah variabel khusus yang diset 1pada awal program oleh penerjemah, jadi saya dapat menggunakannya sebagai basis untuk penggandaan. Setiap iterasi dari whileloop, bit-bergeser $_ke bawah dan melakukan logika AND terhadap yang negatif itu sendiri dikurangi satu untuk membatalkan bit yang.


Anda dapat golf hingga 31 byte: perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'(mungkin ini bisa golf lebih jauh, saya tidak menghabiskan banyak waktu di atasnya).
Dada

2

PowerShell 3+, 58 54 byte

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

Terima kasih TimmyD karena telah menyelamatkan saya 4 byte!

Slightly Ungolfed (pemformatan)

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

Penjelasan

Saya menggunakan pembagian yang sama dengan 4 kali lipat dengan 2 trik seperti banyak jawaban lainnya, tetapi saya mengalami masalah. PowerShell mengonversi angka menjadi floating point jika diperlukan selama pembagian, dan untuk bermain golf itu menjengkelkan karena $v/4*2menjadi sesuatu yang tidak disukai [int]($v/4)*2. Saya berhasil menggunakan bitshifting untuk divisi dengan -shr.

Untuk menghitung berapa kali untuk mencetak iterasi saya hanya mengambil (2^$i)-1yang berfungsi dengan baik dan memiliki efek tambahan meninggalkan nilai input. Mencoba untuk hanya mengalikan dengan 2 itu bermasalah karena mulai dari 0 membuatnya sulit untuk meningkatkan nilai hanya dengan $i*=2dan mulai dari 1 memerlukan terlalu banyak koreksi untuk mendapatkan angka yang benar.

Karena PowerShell tidak memiliki operator untuk itu, dan saya ingin menghindarinya [Math]::Pow(), saya mengandalkan bitshifting lagi untuk kekuatan 2 saya.


@TimmyD whoops lupa menyebutkan versi, dan tip yang bagus; Terima kasih!
briantist

1

Python 2, 47 Bytes

Karena OP mengatakan bahwa array 1D yang memasukkan input baik-baik saja saya telah datang dengan fungsi rekursif ini, yang sayangnya hanya terkait dengan pemenang Python saat ini.

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

1

Perl, 47 byte

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

Tidak ada opsi baris perintah, kali ini (tidak biasa untuk Perl). Gagasan dasarnya adalah karena semua batu pada langkah tertentu memiliki ukuran yang sama, kami hanya merekam ukuran (dalam $a) dan nomor (dalam $_), daripada mencatat seluruh daftar. Saya tidak bisa menemukan cara untuk menyingkirkan ruang (atau +) setelah say; Anda dapat memindahkan2* tetapi tidak akan diuraikan dengan benar jika diikuti oleh tanda kurung buka.

Saya tidak bisa menahan perasaan bahwa ini tidak bisa diperbaiki, tetapi saya tidak bisa melihat caranya.


Jika saya mencoba golf terlalu banyak, saya berakhir dengan jawaban Gabriel Benamy setiap waktu. Hanya untuk menunjukkan beberapa langkah: yang diejelas terasa kurang optimal. Tapi kita masih perlu cara untuk memeriksa apakah kita perlu berhenti atau tidak -> solusi adalah dengan menggunakan sementara bukan for: while$a>1. Tetapi kita perlu menemukan pengganti untuk $_: variabel unit mana pun dapat melakukannya: ganti 1<<$_oleh 1<<++$x. Jadi sekarang $_bebas untuk digunakan, kita dapat menggunakan -ndan mengganti setiap $adengan $_, dan instruksi pertama menjadi $_>>=1. Karena kita sudah -n, $.sudah diatur, jadi kita bisa ganti 1<<++$ldengan $.*=2.
Dada

Melakukan semua modifikasi itu akan menghasilkan perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 byte). Kemudian perhatikan bahwa $_>>=1dilakukan dua kali, sehingga kita dapat mencoba untuk menyingkirkan satu (yang pertama). Mencoba menyingkirkannya, saya dapat say$_ x($.*=2)while($_>>=1)/2>1(menempatkan keduanya dalam whilekondisi). Tetapi hasilnya salah ( $_bisa ganjil), dan mencoba memastikan itu genap, saya berakhir dengan while$_=$_>>1&~1. Jadi kodenya sekarang say$_ x($.*=2)while($_=$_>>1&~1).
Dada

Saya rindu bahwa sudah ada jawaban Perl. Saya kira jika pegolf ini mengubahnya menjadi duplikat, tidak ada gunanya mengeditnya. Di sisi lain, itu sebenarnya tidak salah, jadi tidak ada gunanya menghapusnya juga. Kami mungkin yang terbaik hanya meninggalkannya sebagai bukti kekuatan golf Perl saya yang lebih rendah.

Saya setuju, itu cukup berbeda dari solusi Perl lainnya, dan dengan komentar saya sebelumnya, saya mencoba menunjukkan bahwa satu-satunya cara saya bisa golf itu akan mengubahnya menjadi solusi lain. Jadi membiarkannya seperti itu terasa seperti solusi yang tepat.
Dada

1

Vim 61 54 byte

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

TryItOnline!

Tidak dapat dicetak:

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

Untungnya vim otomatis terpotong pada x / 2.


1

JavaScript, 71 63 59 58 Bytes

Yah, saya datang dengan solusi javascript ini. Benar-benar baru dalam bermain golf, tetapi saya menganggap ini tantangan yang menyenangkan

Disimpan 4 byte berkat saran Titus menggunakan for for loop.

dasar tanpa serigala:

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

Versi golf

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

Saya terbuka untuk saran bagaimana memperbaikinya / belajar golf

input tester


1
Anda dapat menyimpan dua byte dengan forlingkaran: for(o=i=30;i>2;console.log(...)){...}. Dan dengan menggabungkan dua tugas penggilingan menjadi satu, Anda dapat menghapus kawat gigi: i=i/4<<1;(-5). Tidak yakin apakah i=i/4*2;akan melakukan hal yang sama.
Titus

1
Saya yakin Anda belum mengujinya.
Titus

belum, harus lari dari pc untuk menangkap anak-anak saya
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

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

Tidak disatukan

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

Cobalah online!

Penjelasan

&           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

Golf kode pertama, kupikir aku harus mencobanya. (Tidak terlalu bagus).

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

Tidak dijinakkan:

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);
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.