将大石头变成小石头


22

欢迎来到研磨机。

您的任务是通过研磨将大石头变成小石头。

输入一块大石头,n > 3 然后磨碎。

将岩石倒入研磨机继续研磨,直到所有岩石的大小达到极限2

岩石总是磨成相等的一半。如果研磨的结果是奇数,则取结果-1。

继续打印每个研磨的输出。

例子

输入: 5

输出: 22

结果是两个大小为2的岩石

输入: 50

输出:

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

结果是16个大小为2的岩石

输入: 30

输出:

1414
6666
22222222

结果是8个大小为2的岩石

这是所以最短的代码获胜!玩得开心,祝你好运!


你可以期望它是以上3
jacksonecac

我们必须使用您的格式(所有数字都连接在一起)还是可以使用列表之类的东西?有些答案似乎是这样做的。
致命

只要输出显示每次迭代,格式就不必像上面那样。
jacksonecac

1
我会说一个2d数组可以,一个1d数组不可以,但是这取决于您,所以确定。
乔纳森·艾伦

1
@ user902383也可以,除非根据meta共识在挑战中指定。至于输入和输出,两者都很好-参见这篇文章
乔纳森·艾伦

Answers:


12

TSQL,61 59字节

DECLARE @ int=50

,@x int=1WHILE @>2SELECT @=@/4*2,@x*=2PRINT replicate(@,@x)

试试看


8

COW,297291字节

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmoOMoOmoOmoOoommOoMoOMOOmoOMMMmoOMMMmoOOOOMoOmOoMOOMOomoOmoO
MOOMOomOoMOomoOmoomOoMMMOOOMoOmoOMMMmOomOomoomoOmoOMOOMOomOomOomOoMOomoOmoOmoOmoomOomOomOo
mOomOoMMMmoOMMMMOOMOomoOOOMmOomOoMoOmoOmoomOomOoMoomoOmoOmoOMOOMOoMOomoOMoOmOomoomoOMMMOOO
mOoMMMMMMmOoMMMMOomoo

在线尝试!

该代码将每个数字打印在自己的行上,并用附加的换行符分隔迭代。它还会自己打印第一个迭代,然后打印换行符。因此,输入5会得到类似于5 2 2换行符而不是空格的输出。的输出示例50如下。

说明树:

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的样本输出:

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
无话可说

我仍然
无话可说

我没有任何话
Edeki Okoh

我喜欢两年半之后,这仍然使人们感到恐惧。
加布里埃尔·贝纳米

7

05AB1E12 11字节

¸[4÷·€D=¬<#

在线尝试!

说明

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

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

除以4并左移1以得到特殊除法


4

Haskell,75 71 60 50 47字节

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

在线尝试!编辑:由于现在允许将输出作为包含输入的列表,因此可以保存10 13个字节。

用法:

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

原始60字节版本:

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

在线尝试!感谢Christian Sievers指出了较短的公式。

用法:

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

你可以做z<-2*div n 4
Christian Sievers,2016年

3

JavaScript(ES6)64 59 57字节

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


如果我将您的代码放入mothereff.in/byte-counter我会得到59个字节?
Tschallacka

@Tschallacka我认为,f=但是仅用于演示
LarsW

啊好吧。这很清楚:-)仍然必须从myne那里得到2个字节
Tschallacka


3

Java,85个字节

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

测试和取消高尔夫

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

注意:我不知道为什么,Ideone不断给出内部错误,因此对其进行测试是一个问题。要进行测试,只需复制/粘贴并在标准Java IDE中运行即可。(它在那里工作,我确定了;))


ideone与您的代码配合良好。在进行维护时,有时会出现内部错误(我认为)。当我回想起我的旧答案时,我曾经遇到过。+1顺便说一句,我看不到可以打更多的东西。哦,我喜欢你的n=n/4*2把戏。:)
凯文·克鲁伊森

3

C#,88 86 83个字节

由于Skorm,节省了3个字节

通过将更while改为for包含变量声明的循环来保存另一个字节

由于Yodle节省了1个字节

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

匿名函数,返回由每次研磨结果组成的字符串。

完整的程序,带有不完整的方法和测试用例(在最后一次编辑之前!):

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
认为您可以这样做for(i=0;i++<c;)
从而

您仍然可以保存1个字节,如前所述,将秒数更改为for (i = 0; i++ < c;)
MX D

忘记更新帖子。现在更新:)
adrianmp '16

1
您可以将计数器更新为从每次迭代2开始,并且* = 2,以节省1个字节,然后移动新行。然后,您可以将n = n / 4 * 2移到第二个循环中,并删除括号以节省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 '16

2

CJam,21个字节

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

在线尝试!(作为测试套件。)

说明

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字节

WhQ=Q*2my/d4\n

* \n是换行
说明:

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

试试这里


2

MATL,13字节

`K/kEthttH>]x

在线尝试!

`       % 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字节

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

从命令行获取参数。用运行-r


2

果冻13 12 11 字节

:4Ḥx2µȦпṖY

TryItOnline!

注意:OP指出输入也可能在输出中。

怎么样?

: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个字节: :4Ḥḟ0x2µÐĿḊG


2

Perl,40 35 30 +1 = 31字节

-n标志跑

-4字节感谢@Dada

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

在线尝试!

Perl的自动读取输入到变量$_-n被设置。 $.1解释器在程序开始时设置的特殊变量,因此我可以将其用作加倍的基础。循环的每次迭代都会while将其$_向下移位,并对自身的负数减1进行逻辑“与”运算,以抵消1位。


您可以perl -nE 'say$_ x($.*=2)while$_=$_>>1&~1'将其压缩为31个字节:(也许可以进行进一步的复制,我没有花很多时间在上面)。
达达

2

PowerShell 3 +,58 54字节

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

感谢TimmyD为我节省了4个字节!

略微偏离(格式化)

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

说明

我在其他许多答案中使用了相同的4除2技巧,但遇到了问题。PowerShell会在除法过程中根据需要将数字转换为浮点数,而对于高尔夫而言,这很烦人,因为它$v/4*2变得像令人讨厌的东西[int]($v/4)*2。我通过使用bitshifting进行除法来解决这个问题-shr

为了计算打印一次迭代的次数,我只是采取了(2^$i)-1很好的措施,并且省去了输入值。尝试仅乘以2是有问题的,因为从0开始很难用$i*=2而从1开始则需要太多的校正才能使数字正确。

由于PowerShell没有运算符,因此我想避免使用[Math]::Pow(),因此我再次依靠位移位来获得2的幂。


@TimmyD哎呀,忘了提到版本,还有很好的提示;谢谢!
briantist 2016年

1

Python 2,47字节

由于OP表示包含输入的1D数组很好,所以我想出了这个递归函数,不幸的是,它仅与当前的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[]) 46岁
乔纳森·艾伦

1

Perl,47个字节

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

这次没有命令行选项(对于Perl来说不常见)。基本思想是,由于任何给定步骤中的所有岩石都具有相同的大小,因此我们只记录大小(以表示$a)和数量(以表示$_),而不是记录整个列表。我找不到办法摆脱+后面的空间say。你可以移动2*但如果后面加上左括号,它将无法正确解析。

我忍不住觉得这是可以改进的,但是我看不出来。


如果我尝试打很多球,我每次都会得到加布里埃尔·贝纳米(Gabriel Benamy)的回答。仅显示一些步骤:die明显感觉不佳。但是,我们仍然需要一种方法来检查是否需要停止->解决方案是使用一阵子而不是forwhile$a>1。但是,我们需要找到一个替代品$_:任何未初始化变量可以做到这一点:更换1<<$_1<<++$x。因此,现在$_可以自由使用了,我们可以使用-n并替换$a$_,并且第一个指令变为$_>>=1。因为我们已经-n$.设置,所以我们可以更换1<<++$l使用$.*=2
达达

进行所有这些修改将产生perl -nE '$_>>=1;say 2*($_>>=1)x($.*=2)while$_>1'(39个字节)。然后注意$_>>=1完成两次,因此我们可以尝试摆脱一个(第一个)。试图摆脱它,我得到了say$_ x($.*=2)while($_>>=1)/2>1(将它们都放入while病情中)。但是结果是错误的($_可能是奇怪的),并且尝试确保它是偶数,我最终得到while$_=$_>>1&~1。所以现在是代码say$_ x($.*=2)while($_=$_>>1&~1)
达达

我错过了一个Perl的答案。我猜想如果把它打下来变成副本,那么编辑它没有多大意义。另一方面,这实际上并没有错,因此删除它也没有多大意义。我们最好还是保留它,以证明我的劣等Perl高尔夫球能力。

我同意,它与其他Perl解决方案足够不同,并且以我之前的评论,我试图证明,我打高尔夫球的唯一方法就是将其转变为其他解决方案。因此,将其保留为正确的解决方案。
达达

1

Vim 61 54字节

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

TryItOnline!

无法打印的内容:

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

幸运的是,vim会在x / 2上自动截断。


1

JavaScript,71 63 59 58字节

好吧,我想出了这个JavaScript解决方案。打高尔夫球完全是新手,但我觉得这是一个有趣的挑战

感谢Titus使用for循环的建议,节省了4个字节。

未打高尔夫球的基础:

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

高尔夫版

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

我愿意征求建议来改进它/学习打高尔夫球

输入测试仪


1
您可以使用for循环保存两个字节:for(o=i=30;i>2;console.log(...)){...}。通过将两个磨削组合组合为一个,可以卸下牙套:i=i/4<<1;(-5)。不知道是否i=i/4*2;会做同样的事情。
泰特斯(Titus)

1
我敢打赌,您还没有测试过。
泰特斯(Titus)

尚未,不得不从PC上赶下我的孩子
Tschallacka

1

BASH,81个字节

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

1

迅捷,84字节

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

不打高尔夫球

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个字节

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

在线尝试!

说明

&           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个字节

第一次打高尔夫球,以为我会去。(不是很好)。

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

未缩小:

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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.