您能停止再打牌再玩吗?


31

挑战:

输入:范围内的不同正整数的。[1,list-size]

输出:一个整数:列表被随机改组的次数。对于列表,这意味着将列表分为两半,并且将这两个半部分交织在一起(即,对列表进行[1,2,3,4,5,6,7,8,9,10]一次混码处理将导致[1,6,2,7,3,8,4,9,5,10],因此对于此挑战,输入[1,6,2,7,3,8,4,9,5,10]将导致1)。

挑战规则:

  • 您可以假设列表只包含范围内的正整数(如果选择索引为0的输入列表,则为)。[1,list-size][0,list-size1]
  • 您可以假定所有输入列表都是有效的浅滩混排列表,或者是未混排的排序列表(在这种情况下,输出为0)。
  • 您可以假设输入列表将至少包含三个值。

分步示例:

输入: [1,3,5,7,9,2,4,6,8]

对其进行重新整理就变成了:[1,5,9,4,8,3,7,2,6],因为每个偶数索引为0的项都首先出现[1, ,5, ,9, ,4, ,8],然后所有奇数索引为0的项都随之出现[ ,3, ,7, ,2, ,6, ]
该列表尚未订购,因此我们继续:

重新整理列表变得:[1,9,8,7,6,5,4,3,2]
再变成:[1,8,6,4,2,9,7,5,3]
然后:[1,6,2,7,3,8,4,9,5]
最后:[1,2,3,4,5,6,7,8,9],这是一个有序列表,所以我们完成了重新整理。

我们对原始信号进行了[1,3,5,7,9,2,4,6,8]5次改组以达到[1,2,3,4,5,6,7,8,9],因此5在这种情况下,输出为。

一般规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能短的答案。
  • 标准规则适用于具有默认I / O规则的答案,因此允许您使用STDIN / STDOUT,具有适当参数的函数/方法以及返回类型的完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接(即TIO)。
  • 另外,强烈建议为您的答案添加说明。

测试用例:

Input                                                   Output

[1,2,3]                                                 0
[1,2,3,4,5]                                             0
[1,3,2]                                                 1
[1,6,2,7,3,8,4,9,5,10]                                  1
[1,3,5,7,2,4,6]                                         2
[1,8,6,4,2,9,7,5,3,10]                                  2
[1,9,8,7,6,5,4,3,2,10]                                  3
[1,5,9,4,8,3,7,2,6,10]                                  4
[1,3,5,7,9,2,4,6,8]                                     5
[1,6,11,5,10,4,9,3,8,2,7]                               6
[1,10,19,9,18,8,17,7,16,6,15,5,14,4,13,3,12,2,11,20]    10
[1,3,5,7,9,11,13,15,17,19,2,4,6,8,10,12,14,16,18,20]    17
[1,141,32,172,63,203,94,234,125,16,156,47,187,78,218,109,249,140,31,171,62,202,93,233,124,15,155,46,186,77,217,108,248,139,30,170,61,201,92,232,123,14,154,45,185,76,216,107,247,138,29,169,60,200,91,231,122,13,153,44,184,75,215,106,246,137,28,168,59,199,90,230,121,12,152,43,183,74,214,105,245,136,27,167,58,198,89,229,120,11,151,42,182,73,213,104,244,135,26,166,57,197,88,228,119,10,150,41,181,72,212,103,243,134,25,165,56,196,87,227,118,9,149,40,180,71,211,102,242,133,24,164,55,195,86,226,117,8,148,39,179,70,210,101,241,132,23,163,54,194,85,225,116,7,147,38,178,69,209,100,240,131,22,162,53,193,84,224,115,6,146,37,177,68,208,99,239,130,21,161,52,192,83,223,114,5,145,36,176,67,207,98,238,129,20,160,51,191,82,222,113,4,144,35,175,66,206,97,237,128,19,159,50,190,81,221,112,3,143,34,174,65,205,96,236,127,18,158,49,189,80,220,111,2,142,33,173,64,204,95,235,126,17,157,48,188,79,219,110,250]
                                                        45

一个或两个奇数长度且输出大于0的测试用例会很好。在这种情况下,如果您必须自己编写浅滩代码而不是依靠内置函数,则很容易弄乱浅滩。
OlivierGrégoire

@OlivierGrégoire的[1,3,5,7,9,2,4,6,8]长度为9,但是我可能会为长度7和11添加更多一些。编辑:添加了测试用例[1,3,5,7,2,4,6] = 2(长度7)和[1,6,11,5,10,4,9,3,8,2,7] = 6(长度11)。希望能有所帮助。
凯文·克鲁伊森

我的坏处:我确定您提到的测试用例的大小为8。但是,感谢您提供的额外测试用例。
OlivierGrégoire

1
当前提出的问题似乎是“错误的” ...单步浅滩混洗应该导致第一张和最后一张纸牌发生变化,除非您采取某种欺骗手段!即在一次洗牌10张牌后的[6,1,7,2,8,3,9,4,10,5]。
史蒂夫

2
@史蒂夫,我想你还不错。通常,Riffle混洗仅将两个半部分交织在一起,因此两者[1,6,2,7,3,8,4,9,5,10][6,1,7,2,8,3,9,4,10,5]都是可能的。在我的挑战的确意味着顶部卡将永远留在顶级显卡,所以它确实有点CON-招的。我从来没有见过有人IRL使用洗牌,洗牌但是洗牌的扑克牌。通常,它们之间也使用其他类型的洗牌。无论如何,现在改变挑战已经为时已晚,因此,为了应对这一挑战,在进行了浅滩混洗之后,顶级牌将始终保持顶级牌。
凯文·克鲁伊森

Answers:


6

果冻,8 字节

ŒœẎ$ƬiṢ’

在线尝试!

怎么样?

ŒœẎ$ƬiṢ’ - Link: list of integers A
    Ƭ    - collect up until results are no longer unique...
   $     -   last two links as a monad:
Œœ       -     odds & evens i.e. [a,b,c,d,...] -> [[a,c,...],[b,d,...]]
  Ẏ      -     tighten                         -> [a,c,...,b,d,...]
     Ṣ   - sort A
    i    - first (1-indexed) index of sorted A in collected shuffles
      ’  - decrement

25

JavaScript(ES6),44个字节

@nwellnhof建议的较短版本

期望一个带有1索引卡的卡座作为输入。

f=(a,x=1)=>a[x]-2&&1+f(a,x*2%(a.length-1|1))

在线尝试!

给定长度为的牌组,我们定义:[c0,,cL1]L

xn={2nmodLif L is odd2nmod(L1)if L is even

我们寻找使得。ncxn=2


JavaScript(ES6), 57 52  50字节

期望一个带有0索引卡的卡座作为输入。

f=(a,x=1,k=a.length-1|1)=>a[1]-x%k&&1+f(a,x*-~k/2)

在线尝试!

怎么样?

由于JS缺乏通过自定义步进提取数组切片的本机支持,因此模拟整个浅滩混洗可能会非常昂贵(但老实说,我什至没有尝试过)。但是,也可以通过仅查看第二张牌和卡组中的牌总数来找到解决方案。

给定长度为的牌组,此代码将查找,使得:Ln

c2(k+12)n(modk)

其中是第二张牌,定义为:c2k

k={Lif L is oddL1if L is even



5

R58 55 45字节

a=scan();while(a[2]>2)a=matrix(a,,2,F<-F+1);F

在线尝试!

模拟排序过程。输入为1索引,返回FALSE0。


非常好!我正在尝试类似的方法,但是使用的是递归函数,但效果不佳。
user2390246


5

APL(Dyalog Unicode)35 26 23 22 字节SBCS

{⍵≡⍳≢⍵:01+∇⍵[⍒2|⍳⍴⍵]}

在线尝试!

感谢Adám的帮助,Outgolfer的Erik给予了-3的帮助,而ngn给予了-1的帮助。

TIO链接包含两个测试用例。

说明:

{⍵≡⍳≢⍵:01+∇⍵[⍒2|⍳⍴⍵]}
{⍵≡⍳≢⍵:01+∇⍵[⍒2|⍳⍴⍵]}  function takes one argument: ⍵, the array
 ⍵≡⍳≢⍵                  if the array is sorted:
 ⍵≡⍳≢⍵                  array = 1..length(array)
      :0                then return 0
                       otherwise
         1+             increment
                       the value of the recursive call with this argument:
            ⍵[      ]   index into the argument with these indexes:
                 ⍳⍴⍵    - generate a range from 1 up to the size of 
               2|       - %2: generate a binary mask like [1 0 1 0 1 0]
                       - grade (sorts but returns indexes instead of values), so we have the indexes of all the 1s first, then the 0s.

¹



@EriktheOutgolfer更好,谢谢!
Ven

1
∧/2≤/⍵->⍵≡⍳≢⍵
ngn

@ngn没有意识到该阵列没有孔。谢谢!
Ven

4

Perl 6的36个34 32字节

-2字节归功于nwellnhof

$!={.[1]-2&&$!(.sort:{$++%2})+1}

在线尝试!

通过按索引模2进行排序直到列表被排序为止,逆向浅滩随机播放,然后返回序列的长度。

很好笑,我通常不尝试Perl 6的递归方法,但是这次它比原始方法要短。

说明:

$!={.[1]-2&&$!(.sort:{$++%2})+1}
$!={                           }   # Assign the anonymous code block to $!
    .[1]-2&&                       # While the list is not sorted
            $!(             )      # Recursively call the function on
               .sort:{$++%2}       # It sorted by the parity of each index
                             +1    # And return the number of shuffles

3

05AB1E(旧版),9个字节

[DāQ#ι˜]N

在线尝试!

说明

[   #  ]     # loop until
  ā          # the 1-indexed enumeration of the current list
 D Q         # equals a copy of the current list
     ι˜      # while false, uninterleave the current list and flatten
        N    # push the iteration index N as output

我什至不知道有可能在旧版循环外输出索引。我认为那时将再次为0,就像新的05AB1E版本一样。好答案!比使用启发性挑战的内置unshuffle10倍Å≠。:)
凯文·克鲁伊森

@KevinCruijssen:有趣。我不知道有什么改组。在这种情况下,它与我的版本相同,但是取消混洗可维护2D数组的尺寸。
Emigna

3

Java(JDK),59个字节

a->{int c=0;for(;a[(1<<c)%(a.length-1|1)]>2;)c++;return c;}

在线尝试!

仅对大小小于31的数组或迭代小于31的解决方案可靠地工作。有关更一般的解决方案,请参见以下63个字节的解决方案:

a->{int i=1,c=0;for(;a[i]>2;c++)i=i*2%(a.length-1|1);return c;}

在线尝试!

说明

在一个浅滩上,下一个位置是前一个乘以两倍(如果它是奇数)或以长度为模(如果是偶数),则取两个模。

因此,我使用此公式遍历所有索引,直到在数组中找到值2。

学分


两次使用163字节x.clone()代替A.copyOf(x,l)
凯文·克鲁伊森


@Arnauld谢谢!我很难弄清楚如何简化“长度,否则长度-1”
OlivierGrégoire

@Arnauld哦!我的新算法实际上与您的算法相同...我花了半个小时自己弄清楚了它
OlivierGrégoire

更准确地说,这相当于对@nwellnhof发现的原始算法进行了改进。
Arnauld

3

J28 26字节

-2字节感谢乔纳!

 1#@}.(\:2|#\)^:(2<1{])^:a:

在线尝试!

受Ven的APL解决方案启发。

说明:

               ^:       ^:a:   while 
                 (2<1{])       the 1-st (zero-indexed) element is greater than 2   
     (        )                do the following and keep the intermediate results
          i.@#                 make a list form 0 to len-1
        2|                     find modulo 2 of each element
      /:                       sort the argument according the list of 0's and 1's
1  }.                          drop the first row of the result
 #@                            and take the length (how many rows -> steps)     

K(ngn / k),25个字节

感谢ngn的建议和他的K解释器!

{#1_{~2=x@1}{x@<2!!#x}\x}

在线尝试!


收敛-迭代,然后减一,然后计数-这导致代码更短
ngn

@ngn。因此,类似于我的J解决方案-稍后再试,谢谢!
Galen Ivanov

1
1#@}.(\:2|#\)^:(2<1{])^:a:26字节
约拿书

@Jonah谢谢!
Galen Ivanov

2

APL(NARS),字符49,字节98

{0{∧/¯1↓⍵≤1⌽⍵:⍺⋄(⍺+1)∇⍵[d],⍵[i∼d←↑¨i⊂⍨2∣i←⍳≢⍵]}⍵}

当可以使用一个线性n时,为什么要在最深循环中使用一种算法应该为nlog(n)?只是几个字节?使用∧/¯1↓⍵≤1⌽⍵O(n)]测试,[⍵≡⍵[⍋⍵] O(nlog n)和面对的每个元素按顺序排列:

  f←{0{∧/¯1↓⍵≤1⌽⍵:⍺⋄(⍺+1)∇⍵[d],⍵[i∼d←↑¨i⊂⍨2∣i←⍳≢⍵]}⍵}
  f ,1
0
  f 1 2 3
0
  f 1,9,8,7,6,5,4,3,2,10
3
  f 1,3,5,7,9,11,13,15,17,19,2,4,6,8,10,12,14,16,18,20
17

这是我第一次看到有人区分字符和字节differentiate。当我看到Unicode字符时,它总是使我烦恼,他们声称每个字符一个字节。这个😠不是一个字节!
Kerndog73

@ Kerndog73所有的数字,但在APL认为字符不是数字......(他们似乎AV数组元素)
RosLuP

2

Ruby,42个字节

f=->d,r=1{d[r]<3?0:1+f[d,r*2%(1|~-d.max)]}

在线尝试!

怎么样:

在数组内搜索数字2:如果它位于第二位置,则说明尚未对牌组进行洗牌,否则请检查连续进行洗牌的位置。



2

C(GCC)64 63字节

来自nwellnhof的-1个字节

i,r;f(c,v)int*v;{for(i=r=1;v[i]>2;++r)i=i*2%(c-1|1);return~-r;}

根据Arnauld和OlivierGrégoire的答案,这是一个大大缩短的答案。我将旧解决方案留在下面,因为它可以解决带有不连续卡片的卡片组的一般性问题。

在线尝试


C(GCC)162字节

a[999],b[999],i,r,o;f(c,v)int*v;{for(r=0;o=1;++r){for(i=c;i--;(i&1?b:a)[i/2]=v[i])o=(v[i]>v[i-1]|!i)&o;if(o)return r;for(i+=o=c+1;i--;)v[i]=i<o/2?a[i]:b[i-o/2];}}

在线尝试

a[999],b[999],i,r,o; //pre-declare variables
f(c,v)int*v;{ //argument list
    for(r=0;o=1;++r){ //major loop, reset o (ordered) to true at beginning, increment number of shuffles at end
        for(i=c;i--;(i&1?b:a)[i/2]=v[i]) //loop through v, split into halves a/b as we go
            o=(v[i]>v[i-1]|!i)&o; //if out of order set o (ordered) to false
        if(o) //if ordered
            return r; //return number of shuffles
        //note that i==-1 at this point
        for(i+=o=c+1;i--;)//set i=c and o=c+1, loop through v
            v[i]=i<o/2?a[i]:b[i-o/2];//set first half of v to a, second half to b
    }
}

2

R,85个字节

s=scan();u=sort(s);k=0;while(any(u[seq(s)]!=s)){k=k+1;u=as.vector(t(matrix(u,,2)))};k

在线尝试。

说明

愚蠢(强力)方法,远不及遵循#2卡。

与其重新组合输入,不如s从一个有序的向量开始u,我们逐步对其进行重新排列,直到与相同s。由于将奇数长度的向量折叠到2列矩阵中,这会为奇数长度的输入给出警告(但混洗计数仍然正确)。在这种情况下,在R中,丢失的数据点通过循环输入的第一个元素来填充。

如果我们提供了不能被改组的向量,循环将永远不会终止。

附录:如果改组,则节省一个字节。与上面的答案不同,不需要与进行转置t(),但是,byrow=TRUE因此才T出现在中matrix()

R,84字节

s=scan();u=sort(s);k=0;while(any(s[seq(u)]!=u)){k=k+1;s=as.vector(matrix(s,,2,T))};k

在线尝试!


我自由决定了标题,并为测试用例添加了一个TIO链接(基于另一个R答案),还验证了您的答案符合预期,因此,我+1,欢迎使用PPCG!:)
凯文·克鲁伊森





1

Pyth,18个字节

L?SIb0hys%L2>Bb1
y

在线尝试!

-2感谢Outgolfer的@Erik。

该脚本有两行:第一行定义一个函数y,第二行y使用隐式Q(求值的stdin)参数调用。

L?SIb0hys%L2>Bb1
L                function y(b)
 ?               if...
  SIb            the Invariant b == sort(b) holds
     0           return 0
      h          otherwise increment...
       y         ...the return of a recursive call with:
             B   the current argument "bifurcated", an array of:
              b   - the original argument
            >  1  - same with the head popped off
          L      map...
         % 2     ...take only every 2nd value in each array
        s         and concat them back together

¹


1

PowerShell62 71 70 66字节

如果添加了偶数个元素的测试用例,则+9字节。

-1字节,带有splatting。

-4个字节:将表达式包装到$i,并$j扩展到新的作用域。

for($a=$args;$a[1]-2;$a=&{($a|?{++$j%2})+($a|?{$i++%2})}){$n++}+$n

在线尝试!


1

Japt13 11 10字节

以我的光泽,新 -工作进展中解释试驾。

ÅÎÍ©ÒßUñÏu

尝试运行所有测试用例

ÅÎÍ©ÒßUñÏu     :Implicit input of integer array U
Å              :Slice the first element off U
 Î             :Get the first element
  Í            :Subtract from 2
   ©           :Logical AND with
    Ò          :  Negation of bitwise NOT of
     ß         :  A recursive call to the programme with input
      Uñ       :    U sorted
        Ï      :    By 0-based indices
         u     :    Modulo 2

1
这个口译员看起来很酷。
递归

0

Python 3,40个字节

f=lambda x:x[1]-2and 1+f(x[::2]+x[1::2])  # 1-based
f=lambda x:x[1]-1and 1+f(x[::2]+x[1::2])  # 0-based

在线尝试!

我需要更频繁地刷新页面:错过了Outgolfer的编辑Erik做的类似技巧=)

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.