Küçük kayalara büyük kayalar yapın


22

Öğütücüye hoş geldiniz.

Senin görevin büyük kayaları öğüterek küçük kayalara dönüştürmektir.

Büyük bir kayanın bir girdisini alın n > 3 ve eziyet edin.

Kayaları öğütmeye devam ederek tüm kayaların büyüklüğü kadar öğütmeye devam edin 2.

kayalar daima eşit yarıya öğütülür. Bir taşlama sonucu tuhafsa, sonucu alın - 1.

İlerlerken her taşlamanın çıktısını yazdırın.

Örnekler

giriş: 5

çıktı: 22

Sonuç 2 büyüklüğünde iki kaya

giriş: 50

çıktı:

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

sonuç 2 büyüklüğünde 16 kaya

giriş: 30

çıktı:

1414
6666
22222222

sonuç 8 büyüklükte 8 kayalar

Bu yani en kısa kod kazanır! Eğlenmene bak ve iyi şanslar!


3'ün üstünde olmasını bekleyebilirsiniz.
jacksonecac

Formatınızı mı kullanmak zorundayız (birleştirilmiş tüm sayılar) yoksa listeler gibi şeyleri kullanabilir miyiz? Bazı cevaplar bunun yerine öyle görünüyor.
Aralık’ta

Çıktı her yinelemeyi gösterdiği sürece, formatın yukarıdaki gibi olması gerekmez.
jacksonecac 14

1
Bir 2d dizi yapar ve bir 1d olmaz derdim, ama bu size kalmış.
Jonathan Allan,

1
@ user902383 ya da meta konsensüs uyarınca zorlukta belirtilmediği sürece iyidir . Giriş ve çıkış gelince, yine ikisi de iyi - bu yazıya bakın .
Jonathan Allan,

Yanıtlar:



8

COW, 297 291 bayt

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

Çevrimiçi deneyin!

Kod her numarayı kendi satırına basar ve yinelemeleri ek bir yeni satırla ayırır. Ayrıca, ilk yinelemeyi kendi başına yazdırır, ardından yeni bir satır yazar. Böylece 5 girişi 5 2 2boşluk yerine yeni satırlar dışında görünen bir çıktı verir . İçin örnek çıktı 50aşağıda verilmiştir.

Açıklama ağacı:

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

50 girişi için örnek çıktı:

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
Hiçbir
sözüm

Hala bir
sözüm

Hiçbir
sözüm

İki buçuk yıl sonra, bunun hala insanları nasıl korkuttuğunu seviyorum.
Gabriel Benamy

7

05AB1E , 12 11 bayt

¸[4÷·€D=¬<#

Çevrimiçi deneyin!

açıklama

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

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

Özel bölümü elde etmek için 4'e bölün ve 1'e kaydırın


4

Haskell, 75 71 60 50 47 bayt

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

Çevrimiçi deneyin! Düzenleme: Çıktının şimdi girişi içeren bir liste olmasına izin verildiğinden, 10 13 bayt kaydedilebilir.

Kullanımı:

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

Orijinal 60 bayt sürümü:

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

Çevrimiçi deneyin! Kısa formülü işaret ettiği için Christian Sievers'e teşekkürler.

Kullanımı:

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

Sadece yapabilirsin z<-2*div n 4.
Christian Sievers


3

Python 2, 48 47 bayt

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

s=s/4*21 bayt kaydetme için çalışacak.
Jonathan Allan,

3

Java, 85 bayt

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 ve iğrenç

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

Not: Nedenini bilmiyorum, Ideone sürekli iç hata veriyor, bu yüzden üzerinde test yapmak sorun. Test etmek için, kopyalayıp yapıştırın ve standart Java IDE'nizde çalıştırın. (Orada çalışıyor, bundan emin oldum;))


ideone kodunuzla iyi çalışır. Bakım yaparken iç hata veren somtimes (sanırım). Eski cevaplarıma bakarken daha önce de yaşadım. +1 btw, daha fazla golf oynayabilecek hiçbir şey göremiyorum. Oh, ve n=n/4*2numaranı beğendim . :)
Kevin Cruijssen

3

C #, 88 86 83 bayt

Skorm sayesinde 3 bayt kurtarıldı

Değişken bildirimleri içeren whilebir fordöngüye değiştirerek başka bir bayt kaydedildi

Yodle sayesinde 1 bayt kaydedildi

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

Her taşlamanın sonucundan oluşan bir dize döndüren adsız işlev.

Ungolfed yöntemi ve test vakaları ile tam program [son düzenlemeden önce!]:

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
Yaparak for döngüsünde 1 byte tasarruf edebileceğinizi düşününfor(i=0;i++<c;)
Yodle

Saniyenizi 15: 54'tefor (i = 0; i++ < c;)
MX D

Gönderiyi güncellemeyi unuttum. Şimdi güncellendi :)
adrianmp

1
Sayacınızı 1 bayttan tasarruf etmek için her yinelemede 2 ve * = 2 ile başlatabilir ve yeni satır ekini taşıyabilirsiniz. Daha sonra n = n / 4 * 2'yi ikinci döngüye taşıyabilir ve 2 tane daha tasarruf etmek için parantezleri kaldırabilirsiniz. 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 bayt

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

Çevrimiçi deneyin! (Test takımı olarak.)

açıklama

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 bayt

WhQ=Q*2my/d4\n

* \nyeni bir satırdır
Açıklama:

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

Burada dene


2

MATL , 13 bayt

`K/kEthttH>]x

Çevrimiçi deneyin!

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

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

Komut satırından argüman alır. İle koş -r.


2

Jöle , 13 12 11 bayt

:4Ḥx2µȦпṖY

TryItOnline!

Not: OP, girişin de çıkışta olabileceğini belirtti.

Nasıl?

: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

12 bayt için görüntülenen girişi olmayan sürüm: :4Ḥḟ0x2µÐĿḊG


2

Perl, 40 35 30 + 1 = 31 bayt

-nBayrakla koş

@Dada sayesinde -4 bayt

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

Çevrimiçi deneyin!

Perl otomatik değişkene giriş okur $_zaman -nayarlanır. tercüman tarafından programın başında $.ayarlanmış özel bir değişkendir 1, bu yüzden onu iki katına çıkarmak için bir üs olarak kullanabilirim. whileDöngünün her yinelemesi, bit kaydırır $_ve bir bitini iptal etmek için bir eksi negatifine karşı mantıklı bir VE gerçekleştirir.


31 byte'a kadar golf oynayabilirsiniz: perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'(belki bu daha da golf oynayabilir, üzerinde çok fazla zaman harcamamış olabilirim).
Dada

2

PowerShell 3+, 58 54 bayt

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

Beni 4 bayt kurtardığın için teşekkürler TimmyD !

Biraz Ungolfed (biçimlendirme)

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

açıklama

Aynı cevabı, diğer cevapların çoğunda olduğu gibi 4 ile 2 ile 2 ile çarpıyorum, ancak bir sorunla karşılaştım. PowerShell, bölme sırasında gerektiğinde sayıları kayan noktaya dönüştürür ve rahatsız edici golf $v/4*2oynamak için hoş olmayan bir şey olur çünkü [int]($v/4)*2. Bunun için bölünme uçlarını değiştirmeyi bildim -shr.

Bir yinelemenin kaç kez yazdırılacağını hesaplamak için sadece (2^$i)-1güzel bir şekilde çalışan ve girdi değerini dışarıda bırakma etkisine sahip olan sadece alıyorum . Sadece 2 ile çarpmaya çalışmak sorunluydu çünkü 0'dan başlamak, değeri sadece ile arttırmayı zorlaştırıyor $i*=2ve 1'den başlamak, sayıyı düzeltmek için çok fazla düzeltme gerektiriyor.

PowerShell'de bunun için bir operatör olmadığından ve kaçınmak istediğim için [Math]::Pow(), yine 2 gücüm için bit değişmesine güvenmiştim.


@TimmyD sürümünden söz etmeyi unuttu ve iyi bir ipucu; Teşekkürler!
Britanist 19

1

Python 2, 47 Bayt

OP, girişi içeren bir 1D dizisinin iyi olduğunu söylediğinden beri, bu özyinelemeli fonksiyon ile karşılaştım, bu ne yazık ki sadece şu anki Python kazananı ile bağdaştırıyor.

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

1

Perl, 47 bayt

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

Bu sefer komut satırı seçeneği yok (alışılmadık şekilde Perl için). Temel fikir, herhangi bir adımdaki tüm kayaların aynı boyutta olması nedeniyle, tüm listeyi kaydetmek yerine sadece boyutu (inç $a) ve sayıyı (inç $_) kaydederiz. Uzaydan (veya +) sonra kurtulmak için bir yol bulamadım say; hareket ettirebilirsiniz, 2*ancak açma parantezi ile takip edilirse doğru şekilde ayrıştırılmaz.

Yardım edemem ama bunun iyileştirilebilir olduğu hissini sallayın, ama nasıl göremiyorum.


Çok fazla golf oynamayı denersem, sonunda Gabriel Benamy'nin cevabını veririm. Sadece birkaç adım göstermek için: dieaçıkça alt-optimal hissediyor. Fakat yine de durup durmayacağımızı kontrol etmenin bir yoluna ihtiyacımız var -> bir çözüm for: yerine bir süre kullanmaktır while$a>1. Ama biz yerine birini bulmalıyız $_: Herhangi unitialized değişken yapabilirsiniz: yerine 1<<$_göre 1<<++$x. Yani şimdi $_kullanmakta özgürdür, daha sonra -nher birini a $aile kullanabilir ve değiştirebiliriz $_ve ilk talimat olur $_>>=1. Biz bu yana -n, $.ayarlanır, bu yüzden yerini alabilir 1<<++$lile $.*=2.
Dada

Tüm bu değişikliklerin yapılması perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39 bayt) üretecektir . Öyleyse bunun $_>>=1iki kez yapıldığına dikkat edin , böylece birinden kurtulmaya çalışabiliriz (birincisi). Ondan kurtulmaya çalışırken, aldım say$_ x($.*=2)while($_>>=1)/2>1(ikisini de whileduruma soktum). Ama sonuç yanlıştır ( $_tuhaf olabilir) ve sonuçta eşit olduğundan emin olmaya çalışıyorum while$_=$_>>1&~1. Yani kod şimdi say$_ x($.*=2)while($_=$_>>1&~1).
Dada

Zaten bir Perl cevabı olduğunu özledim. Sanırım bu golf oynamak, onu bir kopya haline getirirse, düzenlemede fazla bir nokta yoktur. Öte yandan, aslında yanlış değil, yani onu silmenin de anlamı yok. Muhtemelen aşağılık Perl golf güçlerimin bir kanıtı olarak bırakarak en iyisiyiz.

Kabul ediyorum, diğer Perl çözümünden yeterince farklı ve önceki yorumlarımla golf yapabilmemin tek yolunun bunu diğer çözüme dönüştüreceğini göstermeye çalıştım. Bu yüzden doğru çözüm gibi hissettirdiği gibi bırakarak.
Dada

1

Vim 61 54 bayt

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

Neyse ki vim otomatik olarak x / 2'de kesiliyor.


1

JavaScript, 71 63 59 58 Bayt

Ben bu javascript çözümü ile geldi. Golf sahasında tamamen yeni, ancak bunu eğlenceli bir meydan okuma olarak öğrendim

Bir for döngüsü kullanan Titus önerisi sayesinde 4 bayt kaydedildi.

asılsız temel:

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

Golf versiyonu

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

Nasıl geliştirileceğini / golf oynamayı önerebileceğim önerilerime açığım

giriş test cihazı


1
Bir iki bayt kaydedebilirsiniz fordöngü: for(o=i=30;i>2;console.log(...)){...}. Ve iki öğütme tertibatını bire birleştirerek, diş tellerini çıkarabilirsiniz: i=i/4<<1;(-5). i=i/4*2;Aynısını yapacak mı emin değilim .
Titus,

1
Bahse girerim bunu test etmedin.
Titus,

henüz değil, çocuklarımı yakalamak için bilgisayardan kaçmak zorunda kaldım
Tschallacka

1

BASH, 81 bayt

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 Bayt

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 bayt

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

Çevrimiçi deneyin!

açıklama

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

İlk kod golf, gitmem gerektiğini düşündü. (Bu hiç iyi değil).

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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.