找到并旋转


30

任务

这是一个简单的挑战。您的输入是一个非空字符串,仅包含数字0123456789和哈希值#。它将仅包含一串数字,该数字编码一个非负整数,并且可以环绕在字符串的末尾,并且至少包含一个#。该整数可能具有前导零。例如##44##013####并且23###1是有效的投入,同时###0099#4#4没有。

您的任务是n从字符串中提取整数,并n向右输出字符串旋转步骤。

例子

  • 输入#1##应向右旋转1步,因此正确的输出为##1#
  • 输入#026###应向右旋转26步,因为前导0被忽略。正确的输出是26####0
  • 输入1####2的末尾包含整数21,因此应将其向右旋转21步。正确的输出是##21##

规则和计分

您可以编写完整的程序或函数。最低字节数获胜,并且不允许出现标准漏洞。

您可以假定数字n适合int您的语言的标准类型。相反,如果该标准int类型实现了任意精度的整数,则(理论上)您必须支持任意大的n

测试用例

#1## -> ##1#
##4## -> #4###
1####1 -> ####11
1####2 -> ##21##
#026### -> 26####0
#000### -> #000###
###82399 -> ##82399#
51379#97 -> #9751379
#98##### -> ###98###
#######4## -> #4########
60752#1183 -> 8360752#11
####99366800## -> 366800######99
########9##### -> ###9##########
91#####515694837 -> 1#####5156948379
###6114558###### -> #6114558########
######219088736090042#### -> 9088736090042##########21
#46055080150577874656291186550000138168########### -> 0138168############4605508015057787465629118655000
568375993099127531613012513406622393034741346840434468680494753262730615610086255892915828812820699971764142551702608639695081452206500085233149468399533981039485419872101852######################3680 -> 99533981039485419872101852######################36805683759930991275316130125134066223930347413468404344686804947532627306156100862558929158288128206999717641425517026086396950814522065000852331494683

7
我们必须支持所有测试用例吗?这些数字中的一些数字相当大……使用8位整数的语言是否可以接受?
丹尼斯

@Dennis可以在不将整数实际加载到内存的情况下使用模块化算术解决挑战,但是您是对的,这在许多语言中都是一个麻烦。假设您只需要处理n适合int您的语言本机类型(可能是任意精度)的那些测试用例。稍后我将更新挑战文本。
Zgarb

如果input =,我们该怎么办1234
CalculatorFeline

2
@CatsAreFluffy “和至少一个#”
FryAmTheEggman '16

Answers:


10

CJam,11个字节

q_'#%W%sim>

在线尝试!验证所有测试用例

请注意,这不适用于最后两个测试用例,因为所涉及的数字不适合64位。

怎么运行的

q_          e# Read all input and push it twice.
  '#%       e# Split at runs of '#'.
     W%     e# Reverse the resulting array.
       si   e# Cast to string, then to int.
         m> e# Rotate the original input that many places to the right.

哦,太简单了!
Luis Mendo

7

朱莉娅71 65字节

s->join(circshift([s...],maximum(parse,split(s*s,"#",keep=1<0))))

这是一个匿名函数,它接受一个字符串并返回一个字符串。要调用它,请将其分配给变量。

我们将输入附加到自身,将其分割为一个数组#作为分隔符,解析每个整数,然后取最大值。这定义了我们将字符串向右移动的次数。我们将字符串喷射到一个Char数组中,进行移位,然后将join其重新组合在一起。


7

Python,66个字节

lambda l:(2*l)[-int(''.join(l.split('#')[::-1]))%len(l):][:len(l)]

5

视网膜 65岁 57 49

(\ d *)#*(\ d +)
$ 2 $ 1 $ 0
^ \ d +
$ *
+`1(。*)(。)
 $ 2 $ 1
<空格>

感谢Martin,节省了8个字节!

在线尝试!

注意,对于在线的非常大的测试用例,对于大多数大型机器而言,这将超时/用尽内存。

这将获取字符串中的最后一个数字,并获取字符串中的第一个或没有数字,并将其放在字符串前面。然后,它将该组合数转换为一进制,并在删除一进制数字的同时重复旋转。


3

果冻12 10字节

ẋ2~ṣ0‘ḌṂṙ@

在线尝试!验证所有测试用例

背景

假设输入为51379#97

通过将字符串重复两次(51379#9751379#97),我们可以确保它包含数字的连续表示形式。

接下来,我们将按位非应用于所有字符。这会尝试转换为int,因此'1'会被赋值为1,然后映射为〜1 = -2。如果失败(#),则返回0

对于我们的示例,这给出了

[-6, -2, -4, -8, -10, 0, -10, -8, -6, -2, -4, -8, -10, 0, -10, -8]

接下来,我们将零分开以将编码数字的部分与其余部分分开。

[[-6, -2, -4, -8, -10], [-10, -8, -6, -2, -4, -8, -10], [-10, -8]]

按位NOT将n映射到-n-1,因此我们将每个值递增以获得-n

[[-5, -1, -3, -7, -9], [-9, -7, -5, -1, -3, -7, -9], [-9, -7]]

接下来,我们将每个列表从基数10转换为整数。

[-51379, -9751379, -97]

最低的数字是我们要搜索的数字的负数。由于果冻列表旋转原子旋转到左边,这避免乘以-1,以向右旋转。

怎么运行的

ẋ2~ṣ0‘ḌṂṙ@  Main link. Input: S (string)

ẋ2          Repeat the string twice.
  ~         Apply bitwise NOT to all characters.
            This maps 'n' to ~n = -(n+1) and '# to 0.
   ṣ0       Split at occurrences of zeroes.
     ‘      Increment all single-digit numbers.
      Ḍ     Convert each list from base 10 to integer.
       Ṃ    Take the minimum.
        ṙ@  Rotate S that many places to the left.

3

MATL28 25 17 16字节

!G1Y4XXPZcXvUYS!

借用Dennis拆分数组并逆转片段顺序的思想,减少了8个字节

最后两个测试用例不起作用,因为数量太大。

编辑(2016年5月20日)由于语言的最新更改,链接中的代码使用Xz代替Xv

在线尝试!

!         % take implicit input: string. Transpose into column char array
G         % push input string again
1Y4       % predefined literal '\d' (for regexp)
XX        % match regexp. Gives cell array with 1 or 2 strings
P         % flip that array
ZcXv      % join the strings in that array, without spaces
U         % convert to number
YS        % rotate the transposed input that many times
!         % put back into row form (string). Implicitly display

2

PowerShell,153个字节

(但请参见下面的“额外信用”部分)

param($a)$d=[System.collections.arraylist][char[]]$a;for($b=+("$a$a"-split"#"-ne'')[1];$b;$b--){$r=$d[-1];$d.removeAt($d.Count-1);$d.insert(0,$r)}-join$d

PowerShell没有“移动”数组的概念,因此我不得不推出自己的解决方案。较大的数字将花费很长时间,但最终应完成适合32位int的所有操作。

接受input $a,并将一个新变量设置$d[System.Collections.ArrayList]对象。这样做是因为,从技术上讲,PowerShell中的数组是不可变的(下面在Extra Credit中进一步说明),因此不支持移位所需的任意插入或删除。然后,我们进入一个for循环。

最初的条件是我发现的一个窍门-如果我们将输入连接在一起,分割#并忽略空,则结果数组的第二个元素将等于我们的数字,而不考虑换行。我们将其设置为$b,并$b每次减小直到为零。

每次迭代时,我们都将helper设置$r为arraylist中的最后一个元素,删除最后一个元素,然后将其插入到前面...有效地将数组向右“移动”一个元素。

最后,我们简单地输出with,-join$d以便将其串联为一个字符串。


额外信用

如果问题是向左而不是向右移动数组,我们可以使用多重赋值来大大缩短它。基本上,“如果赋值包含的元素多于变量,则所有剩余的值将分配给最后一个变量。”

从本质上说,这意味着像$c=@(1,2,3)$a,$b=$c
将有$a=1一个int和$b=@(2,3)数组。

PowerShell(90字节)执行左移而不是右移

param($a)$b=+("$a$a"-split"#"-ne'')[1];$a=[char[]]$a;for(;$b;$b--){$r,$a=$a;$a+=$r}-join$a

在这里,我们再次接受输入,并按$b上述进行设置。我们将其重新转换$a为字符数组,然后输入与for上述相同的循环。但是,这一次,我们不需要支持任意的删除/插入,因此我们不需要使用昂贵的[System.Collections.ArrayList]对象,也不需要使用昂贵的方法调用。取而代之的是,我们只是将其设置$r为的第一个元素$a,其余元素则重新保存到中$a。然后,我们+=将其坚持到底。

(正如我说的那样,PowerShell数组在技术上是不可变的,但是+=这里的运算符是重载的-它需要一个数组和另一个对象,将它们混合在一起(技术术语)到一个新的数组中,将其返回并保存为变量名,然后销毁从功能上讲,我们只是在数组的末尾添加了一个元素,但是从技术上(从内存/垃圾清理的角度等等)来说,它是一个全新的数组,显然这可能会成为昂贵的操作如果数组很大或很复杂,则不利的一面是,由于数组是不可变的,因此对其进行索引或对其进行迭代非常便宜。)

输出保持相同的动作,并带有-join将其转换为单个字符串的语句。


1

严重的是21个字节

,;;+'#@s`≈`MM@#@`/`nΣ

在线尝试!

警告:此解决方案效率很低,因此较大的测试用例将在TIO上超时。使用本地解释器。

说明:

,;;+'#@s`≈`MM@#@`/`nΣ
,;;+                   make 3 copies of input, and concatenate two of them
    '#@s               split on #s
        `≈`MM          convert strings to ints, take maximum
             @#@       explode final copy of input
                `/`n   rotate to the right n times
                    Σ  join

Concat并发挥最大作用:好主意!
路易斯·门多

@LuisMendo当我在这里撰写说明时,我很高兴看到Alex的答案以相同的策略弹出。
Mego

似乎唯一一个最初使用朴素方法的人是我:-)(旋转初始字符串,直到所有数字都连续)
Luis Mendo

1

Mathematica,69字节

#~StringRotateRight~ToExpression[""<>Reverse@TextCases[#,"Number"]]&

在中找到数字序列,如果有2,则需要颠倒顺序。连接字符串(如果只有一个,则仅返回数字字符串)。将字符串转换为数字,然后将字符串旋转该次数。


FromDigits代替ToExpression
CalculatorFeline

1

Pyth,22个 14字节

.>zs-.<zxz\#\#

在这里尝试!

说明

。> zs-。<zxz \#\##z = input

     。<z#向左旋转z
        xz \##第一次出现哈希值的索引
                  #这样可以确保整数不绕在末尾
    -\##过滤掉所有哈希
   s#强制转换为整数,还删除前导零
。> z#对输入字符串进行最后的旋转并打印

这适用于所有测试用例,并且对于大量数字几乎可以立即完成。


您可以-...\#代替h:..."\d+"1。同样,无需转换z为字符列表,.>也可以处理字符串。
雅库布,2016年

@Jakube感谢您的提示,当我这样做时非常累。^^
Denker

1

JavaScript(ES6)66

一次,%JavaScript的负数愚蠢的负数很有用

z=>(z+z).substr(-(l=z.length,[a,b]=z.match(/\d+/g),b?b+a:a)%l-l,l)

1
@WashingtonGuedes不,总和b+a是字符串串联。a='32',b='1', (b?b+a:a)=='132', (b|0+a)==33
edc65 '16


1

JavaScript(ES6),67 64字节

s=>(l=s.length,s+s).substr(l-s.split(/#+/).reverse().join``%l,l)

丹尼斯的CJam答案的另一个体现。

编辑:通过分配edc65的答案中他没有引起注意的部分,节省了3个字节。


使用三进制和总和而不是rev​​erse()。join(),您应该击败我的得分
edc65 '16

@Downgoat对不起,我最近对它们的了解大多不错,但是我在深夜才这样做,所以我并没有想清楚。
尼尔

@ edc65不,这使我的得分更高。因此,我s+s改为复制技巧。(我实际上是昨晚想到的,但是当时我太累了,无法尝试。)
Neil

1

Perl 5,41个字节

39个字节加两个-lF标志(-M5.01免费):perl -lF -M5.01 script.pl

/#+/;map{unshift@F,pop@F}1..$'.$`;say@F

说明:

  • -lF读取输入,删除尾随的换行符,将其余部分放入字符串$_,将其拆分为字符,然后将其拆分为array @F
  • /#+/在中找到#s 的第一个字符串,$_并将其设置为$`等于它前面的东西和$'等于它后面的东西。如果$`为空,则$'可能包含更多#s。然而,$'.$`是一个字符串,其初始子字符串是旋转数组的次数。
  • 现在我们建立一个list 1..$'.$`,将其$'.$`视为一个整数,然后将其数字化,从而去除所有final #,因此list是从1到旋转数组的次数。
  • 对于该列表中的每个元素,我们旋转数组(pop最后一个元素和unshift其移到开头)。
  • 然后say是旋转数组的所有元素。

1

Ruby- 68 72 70字节

s=ARGV[0]
p s.split(//).rotate(-(s+s).scan(/\d+/).map(&:to_i).max)*""
  • split 将字符串转换为数组
  • (s+s).scan(/\d+/) 将字符串连接到自身并获得数字数组(作为字符串)
  • map(&:to_i) 将字符串转换为整数
  • max 选择最大的整数
  • rotate max
  • *""将数组转换回字符串(的简写形式join

用法: ruby scriptname.rb "[string]"


我是新来的。用不同语言发布多个答案的礼节如何?我添加了一个单独的答案,以防万一错误。如果不能添加多个答案,请告诉我,我将其
删除

1
用不同语言的多个答案都可以,甚至可以鼓励(前提是它们都是正确的)。
Zgarb '16

0

05AB1E14 13字节

嗯,代码不太可能因大于100000的数字而终止,但是如果您足够耐心,将有一个输出:)。码:

'#¡rJ¹sF¤rS\J

说明:

'#¡             # Split the input on '#'
   r            # Reverse the stack
    J           # Join the stack
     ¹          # Take the first input
      s         # Swap with the number
       F        # For N in range(0, number), do...
        ¤       #   Obtain the last character
         r      #   Reverse the stack
          S     #   Split everything to individual characters
           \    #   Delete the last character
            J   #   Join the stack

在线尝试!

使用CP-1252编码


0

VBSCRIPT, 82 99个字节

之前的代码无法处理数字结尾的情况

b=len(a):f=replace(a,"#","/",1,1):c=replace(split(f&f,"/")(1),"#",d) mod b:d=right(a,c)&left(a,b-c)

放开

b=len(a)                                 -a->implicit input, get its length 
f=replace(a,"#","/",1,1)  -replace first instance of # so we can split later
c=replace(split(f&f,"/")(1),"#",d) mod b    -get the number and calc the mod
d=right(a,c)&left(a,b-c)                    -d->implicit output

有点烂...即使在VBscript中,也可能有更好的方法


欢迎使用编程难题和Code Golf Stack Exchange。可以通过在您的高尔夫代码下面添加代码细目和解释来改善此答案。另外,是否可以通过创建函数而不是程序来保存字节,a函数输入在哪里,它返回输出?这样,您将不需要inputboxand msgbox调用。
wizzwizz4 '16

为什么需要b
CalculatorFeline

0

Mathematica,73 58字节

#~StringRotateRight~Max[FromDigits/@StringSplit[#<>#,"#"]]&

很多字节。 15 个字节 保存 感谢 IPoiler


StringRotateRight在这里保存一些字节。
IPoiler '16

0

Matlab的(73)

  @(a)regexprep(a,'(\d*)#*(\d*)#*','${circshift($0,[0 str2num([$2 $1])])}')
  • 这正在使用另一种方法,我想知道@luis是否使用了它,因为在提及他的描述时(un)有一些共同点?不幸的是,我不了解裁剪的Matl语言。

0

matlab (86) 72

 @(n)circshift(n,[0 str2num(circshift(n(n~='#'),[0,-find(n=='#',1)+1]))])
  • 该函数对字符串进行两次遍历,一次用于整数提取,第二次用于所需的任务,它不需要花费太多时间,因为matlab继续旋转(Dim)modulus(Length)直到出现较大范围的分段失败。

  • 会更加努力地打高尔夫球....


(86)

  @(n)circshift(n,[0 str2num([strtok(n(find(n=='#',1,'last'):end),'#') strtok(n,'#')])])
  • 此函数与前一个函数的区别是,它确实将两个遥远的整数出现向后连接,而第一个只是旋转它。
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.